Mar 1, 2026·6 min read·4 visits
Gradio < 6.7 on Windows (Python 3.13+) allows unauthenticated arbitrary file read. This is due to a change in how Python handles root-relative paths, bypassing Gradio's traversal protection.
A high-severity absolute path traversal vulnerability exists in Gradio versions prior to 6.7 when running on Windows with Python 3.13 or newer. The vulnerability arises from a breaking change in Python 3.13's `os.path.isabs()` implementation, which no longer treats root-relative paths (e.g., `/Windows/win.ini`) as absolute on Windows. Gradio's path sanitization logic relied on the previous behavior, allowing unauthenticated remote attackers to bypass security checks and read arbitrary files from the host filesystem.
Gradio is a popular open-source Python library used for creating machine learning demos and web applications. It serves static files and assets to end-users via a built-in web server. CVE-2026-28414 represents a logic flaw in how Gradio validates user-supplied file paths, specifically when the application is hosted on a Windows environment running the Python 3.13 runtime or later.
The core issue is not a traditional coding error within Gradio itself, but rather a failure to adapt to an upstream breaking change in the Python standard library. Gradio relied on os.path.isabs() to detect and reject absolute paths provided by users. However, Python 3.13 altered the semantics of this function on Windows, causing it to return False for root-relative paths (paths starting with a slash but lacking a drive letter).
Consequently, an unauthenticated attacker can supply a crafted path like /Windows/win.ini. The application incorrectly classifies this as a safe, relative path and attempts to join it with the static file directory. Due to Windows path joining rules, this resolves to the absolute path on the drive root, granting the attacker access to the file system.
The vulnerability stems from the interaction between Gradio's safe_join utility and the specific implementation of ntpath.isabs (the Windows implementation of os.path.isabs) in Python 3.13.
The Python 3.13 Breaking Change
Prior to Python 3.13, os.path.isabs() on Windows considered any path starting with a directory separator (specifically forward slashes /) as absolute, even if it lacked a drive letter. For example, os.path.isabs('/test') would return True. In Python 3.13, this behavior was aligned with the Windows API strict definition of absolute paths. Now, a path is only considered absolute if it contains both a drive letter and a root directory (e.g., C:\). Therefore, os.path.isabs('/test') now returns False.
The Path Joining Mechanism
Gradio uses os.path.join(base_dir, user_input) to serve files. The Windows implementation of os.path.join has a specific behavior: if a component is an absolute path (or drives-relative), all previous components are discarded, and joining continues from the absolute path.
Crucially, while isabs() now returns False for /Windows/win.ini, os.path.join still treats it as an anchor to the root of the current drive. If the application is running in C:\app\static and the attacker requests /Windows/win.ini:
os.path.isabs('/Windows/win.ini') returns False (Check Passed).os.path.join('C:\app\static', '/Windows/win.ini') resolves to C:\Windows\win.ini.The attacker successfully breaks out of the intended directory.
The vulnerability is located in gradio/utils.py within the safe_join function. This function is responsible for ensuring that file operations are restricted to a specific directory.
The original code relied entirely on os.path.isabs to filter out malicious inputs that attempt to traverse to the root.
def safe_join(directory: DeveloperPath, path: UserProvidedPath) -> str:
filename = os.path.normpath(path)
# ...
if (
any(sep in filename for sep in _os_alt_seps)
or os.path.isabs(filename) # <--- VULNERABILITY POINT
or filename == ".."
or filename.startswith("../")
):
raise ValueError("Invalid path")
# ...In the snippet above, on Python 3.13 (Windows), os.path.isabs("/Windows/win.ini") evaluates to False. The code proceeds to process the path, assuming it is relative to the directory.
The fix introduces an explicit check for paths starting with a forward slash, reinstating the protection that was implicitly provided by older Python versions.
def safe_join(directory: DeveloperPath, path: UserProvidedPath) -> str:
filename = os.path.normpath(path)
# ...
if (
any(sep in filename for sep in _os_alt_seps)
or os.path.isabs(filename)
or filename.startswith("/") # <--- FIX: Explicit check for root-relative paths
or filename == ".."
or filename.startswith("../")
):
raise ValueError("Invalid path")> [!NOTE]
> While this patch addresses the immediate exploit vector, developers should remain cautious of drive-relative paths (e.g., C:file.txt) which might also bypass isabs checks depending on the specific Python version and OS configuration.
Exploiting CVE-2026-28414 requires no special privileges or authentication. The attacker simply needs network access to a vulnerable Gradio instance running on Windows with Python 3.13+.
The attack is performed via a standard HTTP GET request. Gradio endpoints often accept file paths as parameters for component handling.
Prerequisites:
PoC Request:
Assuming the Gradio server is running on 127.0.0.1:7860, the attacker targets a known system file.
curl "http://127.0.0.1:7860/file=/Windows/win.ini"Execution Flow:
/Windows/win.ini.safe_join checks the path. os.path.isabs returns False because the path lacks a drive letter.C:\Users\User\AppData\Local\Temp\gradio).os.path.join sees the leading slash in the second argument and anchors it to the drive root C:\.C:\Windows\win.ini, which is read and returned to the attacker.This technique allows the extraction of any file on the same drive as the running application, provided the process has read permissions (which is the default for most user-accessible files on Windows).
The impact of this vulnerability is rated as High (CVSS 7.5). It fundamentally compromises the confidentiality of the host system.
Confidentiality Loss: Attackers can read any file on the partition where the Gradio application is running. In a typical machine learning environment, this often includes:
.env, config.yaml) containing API keys, database passwords, or cloud provider secrets.Scope Limitations: The vulnerability is strictly an Arbitrary File Read. It does not directly allow for Remote Code Execution (RCE) or file modification (Integrity/Availability impact is None). However, the information gathered (such as credentials) could easily lead to secondary attacks that achieve RCE.
Environment Specificity: The narrow requirement for Python 3.13+ on Windows limits the immediate blast radius compared to platform-agnostic vulnerabilities. However, as Python 3.13 adoption increases, the exposure surface will naturally expand.
The primary remediation is to upgrade the Gradio package to a version that specifically addresses the path traversal logic logic flaw.
Patching: Update Gradio to version 6.7 or later.
pip install --upgrade gradioAlternative Workarounds: If upgrading Gradio is not immediately feasible, the following temporary mitigations can be applied:
os.path.isabs behavior, neutralizing the exploit vector.Verification:
After patching, teams should verify the fix by attempting to request a root-relative path (e.g., /Windows/win.ini or similar) against a non-production instance to ensure a 403 Forbidden or 500 Internal Error is returned instead of the file content.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Gradio Gradio | < 6.7 | 6.7 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-36 |
| Attack Vector | Network |
| CVSS Score | 7.5 (High) |
| Impact | Arbitrary File Read |
| Platform | Windows / Python 3.13+ |
| Exploit Status | PoC Available |
Absolute Path Traversal