CVE-2026-111171
Executive Summary
CVE-2026-111171 is a server-side request forgery (SSRF) vulnerability in the Python library Web3.py affecting versions 7.15.0 through 7.16.0 and 8.0.0b2 through 8.0.0. The flaw resides in the _check_ip_blocked() function, which fails to unwrap IPv4-mapped IPv6 addresses during CCIP Read URL validation. Malicious smart contracts can return OffchainLookup URLs containing IPv4-mapped IPv6 hosts or AAAA records, causing clients with CCIP Read enabled to send requests to loopback, private, or link-local services. This enables attackers to perform internal network reconnaissance, access cloud metadata endpoints, or interact with services bound to localhost, potentially leading to information disclosure or lateral movement within the victim's infrastructure.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
The vulnerability is classified as CWE-918 (Server-Side Request Forgery). Web3.py implements CCIP Read (Cross-Chain Interoperability Protocol Read), a mechanism defined in EIP-3668 that allows smart contracts to offload data retrieval to offchain URLs. When a contract returns an OffchainLookup error, the client is expected to fetch data from a specified URL and return it to the contract. To prevent SSRF attacks, Web3.py includes a validation function _check_ip_blocked() that is intended to block requests to loopback, private, and link-local IP addresses.
The flaw lies in the IP address validation logic. IPv4-mapped IPv6 addresses (e.g., ::ffff:127.0.0.1 or ::ffff:169.254.169.254) are IPv6 addresses that embed an IPv4 address. These addresses are commonly used in dual-stack environments and are treated as IPv6 addresses by many networking stacks. When _check_ip_blocked() processes an IPv4-mapped IPv6 address, it fails to unwrap the embedded IPv4 portion, meaning the validation check does not recognize the address as a blocked IPv4 address (e.g., 127.0.0.1 or 169.254.169.254). As a result, the request is permitted to proceed, and the client sends an HTTP request to the target address.
Additionally, the vulnerability mentions that malicious contracts can return OffchainLookup URLs with "AAAA records." An AAAA record is a DNS record that maps a hostname to an IPv6 address. If an attacker controls a DNS name and configures it with an AAAA record pointing to an IPv4-mapped IPv6 address, the validation may again fail to unwrap the address, allowing the request to reach internal services. This dual attack vector (direct IP in URL and DNS-based redirection) increases the exploitability.
The attack surface is any application using Web3.py with CCIP Read enabled (typically via w3.eth.contract calls that trigger offchain lookups). The vulnerable component is the URL validation logic within the library, which is a client-side control. The impact is that an attacker who can deploy or influence a smart contract (e.g., a malicious token contract, NFT contract, or any contract that returns OffchainLookup) can cause the victim's Web3.py client to make arbitrary requests to internal network resources. The CVSS vector indicates network attack vector (AV:N), high attack complexity (AC:H) because the attacker must craft a contract and have the victim interact with it, no privileges required (PR:N), no user interaction (UI:N), scope changed (S:C) because the vulnerable component (Web3.py client) impacts resources beyond its security scope (internal services), with low confidentiality (C:L) and low integrity (I:L) impact, and no availability impact (A:N).
Exploitation Scenarios
The attack chain for CVE-2026-111171 requires the attacker to control or compromise a smart contract that the victim's Web3.py client interacts with.
Reconnaissance/Target Identification: The attacker identifies a target application or user that uses Web3.py with CCIP Read enabled. This could be a decentralized application (dApp) backend, a wallet service, a blockchain explorer, or any Python-based service that resolves offchain data via EIP-3668. The attacker may also need to know or guess internal network addresses they wish to target (e.g.,
127.0.0.1,169.254.169.254for cloud metadata, or private IP ranges like10.0.0.0/8).Triggering the Flaw: The attacker deploys a malicious smart contract that, when called (e.g., via a
viewfunction or transaction that triggers a CCIP Read lookup), returns anOffchainLookuperror containing a URL that points to an IPv4-mapped IPv6 address or a hostname with an AAAA record resolving to such an address. For example, the URL might behttps://[::ffff:169.254.169.254]/latest/meta-data/orhttps://malicious.example.com/wheremalicious.example.comhas an AAAA record::ffff:127.0.0.1. The victim's Web3.py client, upon receiving theOffchainLookup, attempts to validate the URL using_check_ip_blocked(). Due to the flaw, the validation does not block the address.Payload/Execution Method: The client then sends an HTTP GET request to the crafted URL. Since the URL resolves to an internal or loopback address, the request is sent to the internal service. The attacker does not need to deliver a separate payload; the request itself is the exploitation. The response from the internal service is then returned to the smart contract (or processed by the client), potentially exposing sensitive information. In some configurations, the response might be included in the transaction or displayed to the user, but even if not, the attacker can infer information based on the success or failure of the request or by observing timing differences.
Post-Exploitation Impact: Successful exploitation allows the attacker to perform SSRF, which can be used to:
- Access cloud instance metadata services (e.g., AWS EC2 metadata at
169.254.169.254) to retrieve temporary credentials, potentially leading to full cloud account compromise. - Scan internal networks and identify open ports and services.
- Interact with internal APIs that lack authentication when accessed from localhost.
- Retrieve sensitive files from local services (e.g.,
http://127.0.0.1:8080/admin). - Bypass firewall restrictions by using the victim's machine as a proxy. The impact is limited to confidentiality and integrity (low) as per CVSS, but in cloud environments, the impact can be severe if metadata credentials are exposed.
- Access cloud instance metadata services (e.g., AWS EC2 metadata at
No public PoC or exploit code is available; the attack chain is inferred from the vulnerability class and the NVD description.
Impact Assessment
The CVSS v3.1 score is 5.4 (Medium), with vector CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:L/I:L/A:N. The attack vector is network-based, but attack complexity is high because the attacker must craft a malicious contract and ensure the victim interacts with it. No privileges are required, and no user interaction is needed beyond the victim's client processing the contract call. The scope is changed because the vulnerable Web3.py client can affect resources beyond its security scope (internal services). Confidentiality and integrity impacts are low, and there is no availability impact.
The business impact includes potential unauthorized access to internal services, information disclosure, and in cloud environments, credential theft leading to broader compromise. Affected systems are any application using Web3.py versions 7.15.0-7.16.0 or 8.0.0b2-8.0.0 with CCIP Read enabled. This includes blockchain nodes, dApp backends, wallet services, and any Python service interacting with smart contracts that support EIP-3668. The blast radius depends on the network segmentation and the sensitivity of internal services reachable from the vulnerable client. In a cloud environment, the blast radius could extend to the entire cloud account if metadata credentials are obtained.
Detection Guidance
Sigma Rule
title: Web3.py CCIP Read SSRF Attempt via IPv4-Mapped IPv6
id: 8f3c2d1e-4a5b-6c7d-8e9f-0a1b2c3d4e5f
status: experimental
description: Detects potential SSRF exploitation attempts against Web3.py clients via CCIP Read OffchainLookup URLs containing IPv4-mapped IPv6 addresses.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-111171
author: Threat Intelligence Team
date: 2026-01-01
tags:
- attack.t1190
- attack.initial_access
logsource:
category: process_creation
product: linux
detection:
selection:
Image|endswith: '/python'
CommandLine|contains: 'web3'
condition: selection
falsepositives:
- Legitimate use of Web3.py with CCIP Read to non-malicious endpoints
level: medium
YARA Rule
rule CVE_2026_111171_Web3py_SSRF
{
meta:
description = "Detects Web3.py versions vulnerable to CVE-2026-111171"
author = "Threat Intelligence Team"
date = "2026-01-01"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-111171"
strings:
$s1 = "_check_ip_blocked" ascii
$s2 = "OffchainLookup" ascii
$s3 = "CCIP Read" ascii
$s4 = "ipv4_mapped" ascii
condition:
any of them
}
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2026-111171 Web3.py CCIP Read SSRF Attempt"; flow:to_server,established; content:"GET"; http_method; content:"OffchainLookup"; http_header; pcre:"/\[::ffff:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\]/U"; reference:cve,2026-111171; classtype:attempted-recon; sid:1000001; rev:1;)
Elastic Detection
process where process.name == "python" and process.args : "*web3*" and process.args : "*OffchainLookup*"
Splunk SPL Query
index=main sourcetype=web3:client_logs OR sourcetype=python:app_logs
| search "OffchainLookup" OR "_check_ip_blocked"
| regex _raw="\[::ffff:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\]"
| stats count by host, src_ip, dest_ip, url
| where count > 0
Wazuh OSSEC Rule
<group name="web3,ssrf,">
<rule id="100001" level="10">
<decoded_as>json</decoded_as>
<field name="message">OffchainLookup</field>
<regex>\[::ffff:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\]</regex>
<description>CVE-2026-111171: Possible Web3.py CCIP Read SSRF exploitation attempt</description>
<mitre>
<id>T1190</id>
</mitre>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source).
Immediate Mitigations:
- Disable CCIP Read functionality if not strictly needed. In Web3.py, this can be done by not using the
ccip_read_enabledoption or by setting it toFalsewhen making contract calls. - Implement network segmentation to limit the ability of the Web3.py client to reach sensitive internal services (e.g., block access to loopback and link-local addresses at the host firewall level).
- Use an HTTP proxy for all outbound requests from the Web3.py client, and configure the proxy to block requests to private IP ranges, including IPv4-mapped IPv6 addresses.
- Monitor for anomalous requests to internal IP addresses from Web3.py processes.
- Disable CCIP Read functionality if not strictly needed. In Web3.py, this can be done by not using the
Patch/Upgrade Steps:
- No patch is currently available. Track the official Web3.py repository for updates. Once a patched version is released, upgrade to the latest version.
- As a temporary workaround, consider using a custom URL validation wrapper that properly unwraps IPv4-mapped IPv6 addresses before calling
_check_ip_blocked().
Long-Term Hardening:
- Implement robust SSRF protection that normalizes and validates all IP addresses, including IPv4-mapped IPv6 addresses and DNS resolutions.
- Use network policies to restrict outbound traffic from application servers to only necessary destinations.
- Regularly update dependencies and monitor CVE feeds for Web3.py and related libraries.
- Conduct security reviews of smart contracts before interacting with them, especially those that return OffchainLookup errors.
References
- NVD Entry: https://nvd.nist.gov/vuln/detail/CVE-2026-111171
- Web3.py GitHub Repository: https://github.com/ethereum/web3.py
- EIP-3668: CCIP Read: https://eips.ethereum.org/EIPS/eip-3668
- CWE-918: Server-Side Request Forgery: https://cwe.mitre.org/data/definitions/918.html
- OWASP SSRF Prevention Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html
No known threat actor campaigns or exploit-in-the-wild evidence has been observed for this CVE at this time. CISA KEV status: NO.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.