diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index 7c88f4e7620dec..b0b71b119cf6bd 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -1017,6 +1017,14 @@ export default abstract class Server< req.headers['x-forwarded-proto'] ??= isHttps ? 'https' : 'http' req.headers['x-forwarded-for'] ??= originalRequest?.socket?.remoteAddress + // Validate that if i18n isn't configured or the passed parameters are not + // valid it should be removed from the query. + if (!this.i18nProvider?.validateQuery(parsedUrl.query)) { + delete parsedUrl.query.__nextLocale + delete parsedUrl.query.__nextDefaultLocale + delete parsedUrl.query.__nextInferredLocaleFromDefault + } + // This should be done before any normalization of the pathname happens as // it captures the initial URL. this.attachRequestMeta(req, parsedUrl) diff --git a/packages/next/src/server/lib/i18n-provider.ts b/packages/next/src/server/lib/i18n-provider.ts index efdbe4ac12dd4c..0a1e7c75031677 100644 --- a/packages/next/src/server/lib/i18n-provider.ts +++ b/packages/next/src/server/lib/i18n-provider.ts @@ -134,6 +134,37 @@ export class I18NProvider { } } + /** + * Validates that the locale is valid. + * + * @param locale The locale to validate. + * @returns `true` if the locale is valid, `false` otherwise. + */ + private validate(locale: string): boolean { + return this.lowerCaseLocales.includes(locale.toLowerCase()) + } + + /** + * Validates that the locales in the query object are valid. + * + * @param query The query object to validate. + * @returns `true` if the locale is valid, `false` otherwise. + */ + public validateQuery(query: NextParsedUrlQuery) { + if (query.__nextLocale && !this.validate(query.__nextLocale)) { + return false + } + + if ( + query.__nextDefaultLocale && + !this.validate(query.__nextDefaultLocale) + ) { + return false + } + + return true + } + /** * Analyzes the pathname for a locale and returns the pathname without it. * diff --git a/packages/next/src/server/lib/router-utils/resolve-routes.ts b/packages/next/src/server/lib/router-utils/resolve-routes.ts index f12a3d2bc3c1e6..95ed26105a0be7 100644 --- a/packages/next/src/server/lib/router-utils/resolve-routes.ts +++ b/packages/next/src/server/lib/router-utils/resolve-routes.ts @@ -218,6 +218,11 @@ export function getResolveRoutes( parsedUrl.pathname = maybeAddTrailingSlash(parsedUrl.pathname) } } + } else { + // As i18n isn't configured we remove the locale related query params. + delete parsedUrl.query.__nextLocale + delete parsedUrl.query.__nextDefaultLocale + delete parsedUrl.query.__nextInferredLocaleFromDefault } const checkLocaleApi = (pathname: string) => {