T09 · Insecure Skill Coding Practices
- Location
SKILL.md:66- Finding
API Key Exposure Through Command-Line Arguments
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md:66,74andbin/run.mjs:294,309,376-378
Vulnerability Type: Sensitive credential exposure through the process argument vector
Risk Level: MediumVulnerable Code
SKILL.md:66bash node {baseDir}/bin/run.mjs --operation "hotelsSearch" --api-key "$JUST_SERP_API_KEY" --params-json '{"query":"<query>","check_in_date":"<check_in_date>","check_out_date":"<check_out_date>"}'SKILL.md:74markdown - 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:294js if (!args.apiKey) { fail("Missing required --api-key argument."); }bin/run.mjs:306-311js const requestInit = { headers: { "accept": "application/json", "X-API-Key": args.apiKey, }, method: operation.method, };bin/run.mjs:376-379js if (flag === "--api-key") { parsed.apiKey = value; index += 1; continue; }Technical Analysis
The documented invocation expands
JUST_SERP_API_KEYinto a command-line argument. Consequently, the credential may be present in the Node process argument vector for the lifetime of the process.Depending on operating-system configuration and local permissions, command-line arguments may be observable through process-listing utilities, process monitoring, telemetry, diagnostic collection, shell tracing, or audit infrastructure. HTTPS protects the credential while it is transmitted to the fixed API endpoint, but it does not protect the credential from local disclosure before transmission.
The network transmission itself is consistent with the Skill's declared functionality:
bin/run.mjssends the API key in theX-API-Keyheader to the fixed HTTPS hostapi.justserpapi.com. The weakness is the command-line transport used to supply that key to the script.Attack Path
- A user invokes the Skill according to
SKILL.md, causing the shell to replace `$JUST_SE ...[truncated 1091 chars]
- A user invokes the Skill according to
- Remediation
View remediation
Remediation Suggestions
- Read the credential directly from the environment inside
bin/run.mjsinstead of requiring it as an argument:
js const apiKey = process.env.JUST_SERP_API_KEY; if (!apiKey) { fail("Missing required JUST_SERP_API_KEY environment variable."); } const requestInit = { headers: { accept: "application/json", "X-API-Key": apiKey, }, method: operation.method, };- Remove
--api-keyparsing and updateSKILL.mdso the command does not expand the secret into the argument vector:
bash JUST_SERP_API_KEY="$JUST_SERP_API_KEY" \ node {baseDir}/bin/run.mjs \ --operation "hotelsSearch" \ --params-json '{"query":"<query>","check_in_date":"<check_in_date>","check_out_date":"<check_out_date>"}'-
Where stronger isolation is required, accept the secret through a protected file descriptor or a permission-restricted secret file supplied by the runtime.
-
Ensure error messages, telemetry, shell tracing, and diagnostic output never include request headers or the credential.
-
Scope and rotate the API key, enforce quotas where supported, and revoke any key suspected of having appeared in process-monitoring records.
- Read the credential directly from the environment inside
