fix: Security vulnerability - block malicious file requests
All checks were successful
Production Deployment (Zero Downtime) / deploy-production (push) Successful in 14m30s

This commit is contained in:
2026-02-09 16:02:10 +01:00
parent 3f31d6f5bb
commit b754af20e6
3 changed files with 70 additions and 1 deletions

View File

@@ -4,6 +4,29 @@ import type { NextRequest } from "next/server";
const SUPPORTED_LOCALES = ["en", "de"] as const;
type SupportedLocale = (typeof SUPPORTED_LOCALES)[number];
// Security: Block common malicious file patterns
const BLOCKED_PATTERNS = [
/\.php$/i,
/\.asp$/i,
/\.aspx$/i,
/\.jsp$/i,
/\.cgi$/i,
/\.env$/i,
/\.sql$/i,
/\.gz$/i,
/\.tar$/i,
/\.zip$/i,
/\.rar$/i,
/\.bash_history$/i,
/ftpsync\.settings$/i,
/__MACOSX/i,
/\.well-known\.zip$/i,
];
function isBlockedPath(pathname: string): boolean {
return BLOCKED_PATTERNS.some((pattern) => pattern.test(pathname));
}
function pickLocaleFromHeader(acceptLanguage: string | null): SupportedLocale {
if (!acceptLanguage) return "en";
const lower = acceptLanguage.toLowerCase();
@@ -20,6 +43,11 @@ function hasLocalePrefix(pathname: string): boolean {
export function middleware(request: NextRequest) {
const { pathname, search } = request.nextUrl;
// Security: Block malicious/suspicious requests immediately
if (isBlockedPath(pathname)) {
return new NextResponse(null, { status: 404 });
}
// If a locale-prefixed request hits a public asset path (e.g. /de/images/me.jpg),
// redirect to the non-prefixed asset path.
if (hasLocalePrefix(pathname)) {