GitHub Advisoryadvisory · PyPI

GHSA-h47f-gmjp-m7rr compliance-trestle has an URLSecurityValidator SSRF allowlist bypass via IPv4-mapped IPv6 and 0.0.0.0

HIGH Published 2026-08-12 Modified 2026-08-12 Official page ↗
Aliases
CVE-2026-52776
Ecosystem
PyPI
Packages
compliance-trestle
Severity
High
CVSS vector
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N
Weaknesses
CWE-184, CWE-918
Reviewed
2026-08-12

Affected packages

• PyPI compliance-trestle: < 4.1.0 → fixed in 4.1.0

Description

Summary `compliance-trestle` 4.0.3 (latest) ships an `URLSecurityValidator` in `trestle/core/remote/security.py` to block SSRF to loopback / link-local / cloud-metadata endpoints from the HTTPSFetcher and SFTPFetcher remote-fetch paths. The allowlist is incomplete and can be bypassed by four equivalent address representations that resolve to the same blocked host but evade the validator's checks: • IPv4-mapped IPv6 literals (`[::ffff:169.254.169.254]`, `[::ffff:127.0.0.1]`, `[::ffff:10.0.0.1]`) are returned by `socket.getaddrinfo` as `IPv6Address` objects; `IPv6Address in IPv4Network('169.254.0.0/16')` returns `False`, so the `_check_blocked_networks` and `_check_private_networks` predicates do not match. • IPv4 unspecified address `0.0.0.0` is not in `ALWAYS_BLOCKED_NETWORKS` (which covers `127.0.0.0/8` but not `0.0.0.0/8`); on Linux + Docker, `0.0.0.0` routes to local services on any interface, and on dual-stack-mapped sockets it also reaches loopback listeners. A malicious OSCAL profile referencing one of these URLs in `imports[*].href` or `back-matter.resources[*].rlinks[*].href` causes `HTTPSFetcher.__init__` and `_do_fetch` (which both invoke `validator.validate_url`) to pass the URL through to `requests.get`, contacting cloud-metadata services, loopback admin interfaces, or RFC 1918 internal networks (with `TRESTLE_BLOCK_PRIVATE_IPS=true` set) that the validator was specifically designed to block. Affected versions `compliance-trestle` (PyPI) versions ` False raise TrestleError(...) ``` Four independent gaps: 1. No IPv4-mapped IPv6 normalization. `socket.getaddrinfo('::ffff:169.254.169.254', None)` returns an `IPv6Address`. Python's `ipaddress` module raises `TypeError` if mixed types are compared, and the `in` operator suppresses that to `False`. The validator never calls `.ipv4_mapped` to canonicalize before the membership check, so any always-blocked IPv4 range is bypassable via the `[::ffff:N.N.N.N]` literal. 2. `METADATA_HOSTNAMES` is an exact-string set. The hostname for `https://[::ffff:169.254.169.254]/` is `::ffff:169.254.169.254`, which is not in the set. 3. `0.0.0.0` is not blocked. `0.0.0.0` is not in any of the four `ALWAYS_BLOCKED_NETWORKS` ranges. On Linux and inside containers, connecting to `0.0.0.0` routes to local services on any interface (a common SSRF technique against Docker / orchestrator agents on `0.0.0.0:PORT`). 4. DNS rebinding ribbon is only one IP deep. `_resolve_hostname` records the first `getaddrinfo` result set, but a hostname with mixed records can still serve a private IP on the second resolution `validator.validate_url(self._url)` performs in `_do_fetch`. The IPv4-mapped-IPv6 bypass already eliminates the need for rebinding. Sibling code paths sharing the same defect: `SFTPFetcher.__init__` (lines 359-365 of `cache.py`) wires the identical `URLSecurityValidator` and inherits all four gaps. Reproduction (E2E against `pip install compliance-trestle==4.0.3` + local IMDS simulator) ```bash 1. Setup mkdir -p /tmp/poc-trestle && cd /tmp/poc-trestle python3.12 -m venv venv # any supported runtime (requires-python >= 3.10); 3.12.13 chosen because >= 3.12.4 it carries CPython CVE-2024-4032's is_global fix, proving this bypass is is_global-INDEPENDENT ./venv/bin/pip install --quiet compliance-trestle==4.0.3 ./venv/bin/pip show compliance-trestle | head -2 Name: compliance-trestle Version: 4.0.3 2. Driver cat > e2e_full.py = 3.12.4, so CPython CVE-2024-4032's `is_global`/`is_private` reclassification IS active here; the bypass nevertheless works because this validator uses `IPv6Address in IPv4Network(...)` membership (which silently returns False for cross-version …

Related

Alias · CVE (1)

  • CVE-2026-52776 Compliance-trestle (Trestle) is a tooling platform for managing compliance as code. vulnerability

Weakness · CWE (2)

  • CWE-184 Incomplete List of Disallowed Inputs weakness
  • CWE-918 Server-Side Request Forgery weakness

References