Oct 9, 2026·6 min read·3 visits
A parser mismatch between Python's urllib.parse.urlsplit and HTTP client libraries allows event organizers to bypass local network blocklists using backslash characters in URLs.
An incomplete Server-Side Request Forgery (SSRF) validation check in Indico prior to version 3.3.13 allows authenticated event organizers to bypass outbound network restrictions. By utilizing backslash characters within crafted URLs, attackers can exploit a parser differential between the application's validator and the downstream HTTP client library to access internal network resources.
The open-source event management system Indico, developed at CERN, uses Flask and the Flask-Multipass multi-backend authentication framework. The platform provides event organizers with various features to integrate remote data, including syncing external calendar files and executing outbound webhooks. Because the application initiates outbound network connections on behalf of users, it implements validation routines to prevent Server-Side Request Forgery (SSRF) attacks against internal networks.
CVE-2026-107394 represents an incomplete SSRF validation check that fails to properly handle backslash characters in user-provided URLs. The flaw allows high-privileged authenticated users, such as event organizers, to construct payloads that bypass the internal network blocklist mechanism. An attacker can leverage this bypass to establish unauthorized connections to private services running on the loopback interface or the internal intranet.
The underlying issue stems from a parser differential between the validation component and the downstream HTTP client library. This report provides a detailed technical breakdown of the root cause, the vulnerable code structures, and the remediation steps required to secure affected systems.
The core of the vulnerability resides in the is_private_url function defined in indico/util/network.py. This validation function is designed to check whether a supplied URL resolves to a private IP address range (such as RFC 1918 networks, loopback addresses, or link-local addresses). To extract the target hostname for verification, the function relies on the standard Python library function urllib.parse.urlsplit.
A significant parsing discrepancy occurs when the input URL contains a backslash (\) character, such as in the string http://127.0.0.1\\@1.1.1.1. Python's urlsplit parser does not treat backslashes as equivalent to forward slashes. Consequently, it processes the authority portion of the URL in a manner that identifies 1.1.1.1 (a public, routeable IP address) as the target hostname, passing the validator's check.
In contrast, when the downstream HTTP transport layer (typically powered by libraries like urllib3 or requests) processes the same URL, it normalizes or corrects the backslash. This normalization treats the backslash as a structural delimiter, parsing 127.0.0.1 as the actual host and treating @1.1.1.1 as part of the path or credential block. As a result, the client connects to localhost (127.0.0.1), entirely bypassing the protection layer.
To clarify the mechanism of the vulnerability, the diagram below illustrates how the different parsing libraries interpret the same input string, leading to an unauthorized connection to local resources.
Prior to version 3.3.13, the is_private_url function did not perform pre-parsing validation on the raw URL string to check for special characters. The following snippet illustrates the vulnerable implementation:
# VULNERABLE
def is_private_url(url):
"""Check if the provided URL points to a private IP address."""
# urlsplit extracts the hostname, but fails to handle backslashes correctly
hostname = urlsplit(url).hostname
if not hostname:
return True
# [Hostname resolution and private range checks continue...]To address this vulnerability, the development team implemented a strict pre-parsing validation step in commit 44540e70ab4e20a12f14ddba5218a33749a86736. If the raw URL contains a backslash character, the function immediately terminates and returns True, classing the URL as private/prohibited:
# PATCHED
def is_private_url(url):
"""Check if the provided URL points to a private IP address."""
# Reject any URL containing a backslash to prevent parser differentials
if '\\' in url:
return True
hostname = urlsplit(url).hostname
if not hostname:
return True
# [Hostname resolution and private range checks continue...]This validation strategy is highly effective against the specific backslash-based bypass. However, relying on string-matching blacklists can sometimes introduce risk if other novel character representations or normalization behaviors exist within downstream HTTP components. A more robust defensive architecture would involve resolving the host to an IP address at the socket connection level.
Exploitation of CVE-2026-107394 requires an attacker to hold an account with "Event Organizer" or administrative privileges. This level of access is necessary to interact with features that make outbound requests, such as remote calendar synchronization (.ics importing) or webhook setups. Once authenticated, the attacker navigates to the relevant input form and provides the payload:
http://127.0.0.1:8080\\@1.1.1.1
The application validates the URL, extracts the host as 1.1.1.1, and permits the operation. When the backend service attempts to fetch the data, it connects to port 8080 on the loopback interface (127.0.0.1). If the target service returns data, Indico processes and displays or imports the response. This behavior allows the attacker to read sensitive data from local configuration endpoints, administration interfaces, or container metadata APIs (e.g., cloud provider IMDS endpoints at 169.254.169.254).
This vulnerability is assigned a CVSS v3.1 score of 6.8 (Medium) due to the requirement for high privileges (PR:H). Although the impact on confidentiality is high, there is no direct impact on integrity or availability. The change in scope (S:C) highlights the attacker's ability to cross security boundaries from the web application layer into the underlying hosting network environment.
To detect potential exploitation attempts, security administrators should monitor application logs for anomalous URL structures in configuration forms. Web Application Firewalls (WAF) can be configured to block request payloads containing backslash characters within URL fields. The following regular expression can detect typical backslash-based bypass vectors:
(?i)(https?|ftp)(%3A|:)(%2F|/){2}[^/% s]+(%5C|\\)
The primary remediation is to upgrade Indico to version 3.3.13 or higher. The patch fully resolves the backslash bypass by returning a fail-secure state when a backslash is detected. If upgrading immediately is not feasible, administrators can temporarily implement network-level firewall rules.
For defense-in-depth, configure the Indico application container with limited network access. Restrict outbound traffic to local loopback ranges (127.0.0.0/8, ::1) and internal private addresses unless explicitly required for production integration.
| Product | Affected Versions | Fixed Version |
|---|---|---|
Indico Indico | < 3.3.13 | 3.3.13 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-918 |
| Attack Vector | Network |
| CVSS Score | 6.8 (Medium) |
| EPSS Score | 0.00% |
| Impact | Server-Side Request Forgery |
| Exploit Status | Proof of Concept / Test Case Available |
| KEV Status | Not Listed |
An authorization bypass vulnerability exists in the legacy session export API of Indico, an open-source event management system developed at CERN. Due to a missing object-level access check, authenticated users can bypass configuration-level restrictions to extract private session metadata (including session titles, descriptions, and list of conveners) from events that they are otherwise authorized to view.
CVE-2026-107717 represents a critical prompt boundary bypass and chat role injection vulnerability in the Banks Python package (versions prior to 2.5.0). The library parses generated template outputs line-by-line, attempting to validate each segment as a JSON-serialized ChatMessage object without validating the source boundaries of the text. If an application integrates user input directly into a prompt template, a remote, unauthenticated attacker can supply multi-line inputs with structured JSON payloads. This input is then parsed as high-privilege system instructions or tool execution responses, completely hijacking downstream Large Language Model behavior.
Improper pathname limitation and link resolution (CWE-22 and CWE-59) in the banks library prior to version 2.5.1 allow local attackers to read or write arbitrary files via crafted symbolic links in the prompt directory registry.
Improper validation of dynamic class resolution within Hazelcast's Zero Config Compact Serialization allows unauthenticated clients to trigger reflective class instantiation. This flaw can be exploited to read arbitrary JVM heap or off-heap memory, crash cluster nodes, or achieve arbitrary code execution under specific classpath conditions. This issue is resolved in Hazelcast versions 5.4.5, 5.5.10, 5.6.1, and 5.7.0.
An authentication bypass vulnerability in NearForm's fast-jwt before version 6.3.4 allows attackers to replay expired tokens due to an error in the verifier's cache expiration logic. When caching is enabled, the cache TTL defaults to 10 minutes instead of honoring the token's exp claim if the token lacks an iat claim.
CVE-2026-61427 is a critical authentication bypass and improper input validation vulnerability within the Model Context Protocol (MCP) HTTP-stream server of PraisonAI. In versions prior to 4.6.78, the server lacks authentication by default and forwards client messages directly to Python tool handlers without input validation. When bound to non-localhost interfaces, this permits unauthenticated remote attackers to perform unauthorized administrative operations and execute tools.