CVE-2026-4519
Executive Summary
CVE-2026-4519 is a command-line argument injection vulnerability in the Python Standard Library's webbrowser.open() API. When a URL begins with a leading dash (-), certain web browsers interpret the argument as a command-line option rather than a URL, allowing an attacker who controls the URL input to trigger unintended browser behaviors or argument injection. The vulnerability is rated High severity (CVSS 7.0) and affects all Python applications that pass user-supplied URLs to webbrowser.open() without sanitization. The Python Software Foundation (PSF) has confirmed a fix that rejects leading dashes, and users are strongly advised to sanitize URLs prior to passing them to this API.
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 resides in the webbrowser module of the Python Standard Library, specifically in the open() and open_new()/open_new_tab() functions. These functions construct a command-line invocation of the user's default web browser, appending the URL as a trailing argument. For example, on Unix-like systems, the default implementation invokes something like:
xdg-open <url>
or directly invokes a browser binary such as:
/usr/bin/firefox <url>
The flaw is that no validation is performed on the URL string before it is passed to the browser process. If a URL begins with a dash (e.g., -new-window, --incognito, -private), the browser receives it as a command-line flag rather than a URL. This is a classic command-line argument injection flaw (CWE-20: Improper Input Validation).
The attack surface includes any application that uses webbrowser.open() with input that is not fully trusted. Common scenarios include:
- Applications that open URLs from user-supplied messages, chat links, or email bodies.
- Web-facing applications that process query parameters and pass them to
webbrowser.open(). - CLI tools that accept URLs as positional arguments and relay them to the browser.
The impact is limited to local user interaction (AV:L, UI:R) and results in integrity compromise (C:I/L — integrity low) — the attacker can influence browser behavior but cannot directly execute arbitrary code or read sensitive data. However, certain browsers expose dangerous flags (e.g., --load-extension, --user-data-dir, --proxy-server) that could be abused for traffic interception, profile hijacking, or loading malicious extensions, raising the practical impact beyond a simple nuisance.
The fix, as confirmed by OSV and Debian, changes the webbrowser module to reject URLs that begin with a dash, preventing the argument injection at the API boundary. This is a defense-in-depth measure; developers are also instructed to sanitize URLs independently.
Exploitation Scenarios
Step-by-step attack chain:
Reconnaissance / Target Identification — An attacker identifies a Python application (a CLI utility, a desktop app, or a web service) that calls
webbrowser.open()with a URL that includes user-controlled data. Examples include a note-taking app that opens links from entries, a chat client that renders message URLs, or a web dashboard that opens a user-provided URL in a new tab.Trigger / Weaponization — The attacker crafts a malicious URL beginning with a leading dash. For instance, a URL like
--user-data-dir=/tmp/evilor-new-window http://attacker.com. The key is that the first characters of the string are hyphens, so the browser parses them as flags. In a web application context, the attacker submits this string via a URL parameter; in a desktop app, they paste it into a field or submit a crafted message.Payload / Execution — The victim application calls
webbrowser.open()with the crafted string. The browser binary (e.g., Firefox, Chrome, Edge) receives the flag(s). Depending on the browser and flag used, the attacker can:- Force the browser to use a malicious proxy (
--proxy-server=http://attacker-proxy). - Load a malicious extension (
--load-extension=/path/to/malicious). - Use a temporary user-data-dir to hijack session data or install cookies.
- Suppress security warnings (
--no-sandbox,--disable-web-security).
- Force the browser to use a malicious proxy (
Post-Exploitation Impact — With a malicious proxy or disabled security restrictions, the attacker can intercept TLS traffic, inject content into pages, steal session cookies, or install persistent browser extensions. In the case of
--user-data-dir, the attacker can create a new profile that the victim unknowingly uses, enabling credential harvesting.
The attack requires the victim to interact with the application (UI:R) and is local in scope (AV:L), but the integrity impact (I:L) is real — the attacker can alter browser behavior in ways that undermine the confidentiality and integrity of the user's web sessions.
Impact Assessment
CVSS Breakdown — CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N yields a base score of 7.0 (High). The attack vector is Local (requires the attacker to be on the same system or to supply input to an application the victim runs), Attack Complexity is Low, no privileges are required, and only User Interaction (the victim triggering webbrowser.open()) is needed. The scope is Unchanged; confidentiality is not directly compromised (C:N), integrity is low (I:L — argument injection can alter browser behavior), and availability is unaffected (A:N).
Affected Systems — Every Python application using the webbrowser module is theoretically affected, but the practical risk is concentrated in applications that pass untrusted input to webbrowser.open(). This includes:
- Desktop applications with link-opening features.
- CLI utilities that accept URLs from stdin or arguments.
- Server-side Python applications that invoke
webbrowser.open()in user-triggered flows (rare but possible in automation tools).
Blast Radius — The vulnerability does not expose remote attack paths (AV:L), so the immediate blast radius is limited to a single workstation. However, in enterprise environments where developers use Python-based tools (e.g., Jupyter notebooks, internal dashboards, automation agents), a single successful exploitation could lead to session hijacking or data exfiltration through browser manipulation.
Business Impact — For most organizations, the direct risk is low-to-moderate. The primary concerns are (a) developer workstations where sensitive credentials are accessible via browser sessions, and (b) any Python-based toolchain that processes untrusted URLs. The CVSS score of 7.0 reflects the High severity due to low attack complexity and the potential for integrity compromise.
Detection Guidance
Sigma Rule
title: Python webbrowser.open Argument Injection Attempt
id: 2f8d45c1-9a3e-4b22-8f71-6c1d5e0a9bcd
status: experimental
description: Detects attempts to exploit CVE-2026-4519 by passing URLs with leading dashes to webbrowser.open()
tags:
- attack.t1204
- attack.user-execution
- cve.2026.4519
logsource:
category: process_creation
product: linux
detection:
selection:
Image|endswith:
- '/python'
- '/python3'
- '/python3.x'
CommandLine|contains:
- '--user-data-dir'
- '--proxy-server'
- '--load-extension'
- '--new-window'
- '-private'
- '-incognito'
- '-new-window'
filter:
CommandLine|contains:
- 'webbrowser'
- 'webbrowser.py'
condition: selection and filter
falsepositives:
- Legitimate CLI tools that intentionally pass browser flags
level: high
YARA Rule
rule CVE_2026_4519_Webbrowser_Arg_Injection
{
meta:
author = "ValtersIT Threat Intel"
description = "Detects URLs with leading dashes in Python scripts invoking webbrowser.open()"
cve = "CVE-2026-4519"
date = "2026-01-01"
strings:
$open_call = /webbrowser\.(open|open_new|open_new_tab)\s*\(/ nocase
$dash_url = /webbrowser\.(open|open_new|open_new_tab)\s*\(\s*["'`]-[a-zA-Z]/ nocase
$dash_var = /webbrowser\.(open|open_new|open_new_tab)\s*\(\s*[a-zA-Z_]+\s*\)/ nocase
$browser_flag = /--[a-zA-Z-]{3,}|-[a-zA-Z]{1,2}\s/
condition:
($open_call and $dash_url) or ($open_call and $browser_flag)
}
Suricata IDS Rule
alert http any any -> any any (
msg:"CVE-2026-4519 Python webbrowser Argument Injection Attempt";
content:"--user-data-dir"; sid:1004519; rev:1;
classtype:attempted-user;
metadata:created_at 2026_01_01, updated_at 2026_01_01, cve CVE-2026-4519;
)
Elastic Detection
sequence by process.entity_id with maxspan=1s
[process where event.action == "exec" and process.name : "python*" and
process.command_line : "*webbrowser*"]
[process where event.action == "exec" and process.name : ("firefox", "chrome", "chromium", "edge", "safari") and
process.command_line : ("*--user-data-dir*", "*--proxy-server*", "*--load-extension*", "*-private*", "*-incognito*", "*-new-window*")]
Splunk SPL Query
index=main sourcetype="WinEventLog:Security" OR sourcetype="linux_audit"
| where match(CommandLine, "(?i)(python.*webbrowser.*(--user-data-dir|--proxy-server|--load-extension|-private|-incognito|-new-window))")
| stats count by host, user, CommandLine, ParentCommandLine
| sort - count
Wazuh OSSEC Rule
<group name="python,">
<rule id="197808" level="10">
<if_sid>510</if_sid>
<match>webbrowser\.(open|open_new|open_new_tab)\s*\(\s*["'`]?-</match>
<description>CVE-2026-4519: Python webbrowser.open() called with leading dash URL - potential argument injection</description>
<group>attack.t1204,python,cve-2026-4519,</group>
<mitre>
<id>T1204</id>
</mitre>
</rule>
</group>
Mitigation & Patch Guidance
Immediate Mitigations
- Sanitize all URLs before passing to
webbrowser.open()— strip any leading hyphens usingurl.lstrip('-')or validate withurlparseto ensure the scheme ishttp:orhttps:. - Restrict browser flag usage via group policy or browser configuration to block high-risk flags (
--user-data-dir,--load-extension,--proxy-server) when invoked by Python processes. - Audit code for all calls to
webbrowser.open(),open_new(), andopen_new_tab()— flag any instance where the URL parameter originates from user input, database fields, or external APIs.
- Sanitize all URLs before passing to
Patch / Upgrade Steps
- Python 3.x: Update to a patched Python release. The fix is confirmed in the upstream repository (OSV and Debian trackers). Refer to your distribution's security advisory channels.
- Debian/Ubuntu:
sudo apt update && sudo apt upgrade python3(install the patched version once released in the repositories). - RedHat/CentOS/Fedora:
sudo dnf upgrade python3(follow vendor advisories for the exact patched version). - Windows/macOS: Download the latest Python installer from python.org; run the installer to apply the update.
- Pip/environment managers (pip/conda/poetry): Python itself is not pip-installable, but for applications bundled with vendored libs, use
pip install --upgrade <your-application>to pull the fixed version.
Long-Term Hardening
- Adopt a URL-validation helper in your codebase that normalizes and sanitizes all URLs before use.
- Update CI/CD and static analysis to flag
webbrowser.open()calls with unsanitized inputs (add a custom lint rule or use Bandit/SAST tools). - Monitor OSV and Debian trackers for any downstream advisories.
- Educate developers on argument injection risks in any API that constructs shell or subprocess commands.
References
- NVD Entry — https://nvd.nist.gov/vuln/detail/CVE-2026-4519
- Debian Security Tracker — https://security-tracker.debian.org/tracker/CVE-2026-4519
- Python Standard Library Documentation (webbrowser module) — https://docs.python.org/3/library/webbrowser.html
- CWE-20 Improper Input Validation — https://cwe.mitre.org/data/definitions/20.html
Threat Actor Activity / Exploit-in-the-Wild: No known exploits in the wild have been reported as of this writing. EPSS score is 0.00308 (23.1% percentile), indicating low exploitability likelihood. The CVE is not listed on the CISA KEV catalog. PoC/exploit code availability is unknown, but the attack technique is well understood within the argument injection class.
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.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.