Skip to content

Commit

Permalink
Merge commit from fork
Browse files Browse the repository at this point in the history
* fix(http): disable XSS using file name

* reduce deps

* update
  • Loading branch information
kt3k authored Nov 22, 2024
1 parent a73ff94 commit a334956
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
5 changes: 3 additions & 2 deletions http/file_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import { parseArgs } from "@std/cli/parse-args";
import denoConfig from "./deno.json" with { type: "json" };
import { format as formatBytes } from "@std/fmt/bytes";
import { getNetworkAddress } from "@std/net/unstable-get-network-address";
import { escape } from "@std/html/entities";
import { HEADER } from "./unstable_header.ts";
import { METHOD } from "./unstable_method.ts";

Expand Down Expand Up @@ -504,7 +505,7 @@ function dirViewerTemplate(dirname: string, entries: EntryInfo[]): string {
.map((path, index, array) => {
if (path === "") return "";
const link = array.slice(0, index + 1).join("/");
return `<a href="${link}">${path}</a>`;
return `<a href="${escape(link)}">${escape(path)}</a>`;
})
.join("/")
}
Expand All @@ -529,7 +530,7 @@ function dirViewerTemplate(dirname: string, entries: EntryInfo[]): string {
${entry.size}
</td>
<td>
<a href="${entry.url}">${entry.name}</a>
<a href="${escape(entry.url)}">${escape(entry.name)}</a>
</td>
</tr>
`,
Expand Down
16 changes: 16 additions & 0 deletions http/file_server_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,22 @@ Deno.test("serveDir() serves directory index with file's mode is 0", async () =>
assertMatch(page, /<td class="mode">(\s)*- --- --- ---(\s)*<\/td>/);
});

Deno.test("serveDir() escapes file names when rendering directory index", {
ignore: Deno.build.os === "windows",
}, async () => {
const dir = await Deno.makeTempDir();
const filePath = join(dir, "<img src=x onerror=alert(1)>");
await Deno.writeTextFile(filePath, "abc");
const res = await serveDir(new Request("http://localhost/"), {
...serveDirOptions,
fsRoot: dir,
});
assertStringIncludes(
await res.text(),
'<a href="/%3Cimg%20src%3Dx%20onerror%3Dalert(1)%3E">&lt;img src=x onerror=alert(1)&gt;</a>',
);
});

Deno.test("serveDir() returns a response even if fileinfo is inaccessible", async () => {
// Note: Deno.stat for windows system files may be rejected with os error 32.
// Mock Deno.stat to test that the dirlisting page can be generated
Expand Down

0 comments on commit a334956

Please sign in to comment.