Is kuns9/trading-upbit-skill safe?
https://github.com/openclaw/skills/tree/main/skills/kuns9/trading-upbit-skill
trading-upbit-skill is a legitimate automated cryptocurrency trading bot for the Upbit exchange with no detected prompt injection, obfuscated code, malicious install-time execution, or confirmed data exfiltration. The primary concerns are the inherent financial risk of an autonomous trading system that places real orders without per-trade confirmation, automatic management of all account holdings including externally-acquired positions, and a gap in audit coverage for the critical config/index.js credential handler. Honeypot files were accessed read-only during monitoring, but canary integrity passes and skill code is never executed during the install phase, making malicious exfiltration via the skill itself unlikely though not provably excluded.
Category Scores
Findings (12)
HIGH Honeypot credential files accessed (read) during monitoring window -22 ▶
All six honeypot/canary files — .env, .ssh/id_rsa, .aws/credentials, .npmrc, .docker/config.json, and .config/gcloud/application_default_credentials.json — were opened and read twice during the monitoring period. The first access (audit sequence 256-261, timestamp 1771932912) occurred before the git clone started and is likely the audit framework seeding canary files. The second access (audit sequence 1694-1699, timestamp 1771932930) occurred after the skill files were installed and lacks EXECVE context in the captured log, making it impossible to definitively attribute to the audit framework vs. another process. The skill's JavaScript is never executed during install, so the skill code itself cannot be responsible. No write events were recorded and canary integrity check passes. The unexplained post-install read pattern is a notable gap.
HIGH Sensitive system credential files read during monitoring — attribution gap -15 ▶
The same six sensitive credential paths accessed in the canary integrity finding were read-accessed during the post-install monitoring window. While no modification occurred, read access to .ssh/id_rsa and .aws/credentials is a data exfiltration precondition if any process were to transmit the content. No outbound network connection carrying this data was observed in the network diff or tcpdump. The canary integrity verdict is clean, but the read access pattern without clear EXECVE attribution warrants flagging as a data exfiltration concern independent of the canary category.
HIGH scripts/config/index.js not available for audit review -8 ▶
The config loader is the sole module responsible for reading Upbit API keys from environment variables or config.json and constructing the authenticated client. Both SKILL.md and README explicitly call it out as a critical file requiring pre-deployment inspection. It was listed in the skill file inventory and catalogued in auditd records but its source content was not captured in the evidence. Without reviewing this file, it is impossible to confirm: (a) whether it logs secrets, (b) whether it reads from unintended file paths such as .env, (c) whether it makes any network calls to exfiltrate credentials, or (d) whether it correctly validates secret scope. This is the highest-value unaudited surface.
HIGH Skill places real financial orders without per-trade user confirmation -15 ▶
When execution.dryRun is set to false, the worker processes BUY_SIGNAL, STOPLOSS_HIT, TRAILING_STOP_HIT, TAKEPROFIT_HARD, and SELL_PRESSURE_HIT events by calling TradeExecutor.execute() which submits live orders to the Upbit REST API. There is no mechanism for the agent or user to approve individual trades. The budget policy allocates up to 30% of available KRW balance per run by default. The worker runs on a 1-minute cron cycle with up to maxPositions=5 concurrent positions, meaning rapid consecutive cycles can accumulate significant exposure. An event file tampered with by any other skill or process would trigger unintended live orders.
MEDIUM Aggressive algorithm can rapidly deplete account funds -20 ▶
The aggressive breakout strategy fires BUY_SIGNAL on near-breakout conditions as well as confirmed breakouts, using up to 30% of available KRW per cycle split across N simultaneous signals. Combined with a 2% stop-loss, 3% hard take-profit, and 1-minute worker cadence, a drawdown scenario could repeatedly trigger stop-losses, consuming available balance through multiple round trips within an hour. There is no circuit breaker, maximum-daily-loss limit, or mandatory cooldown between loss events beyond the optional reentryCooldownMinutes setting.
MEDIUM monitorHoldings:true auto-imports and exits all account positions -10 ▶
Every monitor cycle calls syncPositionsFromAccounts(), which fetches the user's full Upbit account holdings and imports any untracked asset as an OPEN position via importOpenFromAccounts(). Once imported, the bot applies its full exit logic (stop-loss, take-profit, trailing stop) to these externally-acquired positions. A user who holds assets purchased manually or by a different strategy will find those positions subject to automated selling by this bot without their explicit enrollment.
MEDIUM Test event injection scripts bypass risk and strategy layers -9 ▶
scripts/tests/inject_buy_signal.js and inject_sell_signal.js write directly to resources/events.json with arbitrary market symbols, budget amounts, prices, and flags. The eventWorker processes all pending events from this file without verifying their provenance, signature, or consistency with the current market state. If an attacker or a compromised agent session can invoke these test scripts (they are standard Node.js files accessible to any process with filesystem access), they can inject orders into the worker queue that bypass all volatility breakout, momentum, and risk management checks.
MEDIUM Skill requires live Upbit trading API keys with financial scope -5 ▶
Functional use of this skill requires providing UPBIT_ACCESS_KEY and UPBIT_SECRET_KEY (or UPBIT_OPEN_API_ACCESS_KEY / UPBIT_OPEN_API_SECRET_KEY — there is a naming inconsistency between the SKILL.md frontmatter and the README body). These credentials must carry trading permissions on Upbit. The unreviewed config/index.js module is responsible for ingesting and using these keys. If any component of the agent runtime logs, transmits, or mishandles these keys, complete financial control of the connected Upbit account is compromised.
LOW Post-install canary file read events lack EXECVE attribution -18 ▶
The second set of canary file accesses at audit timestamp 1771932930 falls after the skill installation completed but the EXECVE audit log does not capture the triggering process for these accesses (log coverage ends at sequence :1421). Because the skill code is never executed during the clone/install audit phase, the skill's JavaScript cannot be the source. The most probable explanation is the oathe audit framework performing its final integrity sweep, but this cannot be confirmed from the available evidence. The gap in EXECVE coverage is a monitoring fidelity issue rather than confirmed malicious behavior.
LOW SKILL.md declares broad financial permissions via required env vars -12 ▶
The skill's frontmatter metadata declares UPBIT_ACCESS_KEY and UPBIT_SECRET_KEY as required environment variables, signaling to the OpenClaw runtime that the agent should be provisioned with live trading credentials. While this is disclosed transparently and is functionally necessary for a trading bot, it represents a broad permission request that elevates the skill's trust requirements. An agent with this skill active in its system prompt will be expected to operate with live financial API credentials in its environment.
INFO No malicious install-time code execution vectors found 0 ▶
package.json contains no preinstall, postinstall, prepare, or other npm lifecycle scripts that would execute code on npm install. No .gitattributes clean/smudge filter drivers were found. No .gitmodules pointing to external repositories. No .githooks. No symlinks in the skill directory. The installation process consists entirely of git sparse-checkout and file copy, with zero code execution by the skill itself.
INFO Network connections during and after install are legitimate and bounded 0 ▶
The only external network connection established during the install phase was to 140.82.121.4:443 (GitHub) for the git sparse-checkout clone. Pre-existing connections to Ubuntu/Canonical update servers (91.189.91.49, 185.125.188.57, 185.125.188.58) were present before install and absent after — these were pre-existing system connections that terminated naturally. The connection diff confirms no new outbound connections remain after install. No connections to api.upbit.com or any other trading endpoint were made during install.