/src/serenity/Userland/Libraries/LibWeb/Fetch/Infrastructure/NoSniffBlocking.cpp
Line | Count | Source |
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 | | |
13 | | namespace Web::Fetch::Infrastructure { |
14 | | |
15 | | // https://fetch.spec.whatwg.org/#determine-nosniff |
16 | | bool determine_nosniff(HeaderList const& list) |
17 | 0 | { |
18 | | // 1. Let values be the result of getting, decoding, and splitting `X-Content-Type-Options` from list. |
19 | 0 | auto values = list.get_decode_and_split("X-Content-Type-Options"sv.bytes()); |
20 | | |
21 | | // 2. If values is null, then return false. |
22 | 0 | if (!values.has_value()) |
23 | 0 | return false; |
24 | | |
25 | | // 3. If values[0] is an ASCII case-insensitive match for "nosniff", then return true. |
26 | 0 | if (!values->is_empty() && Infra::is_ascii_case_insensitive_match(values->at(0), "nosniff"sv)) |
27 | 0 | return true; |
28 | | |
29 | | // 4. Return false. |
30 | 0 | return false; |
31 | 0 | } |
32 | | |
33 | | // https://fetch.spec.whatwg.org/#should-response-to-request-be-blocked-due-to-nosniff? |
34 | | RequestOrResponseBlocking should_response_to_request_be_blocked_due_to_nosniff(Response const& response, Request const& request) |
35 | 0 | { |
36 | | // 1. If determine nosniff with response’s header list is false, then return allowed. |
37 | 0 | if (!determine_nosniff(response.header_list())) |
38 | 0 | return RequestOrResponseBlocking::Allowed; |
39 | | |
40 | | // 2. Let mimeType be the result of extracting a MIME type from response’s header list. |
41 | 0 | auto mime_type = response.header_list()->extract_mime_type(); |
42 | | |
43 | | // 3. Let destination be request’s destination. |
44 | 0 | 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 | 0 | if (request.destination_is_script_like() && (!mime_type.has_value() || !mime_type->is_javascript())) |
48 | 0 | 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 | 0 | if (destination == Request::Destination::Style && (!mime_type.has_value() || mime_type->essence() != "text/css"sv)) |
52 | 0 | return RequestOrResponseBlocking::Blocked; |
53 | | |
54 | | // 6. Return allowed. |
55 | 0 | return RequestOrResponseBlocking::Allowed; |
56 | 0 | } |
57 | | |
58 | | } |