T09 · Insecure Skill Coding Practices
- Location
SKILL.md:262- Finding
Unvalidated Response-Controlled File Download
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md:262-272
Vulnerability Type: Unvalidated remote URL retrieval
Risk Level: Mediumpython result = requests.get(f"{BASE}/v1/pii/{redact_id}", headers=headers).json() if result["status"] == "completed": report = result["report"] print(f"Redacted {report['total_redactions']} PII instances") for pii_type, info in report["pii_detected"].items(): print(f" {pii_type}: {info['count']} found") # Download redacted file pdf = requests.get(result["redacted_file_url"]).content with open("patient_record_redacted.pdf", "wb") as f: f.write(pdf)Technical Analysis
The example treats
redacted_file_urlfrom the remote API response as trusted and passes it directly torequests.get(). It does not validate the URL scheme, hostname, port, redirects, content type, response size, or PDF signature. It also omits request timeouts and HTTP status validation.If the DeepRead service, an upstream component, or its response channel is compromised, an attacker could provide a URL targeting an internal network service or an attacker-controlled host. Automatic redirect handling can also bypass a superficial hostname check unless every redirect destination is validated. Reading the entire response through
.contentallows an oversized response to exhaust client memory or storage.Attack Path
- An attacker compromises or manipulates the API response associated with a redaction job.
- The response sets
redacted_file_urlto an attacker-selected URL, an internal service address, or an endpoint returning an oversized body. - The client performs the request without validating the destination or limiting the response.
- The request may reach resources available from the client network, disclose request metadata, or consume excessive memory and disk space.
- The unverified response is saved locally with a
.pdfextension r ...[truncated 682 chars]
- Remediation
View remediation
Remediation Suggestions
- Parse the returned URL and require the
httpsscheme. - Maintain an explicit allowlist of trusted DeepRead download hostnames and permitted ports.
- Disable redirects or validate the scheme, hostname, and port of every redirect destination.
- Reject loopback, link-local, private, and reserved IP destinations after DNS resolution where appropriate.
- Add connection and read timeouts.
- Stream the response and enforce a maximum file-size limit instead of loading the entire body into memory.
- Call
raise_for_status()before processing the response. - Validate the expected content type and verify the PDF magic bytes before saving.
- Generate a controlled output path and avoid replacing an existing file unless explicitly authorized.
Example hardening should use a pattern equivalent to:
python response = requests.get( validated_url, timeout=(5, 30), allow_redirects=False, stream=True, ) response.raise_for_status()- Parse the returned URL and require the
