T09 · Insecure Skill Coding Practices
- Location
scripts/ping.sh:13- Finding
API Credentials Exposed Through Process Command-Line Arguments
- Content
View full analysis
Vulnerability Details
File Location:
scripts/ping.sh, lines 13–58
Vulnerability Type: API credential exposure through process arguments
Risk Level: MediumVulnerable Code
bash (ms=$(curl -s -o /dev/null -w "%{time_total}" --max-time 30 \ -X POST "https://api.anthropic.com/v1/messages" \ -H "x-api-key: $ANTHROPIC_KEY" -H "anthropic-version: 2023-06-01" -H "content-type: application/json" \ -d '{"model":"claude-sonnet-4-20250514","max_tokens":1,"messages":[{"role":"user","content":"hi"}]}')bash (ms=$(curl -s -o /dev/null -w "%{time_total}" --max-time 30 \ -X POST "https://api.anthropic.com/v1/messages" \ -H "x-api-key: $ANTHROPIC_KEY" -H "anthropic-version: 2023-06-01" -H "content-type: application/json" \ -d '{"model":"claude-opus-4-20250514","max_tokens":1,"messages":[{"role":"user","content":"hi"}]}')bash (ms=$(curl -s -o /dev/null -w "%{time_total}" --max-time 30 \ -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=$GEMINI_KEY" \ -H "Content-Type: application/json" \ -d '{"contents":[{"parts":[{"text":"hi"}]}],"generationConfig":{"maxOutputTokens":1}}')bash (ms=$(curl -s -o /dev/null -w "%{time_total}" --max-time 30 \ -X POST "https://api.minimax.chat/v1/text/chatcompletion_v2" \ -H "Authorization: Bearer $MINIMAX_KEY" -H "Content-Type: application/json" \ -d '{"model":"MiniMax-M1","messages":[{"role":"user","content":"hi"}],"max_tokens":1}')bash (ms=$(curl -s -o /dev/null -w "%{time_total}" --max-time 30 \ -X POST "https://api.x.ai/v1/chat/completions" \ -H "Authorization: Bearer $XAI_KEY" -H "Content-Type: application/json" \ -d '{"model":"grok-3-mini-fast","messages":[{"role":"user","content":"hi"}],"max_tokens":1}')bash (ms=$(curl -s -o /dev/null -w "%{time_total}" --max-time 30 \ -X POST "https://api.openai.com/v1/chat/completions" \ -H "Authorization: Bearer $OPENAI_KEY" -H "Content-Type: application ...[truncated 2627 chars]- Remediation
View remediation
Remediation Suggestions
- Do not place API keys directly in
curlcommand-line header arguments or request URLs. - Supply sensitive
curlconfiguration through standard input or a protected temporary configuration file rather than ordinary process arguments. - If a temporary configuration file is used:
- Create it in a private directory with permissions restricted to the current user.
- Set a restrictive
umask, such as077, before creation. - Register cleanup immediately with
trapso secrets are removed on normal exit, interruption, or failure. - Avoid predictable paths and never write the file into a shared directory.
- Avoid query-string credentials whenever the provider offers a supported header-based or other less observable authentication method.
- Ensure verbose shell tracing is disabled around secret handling and prevent CI, proxy, and diagnostic systems from logging authentication headers or complete sensitive URLs.
- Apply provider-side least privilege, spending limits, quota alerts, expiration policies, and regular key rotation.
- Revoke and rotate any credential suspected of having appeared in process listings or URL logs.
A hardened pattern is to stream a restrictive
curlconfiguration through standard input:bash curl --config - <<EOF silent output = "/dev/null" write-out = "%{time_total}" max-time = 30 request = "POST" url = "https://api.openai.com/v1/chat/completions" header = "Authorization: Bearer ${OPENAI_KEY}" header = "Content-Type: application/json" data = "{\"model\":\"gpt-4o-mini\",\"messages\":[{\"role\":\"user\",\"content\":\"hi\"}],\"max_tokens\":1}" EOFThe implementation should also verify the behavior of the deployed
curlversion and operating environment to ensure configuration supplied through standard input is not copied into logs or diagnostics.- Do not place API keys directly in
