T09 · Insecure Skill Coding Practices
- Location
scripts/get-token.mjs:98- Finding
Forgeable Authorization Flow Can Expose User API Keys
- Content
View full analysis
Vulnerability Details
File Location:
scripts/get-token.mjs, lines 98 and 289–402
Vulnerability Type: Hardcoded shared secret in a client-generated authorization flow
Risk Level: MediumComplete Code Snippet
js authPsk: process.env.PO_AUTH_PSK || "processon_mcp_psk_2026",js function generateCode() { const byteLen = 4 + Math.floor(Math.random() * 4); // 4~7 const randomId = crypto.randomBytes(byteLen).toString("hex"); const timestamp = Math.floor(Date.now() / 1000); const payload = `po_mcp_${randomId}_${timestamp}`; const md5Hex = crypto.createHash("md5").update(config.authPsk).digest("hex"); const ivHex = md5Hex.split("").reverse().join(""); const cipher = crypto.createCipheriv("aes-128-cbc", Buffer.from(md5Hex, "hex"), Buffer.from(ivHex, "hex")); const encryptedBuf = Buffer.concat([cipher.update(payload, "utf8"), cipher.final()]); const base64Str = encryptedBuf.toString("base64"); const result = base64Str.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, ""); if (result.length < 26 || result.length > 49) return generateCode(); return result; }js function generateAuthUrl() { ensureStateDir(); const code = generateCode(); fs.writeFileSync(codeFile, `${code}\n`, { encoding: "utf8", mode: 0o600 }); return `${config.authBase}?uuid=${code}&origin=skill&source=processon_skill&payPointSource=${encodeURIComponent(SKILL_SOURCE)}`; }js async function queryToken(uuid) { const url = new URL(config.tokenQueryPath, config.apiBase); url.searchParams.set("uuid", uuid); return requestJson(url); } async function fetchToken(explicitCode) { const code = readCode(explicitCode); if (!code) { console.log("ERROR:no_code"); return 1; } let payload; try { payload = await queryToken(code); } catch { console.log("ERROR:network"); return 1; } const token = extractToken(payload); if (token) { if (saveToken(token)) { cleanup(); console.log("TOKEN_READY"); return 0; } consol ...[truncated 2204 chars]- Remediation
View remediation
Remediation Suggestions
- Replace client-generated encrypted authorization codes with cryptographically random, one-time device codes issued by the server.
- Bind token redemption to a separate verifier held only by the initiating client, such as a PKCE-style verifier and challenge.
- Do not embed shared authentication secrets in distributed client code. Treat all values shipped in the Skill package as public.
- Clearly display the requesting client and authorization scope to the user before approval.
- Make each authorization code single-use and invalidate it atomically after successful redemption.
- Enforce short expiration periods, strict rate limits, and replay detection on authorization and token-query endpoints.
- Bind the authorization transaction to its intended client instance where feasible.
- Review and revoke credentials issued through suspicious or replayed authorization transactions.
