Listen to this Post
This vulnerability exploits the Astro framework’s improper handling of URL-encoded pathnames in middleware authentication logic. The original fix for CVE-2025-64765 addressed single URL encoding by decoding the request pathname once before comparing it against protected route patterns (e.g., /admin). However, this fix is insufficient. An attacker can bypass it by double-encoding characters in the path. For example, the lowercase letter ‘a’ has a UTF-8 hex code of 61. A single-encoded `%61` would be decoded to ‘a’ by the fixed middleware, triggering the protection. But a double-encoded payload first encodes the `%` sign itself (%25), resulting in %2561. The middleware’s single decode pass transforms `%2561` into %61, leaving the encoded `%61` string intact. The resulting pathname string still contains %61, which does not match the protected pattern /admin, allowing the request to pass through. The request is then processed by the routing layer, which performs its own standard decoding, turning `%61` into ‘a’, ultimately routing the attacker to the protected `/admin` endpoint. This creates an authentication bypass for any route protected by pathname checks in middleware.
Platform: Astro
Version: <5.15.8
Vulnerability : Auth Bypass
Severity: Critical
date: 2025
Prediction: Patch 2025-08-15
What Undercode Say:
curl http://victim.com/%2561dmin
// Example vulnerable check in middleware
export function onRequest({ url, redirect }, next) {
const pathname = decodeURIComponent(url.pathname); // Single decode only
if (pathname.startsWith('/admin')) {
return new Response('Unauthorized', { status: 401 });
}
return next();
}
How Exploit:
1. Identify a protected route (e.g., `/admin`).
- Double-encode a critical character: `a` -> `%61` ->
%2561.
3. Construct request to `/%2561dmin`.
- Middleware decodes once to
/%61dmin, fails to match/admin. - Server routes request, decodes `%61` to
a, accesses/admin.
Protection from this CVE
function containsEncodedComponents(s) {
return /%[0-9A-Fa-f]{2}/.test(s);
}
// After decoding once in middleware:
if (containsEncodedComponents(decodedPathname)) {
return new Response('Bad Request', {status: 400});
}
Update to Astro >=5.15.9.
Implement strict path normalization.
Reject requests with residual encoding.
Impact:
Unauthenticated access to protected admin panels, internal APIs, and sensitive routes leading to full application compromise.
🎯Let’s Practice Exploiting & Learn Patching For Free:
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

