Sep 9, 2026·6 min read·2 visits
Astro prior to 7.2.4 allowed attackers to bypass path-based authorization middleware via a partial string matching flaw when stripping custom base paths (e.g., /appX/admin resolved to /app/admin but bypassed middleware looking for /app/admin).
An authorization bypass vulnerability exists in the Astro web framework prior to version 7.2.4. When configured with a non-root base path, Astro's routing engine stripped the base path from incoming request URLs using an insecure prefix-match check without verifying path-segment boundaries. This created a path parser differential between user-defined middleware and the internal router. An unauthenticated attacker could bypass route-based authorization checks to access administrative or privileged endpoints by altering the path prefix segment.
Astro is a modern web framework designed for building content-driven websites. To support hosting applications under subpaths, the framework allows developers to define a custom, non-root base path (such as '/app'). When configured, Astro is responsible for routing requests relative to this base while developer-defined middleware manages global application concerns, including route-level authentication and authorization.
A flaw exists in Astro's path-handling subsystem prior to version 7.2.4. When parsing incoming HTTP request pathnames, the routing mechanism incorrectly evaluates and strips the base path using a simple prefix match without verifying path-segment boundaries. This implementation defect introduces a critical parser differential between the framework's internal routing engine and standard authorization middleware.
The vulnerability is classified as CWE-187 (Partial String Comparison). It represents a significant class of routing-related security flaws where inconsistent interpretations of a resource path between different security boundaries permit unauthorized access to protected components without authentication.
The root cause lies in how Astro's routing modules (such as BaseApp.removeBase, FetchState.#computePathname, and match-request.ts) stripped the configured base prefix from incoming request paths. To determine if an incoming request path fell under the configured base, the engine used a basic string comparison. Specifically, it checked if the requested pathname started with the base string via the JavaScript .startsWith() function.
When a base of '/app' was configured, a request for '/appX/admin' (where 'X' represents an arbitrary trailing character) successfully matched the .startsWith('/app') condition. Upon evaluating this condition as true, the router stripped the base path. It achieved this by calculating the length of the base path plus one character (to account for the expected slash delimiter) and slicing the original string from that index forward.
Applying this calculation to the path '/appX/admin' resulted in a slice operations of pathname.slice(5). This operation sliced off the prefix '/appX' and resolved the remaining path internally to '/admin'. Consequently, Astro treated the incoming request as a legitimate attempt to access the internal '/admin' route, completely ignoring the boundary mismatch of the '/appX' segment.
The security impact of this vulnerability manifests because of how request objects are processed by middleware versus how they are matched by the internal router. Security middleware generally acts as an interceptor. It evaluates the raw, unmodified URL of the request as exposed by context.url.pathname to determine whether the client is authorized to access the requested resource.
When an attacker sends a request to '/appX/admin', the middleware inspects context.url.pathname and detects '/appX/admin'. Because this pathname does not match the protected pattern of '/app/admin' or start with '/app/admin/', the middleware permits the request to pass. The middleware acts under the assumption that the path refers to an unprivileged route.
However, once the middleware passes execution to the core framework, the router processes the URL using the flawed prefix-stripping routine. The path '/appX/admin' is stripped down to '/admin', which matches the internal protected page component. The core routing engine then renders the protected page and returns it to the client, successfully bypassing the access control boundary. This interaction is illustrated in the following diagram:
Exploiting this vulnerability requires specific application conditions. First, the application must be configured with a non-root base path, such as /app. Second, the application must implement middleware that enforces access control on routes by performing prefix or equality checks against context.url.pathname. Finally, the application must host protected routes under that same base path.
To initiate the exploit, an attacker crafts an HTTP request where the base path is concatenated with an arbitrary suffix character, immediately followed by the target route segment. For example, if the application base is /app and the target is /app/admin, the attacker sends a request to /app-admin or /appX/admin over the network.
Because the string /appX/admin begins with the prefix /app, Astro's router strips the prefix and resolves the request to the administrative controller. The authorization middleware, examining the full pathname, fails to detect that the request is targeting a restricted route because it does not match the expected pattern. This allows unauthenticated users to perform privileged administrative actions.
To resolve this vulnerability, Astro's engineering team consolidated the path parsing logic into a robust helper function called stripRequestBase inside packages/internal-helpers/src/path.ts. This helper function completely eliminates naive prefix checking by enforcing strict path-segment boundary validation.
export function stripRequestBase(pathname: string, base: string): string {
// 1. Collapse duplicate leading slashes to prevent multi-slash bypasses
pathname = collapseDuplicateLeadingSlashes(pathname);
const baseWithoutTrailingSlash = removeTrailingForwardSlash(base);
// 2. Perform exact match check
if (pathname === baseWithoutTrailingSlash) {
return '/';
}
// 3. Enforce path-segment boundary by appending a slash separator
if (pathname.startsWith(baseWithoutTrailingSlash + '/')) {
return pathname.slice(baseWithoutTrailingSlash.length);
}
// 4. Return unmodified path if segment boundary is not met
return pathname;
}By verifying that the base path is followed immediately by a slash character (baseWithoutTrailingSlash + '/'), the patched code ensures that arbitrary suffixes like /appX do not trigger the slicing logic. Under the new implementation, a request to /appX/admin will fail the boundary check. The framework will return the unmodified path /appX/admin, leading to a safe 404 Not Found response instead of exposing the protected endpoint.
The vulnerability poses a moderate-to-high risk depending on the sensitivity of the protected routes hosted within the Astro application. Because exploiting the vulnerability requires no special privileges or user interaction, an unauthenticated attacker can consistently bypass middleware checks to access confidential data or execute administrative functions if the underlying route handler does not perform secondary authentication.
The primary remediation strategy is upgrading the core Astro dependency to version 7.2.4 or higher. Developers can update their projects using standard package managers. Executing npm install astro@7.2.4 or the equivalent command for your package manager will apply the path parsing fixes across all internal dependencies.
If immediate patching is not possible, developers can implement a temporary mitigation directly in their application's middleware. The middleware must manually validate that any incoming request pathname that starts with the base path also respects the path-segment boundary. Any path matching the prefix but failing the slash boundary check should be rejected immediately with an HTTP 400 Bad Request or 404 Not Found response.
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
astro withastro | < 7.2.4 | 7.2.4 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-187 (Partial String Comparison) |
| Attack Vector | Network (AV:N) |
| CVSS Score | 6.3 (Medium) |
| EPSS Score | 0.00407 (Percentile: 33.98%) |
| Impact | Authorization Bypass |
| Exploit Status | PoC available (Unit test validation) |
| KEV Status | Not Listed in CISA KEV |
The software performs a string comparison associated with a security decision, but it does not compare the entire string or enforce a boundary check, allowing a partial match to succeed.
A critical remote code execution vulnerability exists in the Composer PHP dependency manager due to improper neutralization of command parameters passed to the Perforce CLI client. Unauthenticated attackers can exploit this flaw via crafted package metadata in custom repositories or lock files, triggering arbitrary OS command execution when a user or automated CI/CD pipeline runs Composer commands.
A critical remote code execution vulnerability in Astro's image optimization pipeline allows unauthenticated attackers to trigger memory corruption via malformed AVIF images, due to outdated native dependencies in the sharp package.
A high-severity namespace injection vulnerability in both the MongoDB Client Library for PHP (mongodb/mongodb) and the native PHP C Extension (ext-mongodb) allows unauthenticated remote attackers to bypass logical database separation and execute database commands inside unauthorized storage compartments via dot (".") and null byte ("\0") injection.
A critical vulnerability (CVE-2026-84452) in the Windows ML CLI (winml-cli) HTTP server component allows unauthenticated remote code execution via permissive CORS and lack of request validation.
An incomplete fix vulnerability (CVE-2026-15603) in the morgan HTTP request logger middleware for Node.js allows unauthenticated remote attackers to forge log entries. The flaw arises because the escaping mechanism does not neutralize Unicode line separator characters, enabling attackers to inject payloads that trick downstream log processors into splitting single log records into multiple logical entries.
A high-severity denial of service vulnerability in the Node.js middleware 'multer' allows unauthenticated remote attackers to exhaust CPU resources and freeze applications. By submitting small, specially crafted 'multipart/form-data' requests containing large array indices alongside conflicting parameter keys, attackers force synchronous execution loops over up to 4.2 billion elements within the underlying 'append-field' library.