T09 · Insecure Skill Coding Practices
- Location
bin/run.mjs:295- Finding
API Key Exposed Through Command-Line Arguments
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md:57,65;bin/run.mjs:213,228,295-296
Vulnerability Type: Sensitive credential exposure through process arguments
Risk Level: MediumVulnerable Code
SKILL.md:57:bash node {baseDir}/bin/run.mjs --operation "patentSearch" --api-key "$JUST_SERP_API_KEY" --params-json '{"query":"<query>"}'SKILL.md:65: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:211-214:js if (!args.apiKey) { fail("Missing required --api-key argument."); }bin/run.mjs:225-231:js const requestInit = { headers: { "accept": "application/json", "X-API-Key": args.apiKey, }, method: operation.method, };bin/run.mjs:294-299:js if (flag === "--api-key") { parsed.apiKey = value; index += 1; continue; }Technical Analysis
The documented invocation expands
JUST_SERP_API_KEYinto the argument vector of the Node.js process. The implementation then reads the expanded credential fromprocess.argvand places it in theX-API-Keyrequest header.Passing secrets as command-line arguments is unsafe because process arguments may be observable through operating-system process inspection interfaces, monitoring agents, diagnostic tooling, command auditing, or crash-report collection. The documentation's instruction not to paste or log the key does not prevent these system-level disclosure channels.
The outbound request itself uses HTTPS and targets the fixed, declared domain
api.justserpapi.com; the issue is the local credential transport mechanism rather than plaintext network transmission.Attack Path
- A victim exports a valid
JUST_SERP_API_KEY. - The victim runs the documented command with
--api-key "$JUST_SERP_API_KEY". - The shell expands the environ ...[truncated 1186 chars]
- A victim exports a valid
- Remediation
View remediation
Remediation Suggestions
-
Read the credential directly from the environment instead of accepting it as a command-line argument:
js const apiKey = process.env.JUST_SERP_API_KEY; if (!apiKey) { fail("Missing required JUST_SERP_API_KEY environment variable."); } -
Replace
args.apiKeywith the environment-derived value when constructing the request:js const requestInit = { headers: { accept: "application/json", "X-API-Key": apiKey, }, method: operation.method, }; -
Remove
--api-keyparsing and updateSKILL.mdso the documented invocation does not place the credential in the argument vector:bash JUST_SERP_API_KEY="$JUST_SERP_API_KEY" node {baseDir}/bin/run.mjs \ --operation "patentSearch" \ --params-json '{"query":"<query>"}'When the variable is already exported, omit the inline assignment entirely.
-
If environment-based secret delivery is unsuitable, accept the credential through protected standard input or an operating-system secret manager. Do not print, serialize, or include the credential in errors.
-
Rotate any API key that may already have been captured by process telemetry, shell auditing, monitoring agents, or diagnostic logs.
-
Add regression tests confirming that secrets are absent from
process.argv, standard output, standard error, and generated error payloads.
-
