T09 · Insecure Skill Coding Practices
- Location
src/providers/swapExecutor.ts:38- Finding
Remote Swap Transactions Are Signed Without Instruction Validation
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill matches its trading purpose, but live mode can automatically sign real Solana trades with weak controls and has bugs that can misreport exits.
Review carefully before installing for live use. Keep it in paper mode unless you have audited the code, use only a dedicated low-balance trading wallet, protect private keys and API tokens, avoid custom API base URLs unless you fully trust them, and fix the live exit-state bugs and transaction-validation gaps before allowing autonomous trades with real funds.
src/providers/swapExecutor.ts:38Remote Swap Transactions Are Signed Without Instruction Validation
src/monitor.ts:104Live Take-Profit and Trailing-Stop Branches Delete Positions Without Selling Tokens
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
npm install
cp .env.example .env
npm run dev -- --mode paper --minutes 10
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
npm install
cp .env.example .env
npm run dev -- --mode paper --minutes 10
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
npm install
cp .env.example .env
# edit .env
npm run dev -- --mode live --minutes 30
The trailing-stop branch deletes the position in both modes, but only performs a sell in paper mode. In live mode this creates a dangerous state mismatch: the bot believes the asset was exited and stops monitoring it, while the live wallet may still hold the tokens and remain exposed to further price collapse.
This function signs and broadcasts a live Solana swap using the loaded private key with no in-function authorization gate, interactive confirmation, or policy check. In an agent skill context, that means any upstream caller able to invoke this path can trigger irreversible asset movement, making accidental or unauthorized trades much more dangerous than in a purely local script.
This sell path also signs and submits an irreversible blockchain transaction without an explicit authorization or confirmation control at the point of execution. Because it can liquidate held tokens based on caller-supplied parameters, the agent context amplifies the risk of unintended sales, abuse by a compromised upstream component, or prompt-driven misuse.
The skill explicitly supports live trading mode and automated transaction signing, which implies the ability to move real funds irreversibly. Without a clear warning that live mode can execute real on-chain swaps, incur slippage/fees, and cause unrecoverable losses, users may enable or invoke it without informed consent. In the context of autonomous memecoin trading, this omission is more dangerous because the assets are highly volatile and the strategy is designed to react automatically to noisy market and social signals.
This is a markdown file, so SQP-2 applies to missing warnings about behaviors affecting privacy or system integrity. The instructions explicitly direct the user to store a bearer token, but do not include any caution about protecting secrets, avoiding commits, or limiting exposure of credentials.
This script prints the entire loaded configuration object to stdout, which can expose secrets such as API keys, tokens, passwords, or internal endpoints if they are included in the runtime config. Even if intended for debugging, stdout is often captured by CI logs, terminals, process managers, and support artifacts, turning a local debug action into a broader credential disclosure risk.
This file can automatically execute live sell transactions based on streamed wallet events, with no user-facing confirmation, approval checkpoint, or prominent runtime disclosure in the execution path. In a trading bot context, silent autonomous execution is security-relevant because a bad config, compromised event source, or logic error can immediately trigger real asset loss.
The code logs that live mode is not implemented, but elsewhere in the same file it already performs live buy and live sell execution paths. This mismatch is dangerous because operators may rely on the warning and assume no real trades will occur, when in fact funds can be spent or liquidated automatically under certain branches.
This code performs a live asset sale via sellLiveExactIn, which is a safety-critical and potentially irreversible operation. Although there is internal logging elsewhere, there is no explicit user-facing confirmation, prompt, or explanatory comment/docstring at this execution point disclosing that a real trade will be submitted when monitoring conditions trigger.
When stop-loss conditions are met, the function automatically executes a live sell order. This is a destructive financial action, and the code does not include a visible confirmation prompt or nearby warning/comment informing users that monitoring can trigger real trades automatically.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
};
export async function resolveDexScreener(mint: string): Promise<DexMetrics | null> {
const url = `https://api.dexscreener.com/latest/dex/tokens/${mint}`;
const data = await httpGetJson<DsTokenPairs>(url);
const pair = (data.pairs || []).find(p => (p.chainId || "").toLowerCase() === "solana");
if (!pair) return null;
This code accesses sensitive wallet credentials via WALLET_PRIVATE_KEY_BASE58 and WALLET_PRIVATE_KEY_JSON, which is a safety-relevant operation under the rule. In this file there is no confirmation prompt, user-facing disclosure, or explanatory comment/docstring warning that the skill reads private key material to sign transactions.
The manifest uses a caret range for yaml instead of pinning an exact version, which permits automatic installation of newer releases within the major version. In a security-sensitive Solana-related skill, this weakens supply-chain control and makes builds less reproducible, increasing exposure to vulnerable or malicious package updates.
"lint": "echo \"(optional) add eslint\""
},
"dependencies": {
"yaml": "^2.5.1",
"zod": "^3.24.1",
"node-fetch": "^3.3.2",
"pino": "^9.3.2",
yaml has known advisories and the manifest does not pin an exact version, so it is not possible to verify from this file alone whether deployments resolve to a patched release. If the application parses untrusted YAML, affected versions could be abused for denial of service via crashes or excessive recursion.
The zod dependency is specified with a caret range, so different installs may resolve to different package versions over time. This creates avoidable supply-chain risk and can silently introduce vulnerable releases into a project that may process untrusted input.
},
"dependencies": {
"yaml": "^2.5.1",
"zod": "^3.24.1",
"node-fetch": "^3.3.2",
"pino": "^9.3.2",
"pino-pretty": "^11.2.2",
zod has a known DoS advisory, and the use of a version range prevents confirmation that the installed version is fixed. This is mainly dangerous if complex untrusted input is validated in exposed paths, where crafted payloads could consume excessive resources.
node-fetch is not pinned to an exact version, allowing semver-compatible updates to be pulled in automatically. Because this package handles outbound network requests, supply-chain drift is especially relevant and can introduce security regressions or vulnerable code paths.
"dependencies": {
"yaml": "^2.5.1",
"zod": "^3.24.1",
"node-fetch": "^3.3.2",
"pino": "^9.3.2",
"pino-pretty": "^11.2.2",
"minimist": "^1.2.8",
node-fetch has multiple known advisories, and because the manifest does not pin an exact version, the actual installed package cannot be verified as patched. In a networked agent, this matters because vulnerable fetch behavior can affect header forwarding, redirect handling, or availability under malicious input.
The pino logging dependency is unpinned, which reduces build determinism and increases exposure to unexpected dependency changes. While not directly exploitable on its own, it still represents unnecessary supply-chain risk.
"yaml": "^2.5.1",
"zod": "^3.24.1",
"node-fetch": "^3.3.2",
"pino": "^9.3.2",
"pino-pretty": "^11.2.2",
"minimist": "^1.2.8",
"@solana/web3.js": "^1.98.0",
pino-pretty is declared with a caret range, so developers may get differing versions across environments. Even for a formatting/logging package, unreviewed upstream changes can affect the security posture and reproducibility of the build.
"zod": "^3.24.1",
"node-fetch": "^3.3.2",
"pino": "^9.3.2",
"pino-pretty": "^11.2.2",
"minimist": "^1.2.8",
"@solana/web3.js": "^1.98.0",
"bs58": "^5.0.0",
minimist is unpinned, which is more concerning because this package has a history of prototype-pollution advisories and processes command-line input. In a tool that may parse user-supplied arguments, version drift can increase the chance of resolving to an affected or otherwise unsafe release.
"node-fetch": "^3.3.2",
"pino": "^9.3.2",
"pino-pretty": "^11.2.2",
"minimist": "^1.2.8",
"@solana/web3.js": "^1.98.0",
"bs58": "^5.0.0",
"dotenv": "^16.4.5"
minimist has known prototype-pollution advisories, and the unpinned dependency means the resolved version cannot be validated from the manifest. Since it parses command-line arguments, unsafe versions can be abused to alter object prototypes and destabilize application logic.
Detected: suspicious.env_credential_access