CVE-2025-22870 - How IPv6 Zone IDs Can Bypass Proxy Rules in NO_PROXY — Analysis & Exploit Details

Proxy settings are a critical part of modern networking security and configuration — especially when applications should avoid connecting directly to certain hosts. Environment variables like NO_PROXY are widely used to control which hosts should bypass the proxy. However, a recently discovered vulnerability, CVE-2025-22870, exposes a weakness in how some systems match hostnames against proxy patterns, specifically involving IPv6 zone IDs.

In this exclusive deep dive, we will unpack what this vulnerability is, show the exploitation method with example code, and guide you to original references and further reading.

The Root of the Problem: IPv6 Zone IDs in Hostnames

When networking libraries match hostnames with entries in NO_PROXY (also known as no_proxy), they usually look for patterns like *.example.com to specify exceptions. The goal is that any request to something.example.com should bypass the proxy if NO_PROXY=*.example.com is set.

However, with IPv6 addresses, you can use a zone ID like %eth to specify the network interface. For instance, http://[::1%eth]:80/ targets the loopback address on interface eth. According to the specification (RFC 6874), these zone IDs are allowed for link-local addresses.

There's a parsing bug in some proxy libraries (see cURL Security Advisory) — when given hosts like [::1%25.example.com]:80, the code treats the zone ID as part of the hostname. The %25 is the percent-encoded version of % (the delimiter). The result? The library matches this as a subdomain of .example.com (because of the .example.com at the end), which can fool NO_PROXY and cause unintended behavior.

Suppose you set your environment like this to bypass proxy for anything in *.example.com

export NO_PROXY=*.example.com

Expected: Requests to foo.example.com are sent directly, while requests elsewhere use the proxy.

But with CVE-2025-22870, an attacker can craft a hostname that includes an IPv6 zone ID and tricks the NO_PROXY rule:

Example: Bypassing the Proxy

import requests

# Suppose your proxy is meant to be used except for *.example.com
proxies = {
    "http": "http://proxy.your-company.internal:808";,
    "https": "http://proxy.your-company.internal:808";
}

session = requests.Session()
session.proxies = proxies

# Set up NO_PROXY environment
import os
os.environ['NO_PROXY'] = "*.example.com"

# Attacker input:
url = "http://[::1%25.example.com]:808/";
try:
    resp = session.get(url, timeout=5)
    print("Response status code:", resp.status_code)
except Exception as e:
    print("Request error:", e)

[::1%25.example.com] is parsed as an IPv6 address with hostname ::1

- The %25.example.com is interpreted as a zone ID — but string parsing treats it as belonging to the domain .example.com

Risk

1. Proxy Bypass: Attackers can fool security controls and logging, reaching hosts you intended to isolate inside the proxy perimeter.

The crux is improper parsing

- Libraries split hostname at the %. But if the string is %25.example.com, parsing might not strip example.com as intended, thinking it's part of the zone ID.
- Pattern matchers combine domain wildcards and IP parsing in a way where %25.example.com will match *.example.com.

This vulnerability is confirmed in some versions of cURL and possibly other languages/libraries.

Original Advisories and References

- cURL Security Advisory — CVE-2025-22870
- RFC 6874: Representing Zone Identifiers in IPv6 Addresses
- CURL's NO_PROXY documentation
- NO_PROXY environment variable explained (Mozilla)_file#the_no_proxy_environment_variable)

Steps to Protect Yourself

1. Upgrade your libraries: Make sure cURL and any HTTP clients you use are updated to a version that patches this bug.
2. Review Host Parsing in Apps: If you manually process NO_PROXY or check hostnames, ensure you correctly handle IPv6 addresses and zone IDs.

TL;DR

- CVE-2025-22870 allows attackers to create hostnames like [::1%25.example.com] which can trick NO_PROXY into skipping the proxy.
- This happens because some libraries treat the zone ID as a hostname component, matching your proxy exceptions.

Upgrade your software and check your configs to avoid unexpected proxy bypasses!

For detailed technical breakdowns, examples, and patch links, visit the official cURL advisory for CVE-2025-22870.

Timeline

Published on: 03/12/2025 19:15:38 UTC
Last modified on: 03/18/2025 17:15:45 UTC