Serenity Operating System
at master 58 lines 2.4 kB view raw
1/* 2 * Copyright (c) 2022-2023, Linus Groh <linusg@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <LibWeb/Fetch/Infrastructure/HTTP/Headers.h> 8#include <LibWeb/Fetch/Infrastructure/HTTP/Requests.h> 9#include <LibWeb/Fetch/Infrastructure/HTTP/Responses.h> 10#include <LibWeb/Fetch/Infrastructure/NoSniffBlocking.h> 11#include <LibWeb/Infra/Strings.h> 12 13namespace Web::Fetch::Infrastructure { 14 15// https://fetch.spec.whatwg.org/#determine-nosniff 16ErrorOr<bool> determine_nosniff(HeaderList const& list) 17{ 18 // 1. Let values be the result of getting, decoding, and splitting `X-Content-Type-Options` from list. 19 auto values = TRY(list.get_decode_and_split("X-Content-Type-Options"sv.bytes())); 20 21 // 2. If values is null, then return false. 22 if (!values.has_value()) 23 return false; 24 25 // 3. If values[0] is an ASCII case-insensitive match for "nosniff", then return true. 26 if (!values->is_empty() && Infra::is_ascii_case_insensitive_match(values->at(0), "nosniff"sv)) 27 return true; 28 29 // 4. Return false. 30 return false; 31} 32 33// https://fetch.spec.whatwg.org/#should-response-to-request-be-blocked-due-to-nosniff? 34ErrorOr<RequestOrResponseBlocking> should_response_to_request_be_blocked_due_to_nosniff(Response const& response, Request const& request) 35{ 36 // 1. If determine nosniff with response’s header list is false, then return allowed. 37 if (!TRY(determine_nosniff(response.header_list()))) 38 return RequestOrResponseBlocking::Allowed; 39 40 // 2. Let mimeType be the result of extracting a MIME type from response’s header list. 41 auto mime_type = TRY(response.header_list()->extract_mime_type()); 42 43 // 3. Let destination be request’s destination. 44 auto const& destination = request.destination(); 45 46 // 4. If destination is script-like and mimeType is failure or is not a JavaScript MIME type, then return blocked. 47 if (request.destination_is_script_like() && (!mime_type.has_value() || !mime_type->is_javascript())) 48 return RequestOrResponseBlocking::Blocked; 49 50 // 5. If destination is "style" and mimeType is failure or its essence is not "text/css", then return blocked. 51 if (destination == Request::Destination::Style && (!mime_type.has_value() || mime_type->essence() != "text/css"sv)) 52 return RequestOrResponseBlocking::Blocked; 53 54 // 6. Return allowed. 55 return RequestOrResponseBlocking::Allowed; 56} 57 58}