summaryrefslogtreecommitdiff
path: root/std/http/file_server.ts
diff options
context:
space:
mode:
authorsarahdenofiletrav <74922000+sarahdenofiletrav@users.noreply.github.com>2020-11-26 21:31:19 +0000
committerGitHub <noreply@github.com>2020-11-26 22:31:19 +0100
commit28869a632d190dc29d78738bc5e90eadf99bc824 (patch)
tree85b749f6ffbaeada706a6b6d15b0f4ce2399d454 /std/http/file_server.ts
parent4f46dc999b9fd3f26b6586d06d099d7039ca35c8 (diff)
fix(std/http): prevent path traversal (#8474)
Fix path traversal problem when the request URI does not have a leading slash. The file server now returns HTTP 400 when requests lack the leading slash, and are not absolute URIs. (https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html).
Diffstat (limited to 'std/http/file_server.ts')
-rw-r--r--std/http/file_server.ts32
1 files changed, 27 insertions, 5 deletions
diff --git a/std/http/file_server.ts b/std/http/file_server.ts
index 331dbe5c5..c0d58351b 100644
--- a/std/http/file_server.ts
+++ b/std/http/file_server.ts
@@ -187,10 +187,15 @@ async function serveDir(
}
function serveFallback(req: ServerRequest, e: Error): Promise<Response> {
- if (e instanceof Deno.errors.NotFound) {
+ if (e instanceof URIError) {
+ return Promise.resolve({
+ status: 400,
+ body: encoder.encode("Bad Request"),
+ });
+ } else if (e instanceof Deno.errors.NotFound) {
return Promise.resolve({
status: 404,
- body: encoder.encode("Not found"),
+ body: encoder.encode("Not Found"),
});
} else {
return Promise.resolve({
@@ -335,6 +340,21 @@ function normalizeURL(url: string): string {
throw e;
}
}
+
+ try {
+ //allowed per https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html
+ const absoluteURI = new URL(normalizedUrl);
+ normalizedUrl = absoluteURI.pathname;
+ } catch (e) { //wasn't an absoluteURI
+ if (!(e instanceof TypeError)) {
+ throw e;
+ }
+ }
+
+ if (normalizedUrl[0] !== "/") {
+ throw new URIError("The request URI is malformed.");
+ }
+
normalizedUrl = posix.normalize(normalizedUrl);
const startOfParams = normalizedUrl.indexOf("?");
return startOfParams > -1
@@ -383,11 +403,13 @@ function main(): void {
}
const handler = async (req: ServerRequest): Promise<void> => {
- const normalizedUrl = normalizeURL(req.url);
- const fsPath = posix.join(target, normalizedUrl);
-
let response: Response | undefined;
try {
+ const normalizedUrl = normalizeURL(req.url);
+ let fsPath = posix.join(target, normalizedUrl);
+ if (fsPath.indexOf(target) !== 0) {
+ fsPath = target;
+ }
const fileInfo = await Deno.stat(fsPath);
if (fileInfo.isDirectory) {
if (dirListingEnabled) {