Sep 28, 2026·6 min read·31 visits
A logical error in the @grpc/grpc-js xDS path matcher applies a prefix match instead of an exact match when case-insensitive comparison is enabled. This allows clients to bypass RBAC policies and access restricted service endpoints that share a prefix with authorized endpoints.
An authorization bypass vulnerability exists in the @grpc/grpc-js Node.js package (specifically within the xDS plugin wrapper @grpc/grpc-js-xds) due to a logical error in its Role-Based Access Control (RBAC) path matching component. When case-insensitive path matching is enabled, the matching logic performs a prefix comparison using the startsWith method instead of a strict equality comparison. This logic flaw allows unauthenticated or low-privilege clients with access to a shorter path to gain unauthorized access to longer, more privileged method names that share the same prefix.
The @grpc/grpc-js library is a pure JavaScript implementation of the gRPC protocol for Node.js. In microservices architectures, authorization is frequently managed via xDS-based Role-Based Access Control (RBAC) policies, which are parsed and enforced by the @grpc/grpc-js-xds plugin. This component is responsible for examining incoming remote procedure calls (RPCs) and ensuring that clients possess the correct permissions to execute requested methods.
Within this architecture, exact path matching represents a critical mechanism for limiting access to specific gRPC endpoints. Paths are defined hierarchically in the format /ServiceName/MethodName. The vulnerability lies in the logical verification of these paths when processing rules that specify case-insensitive matching.
The attack surface is exposed to any network client capable of sending gRPC requests to an endpoint that relies on the @grpc/grpc-js-xds component for RBAC. Exploitation does not require authentication to the target service if the underlying RBAC rule relies on case-insensitive exact matching to grant permissions.
The root cause of this vulnerability is a logical flaw classified as CWE-187 (Partial String Comparison) and CWE-863 (Incorrect Authorization). In @grpc/grpc-js-xds, the exact path matching logic is implemented within the PathExactValueMatcher class inside packages/grpc-js-xds/src/matcher.ts. This class handles evaluations of incoming RPC paths against configured authorization policies.
When a policy demands an exact match, the evaluator is designed to perform a strict string comparison. However, the implementation branches based on whether the matching rule is case-sensitive. If caseInsensitive is false, the engine correctly performs a strict equality comparison using the identity operator.
When caseInsensitive is true, the engine attempts to normalize the strings using the JavaScript toLowerCase() method. Instead of applying a strict equality check to the normalized strings, the code invokes the startsWith() method. This implementation error changes the behavior from an exact match to a prefix match, validating any incoming path that begins with the target value defined in the policy.
An analysis of the vulnerable codebase in packages/grpc-js-xds/src/matcher.ts reveals the precise code path responsible for the comparison error. The implementation of the apply method in PathExactValueMatcher was written as follows before the patch:
export class PathExactValueMatcher {
// ...
apply(value: string) {
if (this.caseInsensitive) {
// VULNERABLE: Performs a prefix check instead of a strict equality check
return value.toLowerCase().startsWith(this.targetValue.toLowerCase());
} else {
// CORRECT: Performs a strict equality check
return value === this.targetValue;
}
}
}Because of the startsWith() call, an incoming string value such as /myService.Service/MethodSecret matches a policy path of /myService.Service/Method because the prefix matches perfectly. The security patch resolves this discrepancy by replacing the prefix evaluation with a strict equality comparison of the lowercased strings:
export class PathExactValueMatcher {
// ...
apply(value: string) {
if (this.caseInsensitive) {
// FIXED: Performs case-insensitive strict equality check
return value.toLowerCase() === this.targetValue.toLowerCase();
} else {
return value === this.targetValue;
}
}
}The fix is complete and robust against basic prefix-matching bypass vectors. However, developers should be aware that JavaScript toLowerCase() does not account for complex Unicode case folding. While standard gRPC paths are limited to ASCII, any implementations utilizing non-ASCII characters in route configurations could theoretically experience normalization discrepancies.
Exploitation of CVE-2026-101914 requires specific configuration prerequisites on the target gRPC server. The target server must employ xDS-based RBAC policies, contain at least one rule using case_insensitive: true for an exact path matcher, and host service endpoints where one method name serves as a prefix to another more restrictive method.
Consider a deployment where a low-privilege client is authorized to access the /Service/Check method. The server also hosts a highly privileged administrative method named /Service/CheckAdmin. The RBAC policy uses case-insensitive exact matching to authorize access to /Service/Check.
An attacker sends a gRPC request targeting /Service/CheckAdmin. The RBAC engine intercepting the request evaluates the path against the policy. Because of the bug, the evaluation /service/checkadmin.startsWith(/service/check) returns true. The server then executes /Service/CheckAdmin, granting the attacker unauthorized access to administrative functionality.
The overall security impact of this vulnerability is calculated at a CVSS 3.1 Base Score of 6.5 (Medium). The attack vector is Network, and complexity is rated as High due to the specific naming and policy configurations required to trigger the exploit.
When successfully exploited, the integrity of the application is severely compromised because attackers can perform actions they are not authorized to execute. The confidentiality impact is rated as Low because the primary outcome is unauthorized function execution, though this execution may leak state or data. The availability impact is rated as None because the logical flaw does not directly cause application crashes or resource depletion.
This vulnerability is particularly significant in microservices environments that utilize a single gRPC server interface to handle both public and internal endpoints. Bypassing service mesh security boundaries at the gRPC transport layer allows attackers to bypass lateral movement protections and access backend administrative controls.
To fully remediate CVE-2026-101914, administrators and developers must update their @grpc/grpc-js and @grpc/grpc-js-xds dependencies to patched versions. The official fixes are backported and released in multiple release streams.
For systems running on the 1.13.x release line, the package must be upgraded to version 1.13.1 or higher. For systems running on the 1.14.x release line, the package must be upgraded to version 1.14.1 or higher.
If upgrading dependencies is not immediately viable, the vulnerability can be mitigated by disabling case-insensitive matching in the xDS control plane configurations. Setting case_insensitive to false in RBAC policies ensures the engine executes the strict equality code branch. Additionally, services can be refactored to eliminate naming overlaps where one method name is a prefix of another.
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
@grpc/grpc-js gRPC | < 1.13.1 | 1.13.1 |
@grpc/grpc-js gRPC | >= 1.14.0, < 1.14.1 | 1.14.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-187 |
| Attack Vector | Network |
| CVSS v3.1 Score | 6.5 |
| Confidentiality Impact | Low |
| Integrity Impact | High |
| Exploit Status | PoC available |
| KEV Status | Not listed |
The software performs a string comparison that only evaluates a portion of the strings, such as checking if one string starts with another, instead of verifying the entire contents of both strings.
CVE-2026-126192 is an algorithmic complexity vulnerability in Soup Sieve (soupsieve), the default CSS selector engine for Beautiful Soup 4 in Python. Evaluating a CSS selector that contains a general sibling combinator (~) nested inside a :has() relational pseudo-class against attacker-controlled HTML markup triggers O(n^2) quadratic evaluation complexity when the right-hand sibling target is absent. An unauthenticated attacker can supply small HTML documents containing thousands of sibling elements to exhaust CPU resources and stall application worker threads.
CVE-2026-126190 (GHSA-mmhr-3c5m-f64f) is an inefficient algorithmic complexity vulnerability (CWE-407) in Soup Sieve, the default CSS selector library integrated into Beautiful Soup 4. In versions prior to 4.0, evaluating CSS selectors that contain descendant combinators (whitespace between compound selectors) executes an unmemoized upward traversal of the document tree. When evaluated against deeply nested HTML or XML documents, the time complexity scales polynomially at O(n^(k+1)), where n is the tree depth and k is the number of descendant combinators. Remote attackers can supply compact, deeply nested markup (1 KB to 4 KB) to trigger prolonged CPU starvation and denial of service in Python applications.
CVE-2026-122006 is a critical vulnerability in the Ruby on Rails Active Storage framework affecting versions prior to 8.0.5.2 and 8.1.4.1. When an application processes uploaded file attachments using the ImageMagick variant processor (:mini_magick), the framework invokes ImageMagick's metadata analyzer without applying a restrictive security policy. An unauthenticated attacker can upload a crafted file containing directives for unrestricted ImageMagick coders, such as Magick Scripting Language (MSL), resulting in arbitrary server-side file read and write operations. In deployments using the Disk storage service, attackers can exfiltrate sensitive application configuration files, including secret_key_base and master encryption keys, which enables remote code execution via signed payload forgery.
CVE-2026-128065 (also tracked as GHSA-gg5j-6742-v827) is an authorization bypass vulnerability affecting the @grpc/grpc-js-xds library in the Node.js gRPC ecosystem. In versions 1.14.0 and 1.14.1, XdsServer acknowledges Route and VirtualHost resources from an xDS control plane while failing to parse, store, or apply RBACPerRoute override configurations. When experimental RBAC is enabled and a broad top-level ALLOW policy is paired with restrictive VirtualHost or Route overrides, the server evaluates requests strictly against the top-level policy, permitting unauthorized RPC execution.
CVE-2026-126188 (GHSA-3f4q-8x5m-76v8) is an information disclosure vulnerability in the Active Storage component of Ruby on Rails prior to versions 8.0.5.2 and 8.1.4.1. When generating previews or extracting metadata from uploaded media files, Active Storage invokes the external command-line tools ffmpeg and ffprobe without specifying a format whitelist. An attacker who can upload a crafted HTTP Live Streaming (HLS) playlist while declaring a standard video or audio MIME type can cause FFmpeg to engage the HLS demuxer, resolve file:// segment URIs, and disclose visual frames or metadata from local media files readable by the Rails application process.
CVE-2026-126206 (GHSA-jcff-cj73-4w4f) is a Cross-Site Scripting (XSS) vulnerability in version 2.25.2 of the Loofah Ruby gem. The vulnerability stems from an incomplete character reference normalization routine in the `Loofah::HTML5::Scrub.allowed_uri?` method, which fails to decode the HTML5 named character reference `/` (representing the solidus character `/`). Consequently, a crafted `data:` URI such as `data:text/html,<script>alert(1)</script>` bypasses mediatype validation by triggering the WHATWG MIME parser fallback to `text/plain`, while web browsers later resolve `/` to `/` and execute the payload as `text/html`.