Coverage Report

Created: 2026-09-14 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}