Apr 9, 2026·6 min read·2 visits
A delimiter injection vulnerability in Mercure Hub's cache mechanism allows authenticated attackers to access private topic data or cause denial of service via cache key collisions.
The Mercure Hub's TopicSelectorStore is vulnerable to a cache key collision due to improper delimiter handling. This vulnerability enables an attacker to bypass authorization checks, leading to unauthorized access to private topic data or targeted denial-of-service conditions.
The Mercure Hub implements a real-time messaging protocol utilizing server-sent events. The hub manages a TopicSelectorStore component responsible for matching subscriber topic selectors against published resource URIs. This component employs an internal cache to optimize matching operations and reduce computational overhead during high-volume message broadcasting.
A vulnerability in this caching implementation, classified as CWE-1289 (Improper Validation of Unsafe Equivalence in Input), allows for delimiter injection. The system relies on string concatenation to build cache keys, failing to establish strict boundaries between concatenated variables. This structural flaw produces cache key collisions when inputs contain the designated delimiter character.
An attacker exploiting this vulnerability can force the system to cache a specific match evaluation state under an overlapping key. This manipulation grants unauthorized parties access to private topic updates if they successfully collide their public topic request with a private topic identifier. Conversely, attackers can induce a targeted denial-of-service state by caching a negative match evaluation for legitimate subscribers.
The vulnerability possesses a CVSS 4.0 base score of 7.1, reflecting its high severity. The rating emphasizes the high confidentiality impact and low availability impact executable over a network vector without user interaction. Exploitation mandates only low privileges, specifically the baseline capability to interact with the hub's subscription endpoints.
The underlying flaw resides within the caching logic of topicselector.go. The system builds a string key to store boolean results of topic matching operations. The key construction utilizes a string builder appending the static prefix m_, the selector string, an underscore delimiter, and the topic string.
The specific vulnerability arises from the lack of boundary preservation during this serialization. The underscore character serves as a static delimiter but is also permitted within the dynamic selector and topic fields. The encoding function mathematically fails the property of injectivity, mapping multiple distinct input pairs to identical output strings.
When a specific combination is queried, the cache returns the stored result of the previous overlapping permutation. The engine evaluates selector="a" and topic="b_c" but returns the cached boolean match result originally calculated for selector="a_b" and topic="c". The cache completely ignores the actual structural difference of the two distinct evaluations.
The vulnerable Go implementation prior to version 0.22.0 relied on a strings.Builder to construct the cache key dynamically. The match function combined the variables sequentially with hardcoded bytes.
// VULNERABLE CODE (Pre-v0.22.0)
var b strings.Builder
b.Grow(3 + len(topicSelector) + len(topic))
b.WriteString("m_")
b.WriteString(topicSelector)
b.WriteByte('_') // Static delimiter injection point
b.WriteString(topic)
k = b.String()The patched code in commit 4964a69be904fd61e35b5f1e691271663b6fdd64 completely eliminates the string serialization approach. The developer introduced a strongly typed Go composite struct named matchCacheKey.
// MITIGATED CODE (v0.22.0)
type matchCacheKey struct {
topicSelector string
topic string
}
// ... inside match function ...
k := matchCacheKey{topicSelector: topicSelector, topic: topic}
if value, found := tss.matchCache.GetIfPresent(k); found {
return value
}This structural change permanently resolves the vulnerability class. The Go runtime evaluates composite map and cache keys by comparing individual fields sequentially, maintaining strict boundaries in memory. This native language feature prevents string values from bleeding into adjacent fields, fully neutralizing the CWE-1289 vulnerability.
The attack methodology requires the threat actor to establish an authenticated session with the Mercure Hub. The attacker must possess the privileges to subscribe or publish to specific target topics within the instance. Anonymous, unauthenticated exploitation is structurally impossible unless the hub is explicitly configured for open access.
The attacker evaluates the target environment to identify a private topic structure. The objective is to determine a corresponding public or accessible topic combination that produces an identical concatenated string. The attacker must mathematically align the underscore placements across the topicSelector and topic inputs.
The cache poisoning sequence is initiated by requesting the crafted public permutation. This action forces the Mercure Hub to evaluate the match and store the resulting state under the compromised key identifier. The attacker deliberately triggers this evaluation to embed a known state into the cache memory space.
Subsequent requests executing against the private topic permutation trigger the collision. If an authorized client requests the private stream, they receive the cached negative match, resulting in a targeted denial of service. Conversely, if the attacker engineered a positive match cache entry, they bypass standard authorization barriers to read restricted data streams.
The primary consequence of successful exploitation is a breakdown of authorization boundaries for real-time messaging streams. Attackers achieve read access to restricted data streams intended exclusively for privileged internal components or specific users. This represents a high confidentiality impact under the CVSS scoring system.
The vulnerability facilitates a secondary denial-of-service capability against the messaging subsystem. By deliberately seeding negative match results under collided keys, attackers can actively block authorized subscribers from receiving critical system updates. This availability impact is evaluated as low due to its targeted nature and localized effect.
Exploitation is contingent upon specific structural requirements within the deployment. The attacker must possess prior knowledge of target private topic structures to synthesize the overlapping input permutations. Additionally, the attacker must hold a valid connection token to interact with the hub's subscription mechanisms.
The CVSS 4.0 vector formulation calculates a base score of 7.1. The variables contributing to this score are the network attack vector (AV:N), the absence of complex attack prerequisites (AC:L), and the lack of required user interaction (UI:N). The confidentiality impact (VC:H) drives the ultimate severity classification.
The primary mitigation path requires administrators to upgrade the Mercure deployment to version 0.22.0 or subsequent releases. This version structurally addresses the delimiter injection vulnerability by modifying internal cache key data types. The adoption of Go composite structs prevents the underlying input parsing failure.
Workaround feasibility is extremely low for deployments unable to patch immediately. Implementing a Web Application Firewall (WAF) or reverse proxy rule to globally block underscores in topic names is generally impractical. Underscores function as standard characters in many RESTful resource identifiers and dropping them disrupts legitimate traffic flows.
The applied patch provides a complete and permanent fix for this specific code pathway. The structural change to native interface caching neutralizes the entire CWE-1289 vulnerability class within the TopicSelectorStore. Variant string injection attacks against this subsystem are mathematically impossible under the new architecture.
Organizations should complement the technical patch with defense-in-depth reviews. Security teams must review internal topic nomenclature to ensure strict access token boundaries. External clients must only receive tokens scoped strictly to their required access domains, minimizing the attack surface for potential authenticated manipulation.
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:L/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Mercure Hub github.com/dunglas | < 0.22.0 | v0.22.0 |
| Attribute | Detail |
|---|---|
| Vulnerability Type | Improper Validation of Unsafe Equivalence in Input (CWE-1289) |
| Attack Vector | Network (Authenticated) |
| CVSS 4.0 Score | 7.1 (High) |
| Confidentiality Impact | High |
| Exploit Maturity | Proof of Concept (PoC) |
| Fixed Version | v0.22.0 |
The software uses a mechanism to determine if two inputs are equivalent, but the mechanism can be manipulated to improperly identify non-equivalent inputs as equivalent.