T09 · Insecure Skill Coding Practices
- Location
scripts/run.py:103- Finding
Unrestricted API Endpoint Can Exfiltrate Authentication Credentials and Clinical Data
- Content
View full analysis
Vulnerability Details
File Location:
scripts/run.py:103-119,scripts/run.py:227, andscripts/run.py:283-291
Vulnerability Type: Unrestricted credential-bearing outbound request
Risk Level: HighVulnerable Code
python def call_llm( *, api_url: str, model: str, appkey: str, system_prompt: str, user_prompt: str, temperature: float, timeout: int, ) -> str: payload = { "model": model, "temperature": temperature, "messages": [ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt}, ], } try: req = Request( api_url, data=json.dumps(payload, ensure_ascii=False).encode("utf-8"), headers={ "Content-Type": "application/json", "Authorization": f"Bearer {appkey}", }, ) resp = urlopen(req, timeout=timeout)The destination is accepted directly from a command-line argument:
python p.add_argument("--api-url", default=DEFAULT_API_URL, help="OpenAI compatible endpoint URL")The unvalidated value and credential are then passed to the network request:
python out["answer"] = call_llm( api_url=args.api_url, model=args.model, appkey=args.appkey, system_prompt=system_prompt_for(task_key, args.system_prompt), user_prompt=user_prompt, temperature=float(args.temperature), timeout=int(args.timeout), )Technical Analysis
The
--api-urloption permits an operator or integration to select an arbitrary URL. The application does not enforce HTTPS, restrict the destination to trusted model-provider hosts, reject local or private network destinations, or constrain redirects.call_llm()sends the following sensitive information to the selected destination:- The model API ...[truncated 2517 chars]
- Remediation
View remediation
Remediation Suggestions
-
Use an explicit endpoint allowlist
- Restrict requests to approved HTTPS hostnames and expected paths.
- Prefer removing
--api-urlfrom production deployments if endpoint customization is unnecessary. - Compare normalized hostnames rather than using substring or suffix checks vulnerable to lookalike domains.
-
Require secure transport
- Reject all schemes except
https. - Reject URLs containing embedded credentials.
- Continue to verify TLS certificates using a trusted certificate store.
- Reject all schemes except
-
Protect against SSRF
- Reject loopback, link-local, private, multicast, and otherwise reserved IP ranges unless explicitly required.
- Resolve the destination and validate all resulting addresses.
- Account for DNS rebinding by ensuring the connection is made to a validated destination.
- Restrict outbound network access at the container, host, or firewall level.
-
Constrain redirects
- Disable automatic redirects for credential-bearing requests or revalidate every redirect destination.
- Never forward the
Authorizationheader when the scheme, host, or port changes.
-
Separate custom endpoints from production credentials
- Require an explicit high-friction confirmation before sending credentials to a non-default endpoint.
- Use endpoint-specific, short-lived credentials with minimum privileges.
- Do not reuse the production model credential for development or user-selected endpoints.
-
Reduce sensitive-data exposure
- Add enforcement or validation supporting the documented requirement to de-identify patient data.
- Warn users before sending clinical content to any custom endpoint.
- Avoid logging credentials, complete prompts, or sensitive response bodies.
-
Respond to suspected exploitation
- Immediately revoke and rotate any credential that may have been sent to an untrusted endpoint.
- Revie ...[truncated 180 chars]
-
