From 58ad6de9549a0f8cb18ae53eb5453ab0eadf68ab Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Sun, 23 Oct 2022 21:58:18 +0100 Subject: [PATCH] LibWeb: Implement 'Should response be blocked due to nosniff?' AO --- Userland/Libraries/LibWeb/CMakeLists.txt | 1 + .../Fetch/Infrastructure/NoSniffBlocking.cpp | 57 +++++++++++++++++++ .../Fetch/Infrastructure/NoSniffBlocking.h | 18 ++++++ 3 files changed, 76 insertions(+) create mode 100644 Userland/Libraries/LibWeb/Fetch/Infrastructure/NoSniffBlocking.cpp create mode 100644 Userland/Libraries/LibWeb/Fetch/Infrastructure/NoSniffBlocking.h diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 5c639e6559..5484657124 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -132,6 +132,7 @@ set(SOURCES Fetch/Infrastructure/HTTP/Responses.cpp Fetch/Infrastructure/HTTP/Statuses.cpp Fetch/Infrastructure/MimeTypeBlocking.cpp + Fetch/Infrastructure/NoSniffBlocking.cpp Fetch/Infrastructure/PortBlocking.cpp Fetch/Infrastructure/URL.cpp Fetch/Request.cpp diff --git a/Userland/Libraries/LibWeb/Fetch/Infrastructure/NoSniffBlocking.cpp b/Userland/Libraries/LibWeb/Fetch/Infrastructure/NoSniffBlocking.cpp new file mode 100644 index 0000000000..d40d4f759c --- /dev/null +++ b/Userland/Libraries/LibWeb/Fetch/Infrastructure/NoSniffBlocking.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022, Linus Groh + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +namespace Web::Fetch::Infrastructure { + +// https://fetch.spec.whatwg.org/#determine-nosniff +ErrorOr determine_nosniff(HeaderList const& list) +{ + // 1. Let values be the result of getting, decoding, and splitting `X-Content-Type-Options` from list. + auto values = TRY(list.get_decode_and_split("X-Content-Type-Options"sv.bytes())); + + // 2. If values is null, then return false. + if (!values.has_value()) + return false; + + // 3. If values[0] is an ASCII case-insensitive match for "nosniff", then return true. + if (!values->is_empty() && values->at(0).equals_ignoring_case("nosniff"sv)) + return true; + + // 4. Return false. + return false; +} + +// https://fetch.spec.whatwg.org/#should-response-to-request-be-blocked-due-to-nosniff? +ErrorOr should_response_to_request_be_blocked_due_to_nosniff(Response const& response, Request const& request) +{ + // 1. If determine nosniff with response’s header list is false, then return allowed. + if (!TRY(determine_nosniff(response.header_list()))) + return RequestOrResponseBlocking::Allowed; + + // 2. Let mimeType be the result of extracting a MIME type from response’s header list. + auto mime_type = response.header_list()->extract_mime_type(); + + // 3. Let destination be request’s destination. + auto const& destination = request.destination(); + + // 4. If destination is script-like and mimeType is failure or is not a JavaScript MIME type, then return blocked. + if (request.destination_is_script_like() && (!mime_type.has_value() || !mime_type->is_javascript())) + return RequestOrResponseBlocking::Blocked; + + // 5. If destination is "style" and mimeType is failure or its essence is not "text/css", then return blocked. + if (destination == Request::Destination::Style && (!mime_type.has_value() || mime_type->essence() != "text/css"sv)) + return RequestOrResponseBlocking::Blocked; + + // 6. Return allowed. + return RequestOrResponseBlocking::Allowed; +} + +} diff --git a/Userland/Libraries/LibWeb/Fetch/Infrastructure/NoSniffBlocking.h b/Userland/Libraries/LibWeb/Fetch/Infrastructure/NoSniffBlocking.h new file mode 100644 index 0000000000..5929373b16 --- /dev/null +++ b/Userland/Libraries/LibWeb/Fetch/Infrastructure/NoSniffBlocking.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2022, Linus Groh + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include + +namespace Web::Fetch::Infrastructure { + +ErrorOr determine_nosniff(HeaderList const&); +ErrorOr should_response_to_request_be_blocked_due_to_nosniff(Response const&, Request const&); + +}