Skip to content

feat: decide advisory host conditions from the URL's constant text - #171

Merged
SizzleUnrlsd merged 4 commits into
mainfrom
feat/advisory-host
Sep 26, 2026
Merged

SizzleUnrlsd merged 4 commits into
mainfrom
feat/advisory-host

Conversation

@SizzleUnrlsd

Copy link
Copy Markdown
Contributor

Summary

An advisory entry point may now declare a host condition: exploiting it needs the attacker to choose the host of the URL passed as the named argument. The correlation decides the condition from the proof ssrf and open-redirect read (taint.urls, #168), with the advisory's own criteria. There is no exception coded per CVE: the data declares the requirement, and the engine decides it.

Closes #170.

Stacked on #169. Merge #169 first; this PR then shows only its own two commits.

URL passed in the host argument Host condition Finding
Constant text fixes the host, and the call disables redirects (allow_redirects=False, follow_redirects=False) contradicted reachable, not exploitable
Constant text fixes the host, and redirects may be followed; input in the query included pending: "the host is fixed by 'https://api.example.com/', but a redirect may lead to a host the attacker controls" exploitable: the initial host does not clear the chain
Anything else: the whole URL is input, the host is left open ("https://api.example.com" + x), or the base is unknown pending, with the condition's own text exploitable, as before

The environment conditions (.netrc, trust_env, a proxy) stay pending, visible next to the host one.

Design

  • Correlation. check_conditions(entry, arguments, url, passed_as) decides a host condition when the attacker's input is passed in the argument it names, by keyword or position. Otherwise the condition stays pending. correlate receives the URL proof of each advisory flow, which _analyse_module computes with flow_url.
  • Loading. A host condition must name its argument and carry no values nor default; the loader rejects anything else.
  • Other conditions. argument conditions are decided as before, and semantic ones stay pending.
  • Enterprise data. Declaring the host condition on the requests advisories comes in a separate Enterprise PR, with a new data release. Until then no curated advisory declares one, so nothing changes for users.

Verification

  • tests/test_advisory_url_host.py, a new file (no existing test file is modified):

    • a host not proven fixed (the whole URL is input, the host is left open, an unknown base);
    • a fixed host with redirects followed (a path, a query);
    • a fixed host without redirects (positional with allow_redirects=False, keyword with follow_redirects=False);
    • the round trip through advisory files;
    • malformed host conditions.

    The seven tests covering the new decisions failed before the change.

  • pytest: 1285 passed. pytest -m regression: 19 passed, unchanged. ruff check and mypy: clean.

  • The Enterprise plugins pass on this branch (257 tests).

taint.urls states what a URL's constant text proves: a fixed origin, a fixed path, a reference on the current site, and whether a call disables redirects. ssrf now reads it with unchanged verdicts, and open-redirect draws its own: refuted on the current site, a hotspot on a fixed host.
A fixed host with redirects disabled rules the call out; with redirects followed the condition stays pending, naming the chain a redirect may open. The correlation reads the same URL proof as ssrf and open-redirect.
@SizzleUnrlsd SizzleUnrlsd added the enhancement New feature or request label Sep 26, 2026
@SizzleUnrlsd SizzleUnrlsd self-assigned this Sep 26, 2026
@SizzleUnrlsd
SizzleUnrlsd merged commit 3d0f4b1 into main Sep 26, 2026
10 checks passed
@SizzleUnrlsd
SizzleUnrlsd deleted the feat/advisory-host branch September 26, 2026 03:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Advisories: a host condition decided from the URL's constant text

1 participant