mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-09-15 07:19:20 -04:00
basic validation without preflighting
This commit is contained in:
2 files changed
+65
-3
No files matched your search
@@ -26,6 +26,7 @@ const http = @import("http.zig");
|
||||
const Network = @import("Network.zig");
|
||||
const Transfer = @import("HttpClient.zig").Transfer;
|
||||
const SingleFlight = @import("SingleFlight.zig");
|
||||
const HttpClient = @import("HttpClient.zig");
|
||||
|
||||
const log = lp.log;
|
||||
const Allocator = std.mem.Allocator;
|
||||
@@ -103,7 +104,6 @@ fn requiresPreflight(transfer: *const Transfer) bool {
|
||||
const Result = enum { allowed, blocked, pending };
|
||||
|
||||
pub fn check(self: *CorsGate, transfer: *Transfer) !Result {
|
||||
_ = self;
|
||||
const req = &transfer.req;
|
||||
|
||||
if (req.origin) |origin| {
|
||||
@@ -113,8 +113,60 @@ pub fn check(self: *CorsGate, transfer: *Transfer) !Result {
|
||||
}
|
||||
}
|
||||
|
||||
log.debug(.cors, "cross origin", .{ .url = req.url, .origin = req.origin orelse "null" });
|
||||
transfer._cors_cross_origin = true;
|
||||
|
||||
if (!requiresPreflight(transfer)) {
|
||||
log.debug(.cors, "cross origin", .{
|
||||
.url = req.url,
|
||||
.origin = req.origin orelse "null",
|
||||
.preflight = false,
|
||||
});
|
||||
return .allowed;
|
||||
}
|
||||
|
||||
log.debug(.cors, "cross origin", .{
|
||||
.url = req.url,
|
||||
.origin = req.origin orelse "null",
|
||||
.preflight = true,
|
||||
});
|
||||
|
||||
_ = self;
|
||||
return .blocked;
|
||||
|
||||
// try self.fetchThenResumse(transfer);
|
||||
// return .pendind;
|
||||
}
|
||||
|
||||
pub fn validateResponse(transfer: *Transfer) !void {
|
||||
const req = &transfer.req;
|
||||
const allow_origin = HttpClient.findHeader(transfer.res.headers, "access-control-allow-origin");
|
||||
|
||||
if (allow_origin == null) {
|
||||
log.warn(.cors, "blocked", .{ .url = req.url, .reason = "missing acao" });
|
||||
return error.CorsBlocked;
|
||||
}
|
||||
|
||||
const wants_credentials = req.credentials != null or transfer.findRequestHeader("Cookie") != null;
|
||||
|
||||
if (!std.mem.eql(u8, allow_origin.?, "*")) {
|
||||
const origin = req.origin orelse {
|
||||
log.warn(.cors, "blocked", .{ .url = req.url, .reason = "opaque origin" });
|
||||
return error.CorsBlocked;
|
||||
};
|
||||
if (!std.mem.eql(u8, allow_origin.?, origin)) {
|
||||
log.warn(.cors, "blocked", .{ .url = req.url, .reason = "origin mismatch", .allow_origin = allow_origin.?, .origin = origin });
|
||||
return error.CorsBlocked;
|
||||
}
|
||||
} else if (wants_credentials) {
|
||||
log.warn(.cors, "blocked", .{ .url = req.url, .reason = "wildcard with credentials" });
|
||||
return error.CorsBlocked;
|
||||
}
|
||||
|
||||
if (wants_credentials) {
|
||||
const allow_creds = HttpClient.findHeader(transfer.res.headers, "access-control-allow-credentials");
|
||||
if (allow_creds == null or !std.mem.eql(u8, allow_creds.?, "true")) {
|
||||
log.warn(.cors, "blocked", .{ .url = req.url, .reason = "credentials not allowed" });
|
||||
return error.CorsBlocked;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1085,7 +1085,7 @@ pub fn resumeAfterCors(self: *Client, transfer: *Transfer) !void {
|
||||
return self.pipeline(transfer, .after_cors);
|
||||
}
|
||||
|
||||
fn findHeader(headers: []const http.Header, name: []const u8) ?[]const u8 {
|
||||
pub fn findHeader(headers: []const http.Header, name: []const u8) ?[]const u8 {
|
||||
for (headers) |hdr| {
|
||||
if (std.ascii.eqlIgnoreCase(hdr.name, name)) {
|
||||
return hdr.value;
|
||||
@@ -1690,6 +1690,16 @@ fn processOneMessage(self: *Client, msg: http.Handles.MultiMessage, transfer: *T
|
||||
|
||||
try transfer.materializeResponse(msg.conn, .{});
|
||||
|
||||
// Validate the headers for the response with CORS.
|
||||
if (transfer._cors_cross_origin) {
|
||||
CorsGate.validateResponse(transfer) catch |err| {
|
||||
self.removeConn(msg.conn);
|
||||
transfer._conn = null;
|
||||
transfer.failAsync(err);
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
// Latency is only meaningful for responses that hit the network (cache
|
||||
// and synthetic responses never reach processOneMessage).
|
||||
if (!transfer.req.internal) {
|
||||
|
||||
Reference in new issue
Block a user