T09 · Insecure Skill Coding Practices
Error
- Location
- ratelimit.py:20
- Finding
- API Keys Exposed Through curl Process Arguments<![CDATA[ ## Vulnerability Details **File Location**: `probe.py:12-20,63-79`; `quality.py:36-59`; `ratelimit.py:20-43` **Vulnerability Type**: Sensitive credential exposure through command-line arguments **Risk Level**: High ### Vulnerable Code The affected utilities construct authentication headers containing provider API keys and pass those headers directly to `curl` through its argument vector. A representative complete request construction from `ratelimit.py` is: ```python if prov=='gemini': k=creds('gemini')['api_key'] url=f'https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent' h=['Content-Type: application/json',f'X-goog-api-key: {k}'] body=json.dumps({'contents':[{'parts':[{'text':'hi'}]}], 'generationConfig':{'maxOutputTokens':800}}) else: url,key,extra={ 'mistral':('https://api.mistral.ai/v1/chat/completions', creds('mistral')['api_key'],[]), 'openrouter':('https://openrouter.ai/api/v1/chat/completions', creds('openrouter')['api_key'], ['HTTP-Referer: https://arena.ai','X-Title: ArenaAgentMode']), 'kilo':('https://api.kilo.ai/api/gateway/chat/completions', creds('kilo')['api_key'], ['X-KILOCODE-FEATURE: arena-agent']), }[prov] h=['Content-Type: application/json',f'Authorization: Bearer {key}']+extra body=body_common p=subprocess.run( ['curl','-sS','-D','-','-o','/dev/null','-w','%{http_code}',url, '-X','POST','--data-binary','@-','--max-time','40']+ [x for hh in h for x in ('-H',hh)], input=body,capture_output=True,text=True ) ``` `probe.py` and `quality.py` use the same vulnerable pattern by appending secret-bearing headers as `curl -H` arguments. ### Technical Analysis Command-line arguments are normally exposed through process inspection mechanisms such as `/proc/<pid>/cmdline`, process-monitoring software, audit logs, debugging tools, and commands such ...[truncated 1565 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Do not pass authentication headers through `curl -H` command-line arguments. - Reuse the safer implementation already present in `router.py:603-621`: 1. Create a temporary header file using a securely generated name. 2. Set its permissions to mode `0600`. 3. Write authentication headers to that file. 4. Invoke `curl` using its header-file/config-file support without putting the secret in argv. 5. Delete the file in a `finally` block. - Prefer a native HTTP client library that keeps headers in process memory rather than spawning `curl`. - Add an automated test that inspects the child process argument vector and verifies that no API key or authorization header is present. - Correct the blanket documentation claim that keys never appear in process listings until all affected utilities have been repaired. ]]>
