T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/add-watermark-to-pdf.py:217
- Finding
- Unrestricted API Base URL Allows Credential and PDF Exfiltration## Vulnerability Details **File Location**: `scripts/add-watermark-to-pdf.py:217-220`, with the sensitive-data transmission occurring at `scripts/add-watermark-to-pdf.py:52-67` and the unvalidated value reaching that operation at `scripts/add-watermark-to-pdf.py:271-276` **Vulnerability Type**: Unvalidated destination for sensitive network transmission **Risk Level**: High ### Vulnerable Code ```python def create_job( base_url: str, api_key: str, pdf_paths: List[str], text: str, timeout_s: int = 180, ) -> Dict[str, Any]: url = base_url.rstrip("/") + CREATE_PATH headers = make_headers(api_key) files: List[Tuple[str, Tuple[str, Any, str]]] = [] opened = [] try: for p in pdf_paths: f = open(p, "rb") opened.append(f) files.append(("files", (os.path.basename(p), f, "application/pdf"))) data = {"text": text} resp = requests.post(url, headers=headers, files=files, data=data, timeout=timeout_s) ``` ```python ap.add_argument( "--base-url", default=os.getenv("SOLUTIONS_BASE_URL", DEFAULT_BASE_URL), help="Base URL override", ) ``` ```python created = create_job( base_url=args.base_url, api_key=args.api_key, pdf_paths=pdf_paths, text=text, ) ``` ### Technical Analysis The script permits the API destination to be replaced through either the `--base-url` command-line argument or the `SOLUTIONS_BASE_URL` environment variable. It performs no validation of the URL scheme, hostname, port, embedded credentials, or relationship to the documented Solutions API domain. The supplied value flows directly into `create_job()`, which appends `/api/61` and sends an HTTP request containing: - The Solutions API key in the `Authorization: Bearer` header - The complete contents of every selected PDF - The supplied watermark text - The input file base names Cons ...[truncated 1850 chars]
- Remediation
- ## Remediation Suggestions 1. Remove `--base-url` and `SOLUTIONS_BASE_URL` support if alternate service deployments are not a documented requirement. 2. If an override is required, parse it with a standard URL parser and enforce an explicit allowlist of trusted hostnames. 3. Require the `https` scheme and reject plaintext HTTP, embedded user information, fragments, unexpected ports, and malformed URLs. 4. Canonicalize and validate the hostname before appending endpoint paths. Do not use substring or suffix checks that permit deceptive domains. 5. Avoid forwarding the Authorization header across redirects. Disable redirects for sensitive API requests or validate every redirect destination against the same allowlist. 6. Prefer an administrator-controlled configuration file over process-environment or agent-generated destination overrides. 7. Clearly notify users that their PDFs and watermark text are uploaded to the named third-party service, and obtain appropriate consent for confidential documents. 8. Add automated tests confirming rejection of `http://` URLs, untrusted domains, embedded credentials, deceptive subdomains, unexpected ports, and redirects to untrusted hosts.
