Filter out malicious request (#3357)

Co-authored-by: Nicolas Dorseuil <nicolas@gitbook.io>
This commit is contained in:
conico974
2025-06-19 17:00:37 +02:00
committed by GitHub
parent a7a713bca2
commit 81f5bfc2f9
+33
View File
@@ -43,6 +43,12 @@ export async function middleware(request: NextRequest) {
return NextResponse.redirect(normalized.toString());
}
// Reject malicious requests
const rejectResponse = await validateServerActionRequest(request);
if (rejectResponse) {
return rejectResponse;
}
for (const handler of [serveSiteRoutes, serveSpacePDFRoutes]) {
const result = await handler(requestURL, request);
if (result) {
@@ -56,6 +62,25 @@ export async function middleware(request: NextRequest) {
}
}
async function validateServerActionRequest(request: NextRequest) {
// We need to reject incorrect server actions requests
// We do not do it in cloudflare workers as there is a bug that prevents us from reading the request body.
if (request.headers.has('next-action') && process.env.GITBOOK_RUNTIME !== 'cloudflare') {
// We just test that the json body is parseable
try {
const clonedRequest = request.clone();
await clonedRequest.json();
} catch (e) {
console.warn('Invalid server action request', e);
// If the body is not parseable, we reject the request
return new Response('Invalid request', {
status: 400,
headers: { 'content-type': 'text/plain' },
});
}
}
}
/**
* Handle request that are targetting the site routes group.
*/
@@ -82,6 +107,14 @@ async function serveSiteRoutes(requestURL: URL, request: NextRequest) {
});
}
// We want to filter hostnames that contains a port here as this is likely a malicious request.
if (siteRequestURL.host.includes(':')) {
return new Response('Invalid request', {
status: 400,
headers: { 'content-type': 'text/plain' },
});
}
//
// Detect and extract the visitor authentication token from the request
//