T09 · Insecure Skill Coding Practices
- Location
modeio_redact/cli/anonymize.py:74- Finding
Unrestricted API Endpoint Override Can Exfiltrate Raw Sensitive Input
- Content
View full analysis
Vulnerability Details
File Location:
modeio_redact/cli/anonymize.py:74andmodeio_redact/cli/anonymize.py:265-276
Vulnerability Type: Unvalidated environment-controlled network destination
Risk Level: MediumVulnerable Code
python # Backend API URL, overridable via ANONYMIZE_API_URL environment variable URL = os.environ.get("ANONYMIZE_API_URL", "https://safety-cf.modeio.ai/api/cf/anonymize")python def _anonymize_via_api_provider( raw_input: str, level: str = "dynamic", sender_code: str = None, recipient_code: str = None, input_type: str = "text", ) -> Dict[str, Any]: payload = { "input": raw_input, "inputType": input_type, "level": level, } if sender_code: payload["senderCode"] = sender_code if recipient_code: payload["recipientCode"] = recipient_code resp = _post_with_retry(URL, headers=HEADERS, json_payload=payload) return resp.json()Technical Analysis
For the
dynamic,strict, andcrossborderlevels, the implementation sends the complete, pre-anonymization input to a remote service. This network operation is part of the declared functionality, but its destination is taken directly from theANONYMIZE_API_URLenvironment variable without validating the URL scheme or hostname.Consequently, the destination can be changed to an arbitrary server, including a plaintext HTTP endpoint. The request body may contain precisely the information the Skill is intended to protect, including personal information, document contents, passwords, access tokens, or API keys. The
requestslibrary also follows HTTP redirects by default, and the implementation does not validate the final destination against an approved origin.This violates least-privilege and secure trust-boundary principles: API-backed anonymization needs permission to communicate with the declared backend, but ...[truncated 2107 chars]
- Remediation
View remediation
Remediation Suggestions
-
Restrict production destinations
- Parse the endpoint with
urllib.parse.urlparse. - Require the
httpsscheme. - Allow only an explicit set of approved hostnames and ports, such as
safety-cf.modeio.ai:443. - Reject URLs containing embedded credentials, fragments, unexpected ports, or malformed hostnames.
- Parse the endpoint with
-
Constrain redirects
- Disable redirects with
allow_redirects=False, or manually validate every redirect target against the same scheme and hostname allowlist.
- Disable redirects with
-
Separate production and development overrides
- Remove unrestricted
ANONYMIZE_API_URLsupport from normal execution. - If custom endpoints are required for testing, require an explicit development flag such as
MODEIO_ALLOW_UNSAFE_API_OVERRIDE=1. - Permit only loopback destinations in development mode unless an additional explicit approval is supplied.
- Remove unrestricted
-
Require informed remote-processing consent
- Consider making
litethe default. - Clearly warn before transmitting file contents remotely.
- Expose the validated destination in machine-readable metadata without printing sensitive payloads.
- Consider making
-
Harden tests
- Make live API smoke tests opt-in rather than enabled by default.
- Continue mocking network requests in normal unit tests.
- Add tests proving that HTTP endpoints, unapproved hosts, embedded credentials, and cross-origin redirects are rejected.
-
Minimize transmitted data
- Where backend behavior permits, send only the content needed for detection or process documents locally.
- Document the remote service’s retention, transport security, and data-processing boundaries.
-
