T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/decrypt-token.js:162
- Finding
- WorkBuddy bearer token exposed through standard output and process arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/decrypt-token.js:162-169`, `scripts/checkin.sh:115-129`, and `scripts/checkin.sh:154-157` **Vulnerability Type**: Sensitive credential exposure **Risk Level**: Medium ### Vulnerable Code `scripts/decrypt-token.js:162-169`: ```javascript if (token && typeof token === "string") { process.stderr.write( "[安全提示] 已从本地登录态读取 accessToken(新版明文存储),仅用于 WorkBuddy 官方签到接口;" + "请勿将其写入日志、分享或提交。\n" ); emitAndExit(0, "DECRYPT_RESULT:" + token); return; } ``` The legacy decryption branch uses the same output mechanism at `scripts/decrypt-token.js:225-232`: ```javascript if (token) { process.stderr.write( "[安全提示] 已从本地会话解密 accessToken(旧版 state.vscdb),仅用于 WorkBuddy 官方签到接口;" + "请勿将其写入日志、分享或提交。\n" ); emitAndExit(0, "DECRYPT_RESULT:" + token); return; } ``` `scripts/checkin.sh:115-129`: ```bash TOKEN="$(read_token)" if [ -z "$TOKEN" ]; then log "❌ 未找到 Node 或 Electron 运行时,或运行时未能产出令牌。请安装 Node.js,或设置 WB_CHECKIN_NODE / WB_CHECKIN_ELECTRON 指向可用运行时。" exit 1 fi if [[ "$TOKEN" == ERR* ]]; then log "❌ 获取令牌失败(${TOKEN})。请确认已安装并登录 WorkBuddy 桌面端。" exit 1 fi API="https://copilot.tencent.com" STATUS=$(curl -s -m 15 -X POST "$API/billing/meter/checkin-status" \ -H "Content-Type: application/json" -H "Accept: application/json" \ -H "Authorization: Bearer $TOKEN" -d '{}' 2>/dev/null || echo "") ``` `scripts/checkin.sh:154-157`: ```bash RESULT=$(curl -s -m 15 -X POST "$API/billing/meter/daily-checkin" \ -H "Content-Type: application/json" -H "Accept: application/json" \ -H "Authorization: Bearer $TOKEN" -d '{}' 2>/dev/null || echo "") ``` ### Technical Analysis The token reader deliberately writes the complete WorkBuddy access token to standard output using the `DECRYPT_RESULT:<token>` format. Although the normal shell wrapper captures that output, directly invoking `decrypt-token.js`, redirecting its output, running it under a verbose automation framework, or attaching output-capt ...[truncated 1943 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Combine token retrieval and HTTPS submission in one process so the credential is never emitted through stdout. 2. Replace the shell-to-Node plaintext token protocol with a narrow operation such as `performCheckin()`, returning only sanitized status data. 3. If curl must remain external, provide the sensitive header through a protected mechanism that avoids the visible argument vector. For example, use a descriptor-backed curl configuration with permissions restricted to the current user and remove it immediately after use. 4. Ensure any temporary credential-bearing resource is created atomically with mode `0600`, is excluded from logs and backups, and is deleted on all exit paths through a trap. 5. Clear the shell variable immediately after the last authenticated request: ```bash unset TOKEN ``` 6. Document that direct execution of the token reader exposes a credential, even after the internal interface has been hardened. 7. Add automated tests that reject plaintext tokens in stdout, stderr, logs, and normal process arguments. ]]>
