T09 · Insecure Skill Coding Practices
- Location
bin/run.mjs:146- Finding
API Key Exposure Through Command-Line Arguments
- Content
View full analysis
Vulnerability Details
File Location:
bin/run.mjs:79-81, 146-158; documented invocation atSKILL.md:42, 49
Vulnerability Type: API credential exposure through process arguments
Risk Level: MediumVulnerable Code
javascript if (!args.apiKey) { fail("Missing required --api-key argument."); }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]; // Other argument handling omitted. if (flag === "--api-key") { parsed.apiKey = value; index += 1; continue; } fail(`Unknown argument "${flag}".`); } return parsed; }The documented invocation exposes the environment variable through argument expansion:
bash node {baseDir}/bin/run.mjs --operation "ScholarCiteSearch" --api-key "$JUST_SERP_API_KEY" --params-json '{"query":"<query>"}'Technical Analysis
The helper requires the API key to be supplied using
--api-key, andparseArgs()obtains it fromprocess.argv. Although the secret originates in an environment variable, the shell expands$JUST_SERP_API_KEYbefore launching Node, placing the plaintext credential in the child process's command-line argument vector.Depending on operating-system permissions and process isolation, command-line arguments may be observable through facilities such as
/proc/<pid>/cmdline, process-listing utilities, monitoring agents, diagnostic tooling, or captured execution telemetry. The request itself uses HTTPS and sends the key in theX-API-Keyheader; the confirmed weakness is the local credential-transfer mechanism rather than plaintext network transport.Attack Path
- A user stores a valid credential in
JUST_SERP_API_KEY. - The user runs the command documented in
SKILL.md. - The shell expands
$JUST_SERP_API_KEYand places its plaintex ...[truncated 954 chars]
- A user stores a valid credential in
- Remediation
View remediation
Remediation Suggestions
- Read the credential directly from the process environment instead of accepting it through a command-line option:
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, };- Remove
--api-keyhandling fromparseArgs()and remove the flag from every documented invocation:
bash JUST_SERP_API_KEY="..." node {baseDir}/bin/run.mjs \ --operation "ScholarCiteSearch" \ --params-json '{"query":"<query>"}'Prefer setting the variable through a secret manager or protected execution environment rather than inline shell assignment, because inline assignments may also be retained in shell history or automation logs.
-
Reject
--api-keyexplicitly during migration so users do not unknowingly continue exposing credentials through process arguments. -
Review process-monitoring, CI/CD, and diagnostic systems for previously captured command lines. Rotate any key that may have been exposed.
-
Ensure errors and debug output never include request headers, the environment-derived key, or the full argument vector.
