From 89df63e95682dc302c26c593e164c8d705a31e2a Mon Sep 17 00:00:00 2001 From: Muki Kiboigo Date: Tue, 25 Aug 2026 15:57:19 -0700 Subject: [PATCH] safelisted methods always pass in CORS --- src/network/CorsGate.zig | 42 ++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/src/network/CorsGate.zig b/src/network/CorsGate.zig index e40204f82..d7a6da9fb 100644 --- a/src/network/CorsGate.zig +++ b/src/network/CorsGate.zig @@ -73,6 +73,13 @@ fn flushPending(self: *CorsGate, key: []const u8, allowed: bool) void { } } +fn isSafelistedMethod(value: http.Method) bool { + return switch (value) { + .GET, .HEAD, .POST => true, + else => false, + }; +} + fn isSafelistedContentType(value: []const u8) bool { const semi = std.mem.indexOfScalar(u8, value, ';') orelse value.len; const mime = std.mem.trim(u8, value[0..semi], &std.ascii.whitespace); @@ -97,9 +104,8 @@ fn isSafelistedHeader(name: []const u8, value: []const u8) bool { fn requiresPreflight(transfer: *const Transfer) bool { const req = &transfer.req; - switch (req.method) { - .GET, .HEAD, .POST => {}, - else => return true, + if (!isSafelistedMethod(req.method)) { + return true; } for (transfer.req_headers.items) |hdr| { @@ -211,21 +217,23 @@ const CorsPreflightContext = struct { } } - // Access-Control-Allow-Methods - const allow_methods = acam orelse { - log.debug(.cors, "preflight blocked", .{ .url = self.url, .reason = "missing acam" }); - return false; - }; + if (!isSafelistedMethod(self.method)) { + // Access-Control-Allow-Methods + const allow_methods = acam orelse { + log.debug(.cors, "preflight blocked", .{ .url = self.url, .reason = "missing acam" }); + return false; + }; - const methods_wildcard = std.mem.eql(u8, allow_methods, "*") and !self.wants_credentials; - if (!methods_wildcard and !methodAllowed(allow_methods, self.method)) { - log.debug(.cors, "preflight blocked", .{ - .url = self.url, - .reason = "method not allowed", - .allow_methods = allow_methods, - .method = @tagName(self.method), - }); - return false; + const methods_wildcard = std.mem.eql(u8, allow_methods, "*") and !self.wants_credentials; + if (!methods_wildcard and !methodAllowed(allow_methods, self.method)) { + log.debug(.cors, "preflight blocked", .{ + .url = self.url, + .reason = "method not allowed", + .allow_methods = allow_methods, + .method = @tagName(self.method), + }); + return false; + } } // Access-Control-Allow-Headers