T09 · Insecure Skill Coding Practices
- Location
scripts/llm_provider_forensics.py:94- Finding
Unvalidated Provider URLs Enable Credential Disclosure and Server-Side Request Forgery
- Content
View full analysis
Vulnerability Details
File Location:
scripts/llm_provider_forensics.py:94-100, 111-114, 125-131, 146-148, 174-178, 427-444
Vulnerability Type: Unvalidated credential-bearing outbound requests / SSRF
Risk Level: High
Category: T09: Insecure Skill Coding PracticesVulnerable Code
python def openai_call(base_url, api_key, model, prompt, endpoint='responses', timeout=20, stream=False): headers = {'Authorization': f'Bearer {api_key}', 'Content-Type': 'application/json', 'User-Agent': 'Mozilla/5.0'} path = '/responses' if endpoint == 'responses' else '/chat/completions' body = {'model': model, 'input': prompt, 'max_output_tokens': 256} if endpoint == 'responses' else {'model': model, 'messages': [{'role': 'user', 'content': prompt}], 'max_tokens': 256, 'temperature': 0} if stream: body['stream'] = True ok, http, lat, raw = _request(base_url.rstrip('/') + path, headers=headers, body=body, timeout=timeout)python def anthropic_call(base_url, api_key, model, prompt, timeout=20): headers = {'x-api-key': api_key, 'anthropic-version': '2023-06-01', 'content-type': 'application/json', 'User-Agent': 'Mozilla/5.0'} body = {'model': model, 'max_tokens': 256, 'messages': [{'role': 'user', 'content': prompt}]} ok, http, lat, raw = _request(base_url.rstrip('/') + '/v1/messages', headers=headers, body=body, timeout=timeout)python def gemini_call(base_url, api_key, model, prompt, timeout=20): base = base_url.rstrip('/') q = urllib.parse.urlencode({'key': api_key}) body = {'contents': [{'parts': [{'text': prompt}]}]} last = {'ok': False, 'http': None, 'latency_s': None, 'text': None, 'usage': None, 'object': None, 'endpoint': None, 'raw_preview': ''} for p in [f'/v1beta/models/{model}:generateContent?{q}', f'/v1/models/{model}:generateContent?{q}']: ok, http, lat, raw = _request(base + p, headers={'Content-Type': 'application/json', 'User-Agent': 'Mozilla/5.0'}, body= ...[truncated 4003 chars]- Remediation
View remediation
Remediation Suggestions
-
Require secure transport
- Accept only
https://URLs by default. - Reject plaintext HTTP unless a narrowly scoped, explicit development override is provided.
- Display a prominent warning and never attach production credentials when an insecure override is used.
- Accept only
-
Validate destinations before sending credentials
- Parse URLs with
urllib.parse.urlsplit. - Reject embedded user information, malformed hosts, unexpected schemes, and unsupported ports.
- Resolve all destination addresses and block loopback, private, link-local, multicast, unspecified, reserved, and cloud metadata ranges by default.
- Revalidate the destination after DNS resolution and immediately before connection to reduce DNS-rebinding risk.
- Parse URLs with
-
Control redirects
- Disable automatic redirects for authenticated probes, or validate every redirect target using the same scheme, hostname, port, and IP policy.
- Strip credentials whenever a redirect changes the origin.
- Set a strict redirect limit.
-
Bind credentials to expected hosts
- Associate each credential with an approved provider hostname or explicit user-maintained allowlist.
- Require interactive confirmation before sending a key to an unrecognized or changed host.
- Use disposable, least-privileged audit credentials for unknown gateways.
-
Reduce Gemini query-string exposure
- Permit query-parameter authentication only where required by the selected protocol.
- Avoid printing, persisting, or including complete request URLs in exceptions and logs.
- Redact
key,api_key, authorization headers, and equivalent secret fields from all diagnostics.
-
Harden configuration handling
- Validate all selected provider records before initiating any request.
- Reject missing, ambiguous, or conflicting URL and protocol fields.
- Document that provider configuration files contain sensitive credentials and should have restrictive filesyste ...[truncated 309 chars]
-
