T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/setup_token.js:14
- Finding
- Access Token Exposed Through Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup_token.js:14-26`; invocation documented in `references/token_management.md:22-28` **Vulnerability Type**: Sensitive credential exposure through process arguments **Risk Level**: Medium ### Vulnerable Code ```javascript const TOKEN_FILE = path.join(os.homedir(), ".MIAOWEN_ACCESS_TOKEN"); const token = process.argv[2]; if (!token) { console.error("[ERROR] 请提供 Token 参数"); console.error('用法: node setup_token.js "<YOUR_TOKEN>"'); process.exit(1); } // 将 Token 写入文件(覆盖旧内容,不含换行符) try { fs.writeFileSync(TOKEN_FILE, token.trim(), { encoding: "utf-8", mode: 0o600 }); ``` The corresponding documentation explicitly instructs passing the secret as an argument: ```bash node scripts/setup_token.js "<TOKEN_VALUE>" ``` ### Technical Analysis The setup script obtains the Tencent Miaowen access token from `process.argv[2]`. Secrets supplied through command-line arguments can be exposed through: - Process inspection utilities while the command is running. - Shell history. - Agent tool-call histories and execution telemetry. - Command auditing or process-accounting facilities. - Debug and diagnostic logs that record executed commands. The destination file is appropriately created with mode `0600`, and `chmodSync` is subsequently used to reinforce that permission. However, those controls only protect the stored token and do not protect it during command invocation. The Skill documentation also tells the user to paste the token into the conversation and directs the Agent to insert it into a generated shell command. This creates additional opportunities for the credential to remain in conversation history or tool execution records. ### Attack Path 1. The Skill detects a missing or empty token and asks the user to paste a new access token. 2. The Agent follows `references/token_management.md` and executes: `node scripts/setup_token.js "<TOKEN_VALUE>"`. 3. The complete token becomes part ...[truncated 951 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not accept access tokens through command-line arguments. 2. Read the token from standard input or a masked interactive prompt: ```javascript let token = ""; process.stdin.setEncoding("utf8"); process.stdin.on("data", chunk => { token += chunk; }); process.stdin.on("end", () => { saveToken(token.trim()); }); ``` 3. Prefer a terminal input implementation that disables echo when interactive use is required. 4. Update the documentation to use a non-argument workflow, such as: ```bash node scripts/setup_token.js ``` 5. Ensure Agent tool calls, transcripts, and telemetry never record the complete token. 6. Continue creating the destination file with mode `0600`, but also verify ownership and reject unsafe pre-existing targets such as symbolic links. 7. Provide token rotation and revocation guidance in case a token has previously been passed through `argv`. ]]>
