diff options
author | 2021-09-22 16:19:16 -0700 | |
---|---|---|
committer | 2021-09-22 16:19:16 -0700 | |
commit | e00c1e99d67ff6224dcfb783c84ced9896537cb0 (patch) | |
tree | 1a21c91ea69ec5a49c21ec82b5854d5bde4e7f14 /src | |
parent | 39323b46ba9516c6c15df05eae3fe8afa5800958 (diff) | |
download | bun-e00c1e99d67ff6224dcfb783c84ced9896537cb0.tar.gz bun-e00c1e99d67ff6224dcfb783c84ced9896537cb0.tar.zst bun-e00c1e99d67ff6224dcfb783c84ced9896537cb0.zip |
Allow URLs containing absolute filepaths in imports if they match specific file extensions
This is to support ../../ imports
Allowlisting to specific file extensions prevents common webserver security vulnerabilities like reading /etc/passwd
Diffstat (limited to 'src')
-rw-r--r-- | src/http.zig | 41 | ||||
-rw-r--r-- | src/linker.zig | 1 | ||||
-rw-r--r-- | src/options.zig | 9 |
3 files changed, 46 insertions, 5 deletions
diff --git a/src/http.zig b/src/http.zig index 4e0d50e1f..29f58b186 100644 --- a/src/http.zig +++ b/src/http.zig @@ -273,10 +273,8 @@ pub const RequestContext = struct { defer this.done(); try this.writeStatus(500); const route_name = if (route_index > -1) this.matched_route.?.name else this.url.pathname; - Output.prettyErrorln("<r><red>500<r> - <b>{s}<r> rendering <b>/{s}<r>", .{ - @errorName(err), - route_name, - }); + if (comptime fmt.len > 0) Output.prettyErrorln(fmt, args); + Output.flush(); this.appendHeader("Content-Type", MimeType.html.value); var bb = std.ArrayList(u8).init(allocator); defer bb.deinit(); @@ -2250,6 +2248,37 @@ pub const RequestContext = struct { } } + fn handleAbsURL(ctx: *RequestContext, server: *Server) !void { + const extname = ctx.url.extname; + switch (extname.len) { + 3 => { + if (!(strings.eqlComptime(extname, "css") or strings.eqlComptime(extname, "tsx") or strings.eqlComptime(extname, "jsx") or strings.eqlComptime(extname, "mjs"))) return try ctx.sendNotFound(); + }, + 2 => { + if (!(strings.eqlComptime(extname, "js") or strings.eqlComptime(extname, "ts"))) return try ctx.sendNotFound(); + }, + 4 => { + if (!(strings.eqlComptime(extname, "json") or strings.eqlComptime(extname, "yaml"))) return try ctx.sendNotFound(); + }, + else => { + return try ctx.sendNotFound(); + }, + } + + switch (ctx.method) { + .GET, .HEAD => { + const result = try ctx.buildFile( + ctx.url.path["abs:".len..], + ctx.url.extname, + ); + try @call(.{ .modifier = .always_inline }, RequestContext.renderServeResult, .{ ctx, result }); + }, + else => { + try ctx.sendNotFound(); + }, + } + } + pub fn handleReservedRoutes(ctx: *RequestContext, server: *Server) !bool { if (strings.eqlComptime(ctx.url.extname, "bun") and ctx.bundler.options.node_modules_bundle != null) { try ctx.sendJSB(); @@ -2262,12 +2291,16 @@ pub const RequestContext = struct { } const isMaybePrefix = ctx.url.path.len > "bun:".len; + if (isMaybePrefix and strings.eqlComptimeIgnoreLen(ctx.url.path[0.."bun:".len], "bun:")) { try ctx.handleBunURL(server); return true; } else if (isMaybePrefix and strings.eqlComptimeIgnoreLen(ctx.url.path[0.."src:".len], "src:")) { try ctx.handleSrcURL(server); return true; + } else if (isMaybePrefix and strings.eqlComptimeIgnoreLen(ctx.url.path[0.."abs:".len], "abs:")) { + try ctx.handleAbsURL(server); + return true; } return false; diff --git a/src/linker.zig b/src/linker.zig index 182fe3b3c..8e0a8cb43 100644 --- a/src/linker.zig +++ b/src/linker.zig @@ -650,6 +650,7 @@ pub fn NewLinker(comptime BundlerType: type) type { dirname, basename, absolute_pathname.ext, + source_path, )); } }, diff --git a/src/options.zig b/src/options.zig index 937e6a5aa..83901403c 100644 --- a/src/options.zig +++ b/src/options.zig @@ -1104,7 +1104,14 @@ pub const BundleOptions = struct { opts.node_modules_bundle = node_module_bundle; if (opts.origin.isAbsolute()) { - opts.node_modules_bundle_url = try opts.origin.joinAlloc(allocator, "", "", node_module_bundle.bundle.import_from_name, ""); + opts.node_modules_bundle_url = try opts.origin.joinAlloc( + allocator, + "", + "", + node_module_bundle.bundle.import_from_name, + "", + "", + ); opts.node_modules_bundle_pretty_path = opts.node_modules_bundle_url[opts.node_modules_bundle_url.len - node_module_bundle.bundle.import_from_name.len - 1 ..]; } else { opts.node_modules_bundle_pretty_path = try allocator.dupe(u8, pretty_path); |