T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/compress-pdf.py:200
- Finding
- Arbitrary Base URL Allows PDF and API Credential Exfiltration<![CDATA[ ## Vulnerability Details **File Location**: `scripts/compress-pdf.py:34-52, 69-77, 200` **Vulnerability Type**: Unrestricted sensitive-data destination / SSRF-like behavior **Risk Level**: High ### Vulnerable Code ```python def create_job( base_url: str, api_key: str, pdf_path: str, image_quality: int, dpi: int, timeout_s: int = 60, ) -> Dict[str, Any]: url = base_url.rstrip("/") + CREATE_PATH headers = make_headers(api_key) # multipart/form-data: # - file: PDF document # - imageQuality: number # - dpi: number with open(pdf_path, "rb") as f: files = { "file": (os.path.basename(pdf_path), f, "application/pdf"), } data = { "imageQuality": str(image_quality), "dpi": str(dpi), } resp = requests.post(url, headers=headers, files=files, data=data, timeout=timeout_s) ``` ```python def get_job( base_url: str, api_key: str, job_id: Any, timeout_s: int = 30, ) -> Dict[str, Any]: url = base_url.rstrip("/") + f"/api/{job_id}" headers = make_headers(api_key) resp = requests.get(url, headers=headers, timeout=timeout_s) ``` ```python ap.add_argument("--base-url", default=os.getenv("SOLUTIONS_BASE_URL", DEFAULT_BASE_URL), help="Base URL override") ``` ### Technical Analysis Uploading the PDF and authenticating to the documented Cross-Service-Solutions endpoint are necessary for the declared compression functionality. However, the implementation permits the destination to be replaced through either the `--base-url` argument or the `SOLUTIONS_BASE_URL` environment variable. The supplied URL is not restricted to the declared provider, is not required to use HTTPS, and is not checked against a hostname allowlist. The script subsequently attaches the Bearer token and PDF contents to a request sent to that URL. Consequently, control over the process arguments or environment is sufficient to redirect both sensi ...[truncated 1725 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove `--base-url` and `SOLUTIONS_BASE_URL` if alternate service deployments are not a required feature. 2. If configuration is required, parse the URL and enforce: - The `https` scheme. - An explicit allowlist of approved hostnames. - An approved port, normally `443`. - No embedded username or password. - No URL fragment. 3. Ensure the `Authorization` header is only attached when the final request origin exactly matches an approved provider origin. 4. Disable redirects for authenticated upload and polling requests, or manually validate every redirect target before following it. 5. Reject loopback, link-local, private, multicast, and otherwise non-public destination addresses unless explicitly required. 6. Separate trusted administrator configuration from user-controlled Skill input. 7. Add automated tests confirming that HTTP URLs, unapproved domains, IP literals, alternate ports, and cross-origin redirects are rejected before any file or credential is transmitted. ]]>
