Skip to content

Commit

Permalink
Prevent wrangler pages dev from serving asset files outside of the …
Browse files Browse the repository at this point in the history
…build output directory (#3820)
  • Loading branch information
GregBrimble authored Aug 25, 2023
1 parent 6844595 commit 546c231
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/fuzzy-flowers-kneel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wrangler": patch
---

fix: Prevent `wrangler pages dev` from serving asset files outside of the build output directory
12 changes: 12 additions & 0 deletions fixtures/pages-simple-assets/tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ describe.concurrent("Pages Functions", () => {
expect(text).toContain("Hello, world!");
});

it("doesn't escape out of the build output directory", async ({ expect }) => {
let response = await fetch(`http://${ip}:${port}/..%2fpackage.json`);
let text = await response.text();
expect(text).toContain("Hello, world!");

response = await fetch(
`http://${ip}:${port}/other-path%2f..%2f..%2fpackage.json`
);
text = await response.text();
expect(text).toContain("Hello, world!");
});

it("doesn't redirect to protocol-less URLs", async ({ expect }) => {
{
const response = await fetch(
Expand Down
8 changes: 6 additions & 2 deletions packages/wrangler/src/miniflare-cli/assets.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { existsSync, lstatSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { join, resolve } from "node:path";
import { createMetadataObject } from "@cloudflare/pages-shared/metadata-generator/createMetadataObject";
import { parseHeaders } from "@cloudflare/pages-shared/metadata-generator/parseHeaders";
import { parseRedirects } from "@cloudflare/pages-shared/metadata-generator/parseRedirects";
Expand Down Expand Up @@ -89,6 +89,7 @@ async function generateAssetsFetch(
log: Logger,
tre: boolean
): Promise<typeof fetch> {
directory = resolve(directory);
// Defer importing miniflare until we really need it

// NOTE: These dynamic imports bring in `global` type augmentations from
Expand Down Expand Up @@ -174,7 +175,10 @@ async function generateAssetsFetch(
xServerEnvHeader: "dev",
logError: console.error,
findAssetEntryForPath: async (path) => {
const filepath = join(directory, path);
const filepath = resolve(join(directory, path));
if (!filepath.startsWith(directory)) {
return null;
}

if (
existsSync(filepath) &&
Expand Down

0 comments on commit 546c231

Please sign in to comment.