T09 · Insecure Skill Coding Practices
- Location
bin/run.mjs:187- Finding
API Key Exposure Through Command-Line Arguments
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md:48,SKILL.md:55, andbin/run.mjs:116-118,bin/run.mjs:187-204
Vulnerability Type: API credential exposure through the process argument vector
Risk Level: MediumVulnerable Code
SKILL.md:48:bash node {baseDir}/bin/run.mjs --operation "mapsSearch" --api-key "$JUST_SERP_API_KEY" --params-json '{"query":"<query>"}'SKILL.md:55:markdown - Pass the API key with `--api-key "$JUST_SERP_API_KEY"`; do not paste key values into chat messages, screenshots, or logs.bin/run.mjs:116-118:javascript if (!args.apiKey) { fail("Missing required --api-key argument."); }bin/run.mjs:187-204:javascript function parseArgs(argv) { const parsed = { apiKey: null, operation: null, paramsJson: "{}" }; for (let index = 0; index < argv.length; index += 1) { const flag = argv[index]; const value = argv[index + 1]; if (flag === "--operation") { parsed.operation = value; index += 1; continue; } if (flag === "--params-json") { parsed.paramsJson = value; index += 1; continue; } if (flag === "--api-key") { parsed.apiKey = value; index += 1; continue; }Technical Analysis
The documented invocation expands
JUST_SERP_API_KEYinto the command line and the helper reads the resulting secret fromprocess.argv. Consequently, the plaintext credential becomes part of the child process's argument vector.Depending on operating-system permissions and deployment configuration, process arguments may be visible to local users or captured by process-monitoring agents, audit systems, shell tracing, job runners, diagnostic tooling, and command telemetry. Although the helper appropriately transmits the key to the fixed HTTPS endpoint in the
X-API-Keyheader, accepting the credential throughargvunnecess ...[truncated 1473 chars]- Remediation
View remediation
Remediation Suggestions
-
Remove the
--api-keycommand-line option and read the credential directly from the environment:javascript const apiKey = process.env.JUST_SERP_API_KEY; if (!apiKey) { fail("Missing required JUST_SERP_API_KEY environment variable."); } -
Use the environment-derived value only when constructing the request header:
javascript const requestInit = { headers: { accept: "application/json", "X-API-Key": apiKey, }, method: operation.method, }; -
Update
SKILL.mdso the invocation does not expand the secret into an argument:bash JUST_SERP_API_KEY="$JUST_SERP_API_KEY" \ node {baseDir}/bin/run.mjs \ --operation "mapsSearch" \ --params-json '{"query":"<query>"}'If the variable is already exported, omit the inline assignment entirely.
-
If environment-based injection is unavailable, accept the secret through standard input or a permission-restricted credential file rather than through
argv. -
Ensure application logs, shell tracing, CI/CD job output, process telemetry, and error reports never record the API key or request headers.
-
Rotate any credential previously used through the documented command if process arguments may have been collected. Apply server-side expiration, least-privilege scopes, quota limits, and usage monitoring where supported.
-
