Skip to content

Commit 0e06721

Browse files
committed
Remove multiple slashes from asset pathing
1 parent 6f09f23 commit 0e06721

File tree

3 files changed

+19
-9
lines changed

3 files changed

+19
-9
lines changed

.changeset/cyan-laws-mate.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@cloudflare/workers-shared": minor
3+
---
4+
5+
Prevent same-schema attacks

packages/workers-shared/asset-worker/src/handler.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ export const handleRequest = async (
1919
const { pathname, search } = new URL(request.url);
2020

2121
let decodedPathname = decodePath(pathname);
22-
// normalize the path
23-
decodedPathname = decodedPathname.replaceAll('//', '/');
22+
// normalize the path; remove multiple slashes which could lead to same-schema redirects
23+
decodedPathname = decodedPathname.replace(/\/+/g, "/");
2424

2525
const intent = await getIntent(decodedPathname, configuration, exists);
2626

@@ -45,8 +45,6 @@ export const handleRequest = async (
4545
* We combine this with other redirects (e.g. for html_handling) to avoid multiple redirects.
4646
*/
4747
if (encodedDestination !== pathname || intent.redirect) {
48-
console.log(encodedDestination, pathname);
49-
5048
return new TemporaryRedirectResponse(encodedDestination + search);
5149
}
5250

@@ -643,8 +641,6 @@ const safeRedirect = async (
643641
return null;
644642
}
645643

646-
console.log(file, destination, configuration);
647-
648644
if (!(await exists(destination))) {
649645
const intent = await getIntent(destination, configuration, exists, true);
650646
// return only if the eTag matches - i.e. not the 404 case

packages/workers-shared/asset-worker/tests/handler.test.ts

+12-3
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,8 @@ describe("[Asset Worker] `handleRequest`", () => {
115115
exists,
116116
getByETag
117117
);
118-
119118
expect(response.status).toBe(307);
120-
expect(response.headers.get('location')).toBe('/abc/def/123/456');
119+
expect(response.headers.get("location")).toBe("/abc/def/123/456");
121120

122121
response = await handleRequest(
123122
new Request("https://example.com/%2fexample.com/"),
@@ -127,6 +126,16 @@ describe("[Asset Worker] `handleRequest`", () => {
127126
);
128127

129128
expect(response.status).toBe(307);
130-
expect(response.headers.get('location')).toBe('/example.com/');
129+
expect(response.headers.get("location")).toBe("/example.com/");
130+
131+
response = await handleRequest(
132+
new Request("https://example.com/%2f%2f%2fexample.com/%2f/foo"),
133+
configuration,
134+
exists,
135+
getByETag
136+
);
137+
138+
expect(response.status).toBe(307);
139+
expect(response.headers.get("location")).toBe("/example.com/foo");
131140
});
132141
});

0 commit comments

Comments
 (0)