
AI Security Briefing
This GHSA advisory documents CVE-2026-27826, a DNS-rebinding TOCTOU bypass of the SSRF fix in the MCP Atlassian server (mcp-atlassian PyPI package). The prior patch (GHSA-7r34-79r5-rcc9) added validate_url_for_ssrf, which resolves the attacker-controlled X-Atlassian-{Jira,Confluence}-Url header host once at middleware time but discards the resolved IP; the actual outbound request later re-resolves the raw hostname at connect time with no IP pinning, so a rebinding DNS name can pass validation with a public IP and then connect to 169.254.169.254 or an internal address, restoring unauthenticated SSRF to cloud metadata/internal services even on the 'patched' build. The advisory includes an executed PoC against the real urls.py, exact code locations (utils/urls.py, servers/main.py, servers/dependencies.py), and remediation via a custom resolver/cached-getaddrinfo adapter to pin the validated IP.
What it is
An incomplete-fix advisory for CVE-2026-27826 in mcp-atlassian (PyPI, patched ≥0.17.0, HEAD ba72540). It reopens the SSRF fixed in GHSA-7r34-79r5-rcc9 (the X-Atlassian-{Jira,Confluence}-Url header SSRF) by showing that fix — PR #986/#1005 — validates but never pins the resolved IP, leaving a DNS-rebinding TOCTOU window. Classified CWE-918 via CWE-367.
How it works
validate_url_for_ssrf in utils/urls.py (~184-205) resolves the attacker-controlled header host, checks each IP is global, then returns only a string verdict (None/error) — the validated IP is discarded. servers/main.py:526,534 calls it once in middleware; servers/dependencies.py:544-561 then builds the fetcher with the raw hostname, so the outbound request re-resolves at connect time with no pinned IP or custom resolver.
flowchart TD
A[Header host] --> B[getaddrinfo #1: 93.184.216.34 global]
B --> C{guard passes?}
C -->|yes, IP discarded| D[fetcher built with raw hostname]
D --> E[getaddrinfo #2: 169.254.169.254]
E --> F[socket connects to metadata/internal]
C -->|if guard saw 169.254...| G[correctly blocked]Preconditions / Affected
- Any version on the "patched" build (HEAD ba72540); the fix does not close this.
- The
X-Atlassian-*-Urlheaders are processed inUserTokenMiddlewarebefore fetcher creation, so an unauthenticated / low-priv caller controls the host. - A live exploit additionally needs an attacker-controlled fast-rebinding authoritative DNS responder that wins the resolve→connect race.
What to do
Pin the connection to the IP that validate_url_for_ssrf validated:
- use a custom resolver / cached-
getaddrinforequests-adapter, or - pass the validated IP directly with a
Hostheader,
so the connect step cannot re-resolve to a different address.
Caveats
The author is explicit that the executed PoC is a boundary demonstration only: it loads the real urls.py by path (sha256 printed) and drives validate_url_for_ssrf, simulating the two resolutions to prove the structural TOCTOU (validated IP discarded, unpinned hostname re-resolved). It does not demonstrate live end-to-end SSRF on a running server. Severity is rated High, not Critical — CVSS v3.1 AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N (≈7.x), with AC:H reflecting the rebinding-race precondition, versus the parent's 8.2. As of 2026-06-27 no advisory, PR, or issue covered connect-time re-resolution.
Organisations named here
- CWE-918
- GHSA-489g-7rxv-6c8q
- GHSA-7r34-79r5-rcc9
- GHSA-xjgw-4wvw-rgm4
CVEs named here
- CVE-2026-27826
Technologies named here
- mcp-atlassian
- Model Context Protocol
- PyPI
- Python
- Jira
Techniques named here
- SSRF
- TOCTOU
- DNS rebinding
- Time-of-check Time-of-use Race Condition
Related in AppSec
Flowise MCP Security Bypass Enables RCE
Inside an Oracle Database SQL Injection Attack | Huntress
OASIS
