fix(route-rules): prevent open redirect via protocol-relative url byp… · nitrojs/nitro@bc1dd9d · GitHub
Skip to content

Commit bc1dd9d

Browse files
authored
fix(route-rules): prevent open redirect via protocol-relative url bypass (#4236)
1 parent 6edbf84 commit bc1dd9d

7 files changed

Lines changed: 41 additions & 9 deletions

File tree

‎package.json‎

Lines changed: 1 addition & 1 deletion

‎pnpm-lock.yaml‎

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/runtime/internal/route-rules.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ export const redirect: RouteRuleCtor<"redirect"> = ((m) =>
3333
throw new HTTPError({ status: 400 });
3434
}
3535
targetPath = withoutBase(targetPath, strpBase);
36+
} else if (targetPath.startsWith("//")) {
37+
targetPath = targetPath.replace(/^\/+/, "/");
3638
}
3739
target = joinURL(target.slice(0, -3), targetPath);
3840
} else if (event.url.search) {
@@ -56,6 +58,8 @@ export const proxy: RouteRuleCtor<"proxy"> = ((m) =>
5658
throw new HTTPError({ status: 400 });
5759
}
5860
targetPath = withoutBase(targetPath, strpBase);
61+
} else if (targetPath.startsWith("//")) {
62+
targetPath = targetPath.replace(/^\/+/, "/");
5963
}
6064
target = joinURL(target.slice(0, -3), targetPath);
6165
} else if (event.url.search) {

‎test/fixture/nitro.config.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,15 @@ export default defineConfig({
111111
redirect: { to: "https://nitro.build/", status: 308 },
112112
},
113113
"/rules/redirect/wildcard/**": { redirect: "https://nitro.build/**" },
114+
"/rules/redirect/legacy/**": { redirect: "/**" },
114115
"/rules/nested/**": { redirect: "/base", headers: { "x-test": "test" } },
115116
"/rules/nested/override": { redirect: { to: "/other" } },
116117
"/rules/_/noncached/cached": { swr: true },
117118
"/rules/_/noncached/**": { swr: false, cache: false, isr: false },
118119
"/rules/_/cached/noncached": { cache: false, swr: false, isr: false },
119120
"/rules/_/cached/**": { swr: true },
120121
"/api/proxy/**": { proxy: "/api/echo" },
122+
"/rules/proxy/legacy/**": { proxy: "/api/wildcard/**" },
121123
"/cdn/**": { proxy: "https://cdn.jsdelivr.net/**" },
122124
"/rules/basic-auth/**": {
123125
basicAuth: { username: "admin", password: "secret", realm: "Secure Area" },

‎test/presets/netlify.test.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ describe("nitro:preset:netlify", async () => {
4242

4343
expect(redirects).toMatchInlineSnapshot(`
4444
"/rules/nested/override /other 302
45+
/rules/redirect/legacy/* /:splat 302
4546
/rules/redirect/wildcard/* https://nitro.build/:splat 302
4647
/rules/redirect/obj https://nitro.build/ 301
4748
/rules/ba-redirect/* /base 302

‎test/presets/vercel.test.ts‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,13 @@ describe("nitro:preset:vercel:web", async () => {
8181
"src": "/rules/redirect/wildcard/(.*)",
8282
"status": 307,
8383
},
84+
{
85+
"headers": {
86+
"Location": "/$1",
87+
},
88+
"src": "/rules/redirect/legacy/(.*)",
89+
"status": 307,
90+
},
8491
{
8592
"headers": {
8693
"Location": "/other",

‎test/tests.ts‎

Lines changed: 18 additions & 0 deletions

0 commit comments

Comments
 (0)