Логотип exploitDog
Консоль
Логотип exploitDog

exploitDog

github логотип

GHSA-ggxq-hp9w-j794

Опубликовано: 19 нояб. 2025
Источник: github
Github: Прошло ревью
CVSS4: 6.9

Описание

Astro's middleware authentication checks based on url.pathname can be bypassed via url encoded values

A mismatch exists between how Astro normalizes request paths for routing/rendering and how the application’s middleware reads the path for validation checks. Astro internally applies decodeURI() to determine which route to render, while the middleware uses context.url.pathname without applying the same normalization (decodeURI).

This discrepancy may allow attackers to reach protected routes (e.g., /admin) using encoded path variants that pass routing but bypass validation checks.

https://github.com/withastro/astro/blob/ebc4b1cde82c76076d5d673b5b70f94be2c066f3/packages/astro/src/vite-plugin-astro-server/request.ts#L40-L44

/** The main logic to route dev server requests to pages in Astro. */ export async function handleRequest({ pipeline, routesList, controller, incomingRequest, incomingResponse, }: HandleRequest) { const { config, loader } = pipeline; const origin = `${loader.isHttps() ? 'https' : 'http'}://${ incomingRequest.headers[':authority'] ?? incomingRequest.headers.host }`; const url = new URL(origin + incomingRequest.url); let pathname: string; if (config.trailingSlash === 'never' && !incomingRequest.url) { pathname = ''; } else { // We already have a middleware that checks if there's an incoming URL that has invalid URI, so it's safe // to not handle the error: packages/astro/src/vite-plugin-astro-server/base.ts pathname = decodeURI(url.pathname); // here this url is for routing/rendering } // Add config.base back to url before passing it to SSR url.pathname = removeTrailingForwardSlash(config.base) + url.pathname; // this is used for middleware context

Consider an application having the following middleware code:

import { defineMiddleware } from "astro/middleware"; export const onRequest = defineMiddleware(async (context, next) => { const isAuthed = false; // simulate no auth if (context.url.pathname === "/admin" && !isAuthed) { return context.redirect("/"); } return next(); });

context.url.pathname is validated , if it's equal to /admin the isAuthed property must be true for the next() method to be called. The same example can be found in the official docs https://docs.astro.build/en/guides/authentication/

context.url.pathname returns the raw version which is /%61admin while pathname which is used for routing/rendering /admin, this creates a path normalization mismatch.

By sending the following request, it's possible to bypass the middleware check

GET /%61dmin HTTP/1.1 Host: localhost:3000
image

Remediation

Ensure middleware context has the same normalized pathname value that Astro uses internally, because any difference could allow it to bypass such checks. In short maybe something like this

pathname = decodeURI(url.pathname); } // Add config.base back to url before passing it to SSR - url.pathname = removeTrailingForwardSlash(config.base) + url.pathname; + url.pathname = removeTrailingForwardSlash(config.base) + decodeURI(url.pathname);

Thank you, let @Sudistark know if any more info is needed. Happy to help :)

Пакеты

Наименование

astro

npm
Затронутые версииВерсия исправления

< 5.15.8

5.15.8

EPSS

Процентиль: 6%
0.00024
Низкий

6.9 Medium

CVSS4

Дефекты

CWE-22

Связанные уязвимости

CVSS3: 5.3
nvd
3 месяца назад

Astro is a web framework. Prior to version 5.15.8, a mismatch exists between how Astro normalizes request paths for routing/rendering and how the application’s middleware reads the path for validation checks. Astro internally applies decodeURI() to determine which route to render, while the middleware uses context.url.pathname without applying the same normalization (decodeURI). This discrepancy may allow attackers to reach protected routes using encoded path variants that pass routing but bypass validation checks. This issue has been patched in version 5.15.8.

EPSS

Процентиль: 6%
0.00024
Низкий

6.9 Medium

CVSS4

Дефекты

CWE-22