/src/serenity/Userland/Libraries/LibWeb/MixedContent/AbstractOperations.cpp
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2024, Jamie Mansfield <jmansfield@cadixdev.org> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #include <LibWeb/Fetch/Response.h> |
8 | | #include <LibWeb/HTML/Window.h> |
9 | | #include <LibWeb/MixedContent/AbstractOperations.h> |
10 | | #include <LibWeb/SecureContexts/AbstractOperations.h> |
11 | | |
12 | | namespace Web::MixedContent { |
13 | | |
14 | | // https://w3c.github.io/webappsec-mixed-content/#upgrade-algorithm |
15 | | void upgrade_a_mixed_content_request_to_a_potentially_trustworthy_url_if_appropriate(Fetch::Infrastructure::Request& request) |
16 | 0 | { |
17 | | // 1. If one or more of the following conditions is met, return without modifying request: |
18 | 0 | if ( |
19 | | // 1. request’s URL is a potentially trustworthy URL. |
20 | 0 | SecureContexts::is_url_potentially_trustworthy(request.url()) == SecureContexts::Trustworthiness::PotentiallyTrustworthy |
21 | | |
22 | | // 2. request’s URL’s host is an IP address. |
23 | 0 | || request.url().host().has<URL::IPv4Address>() || request.url().host().has<URL::IPv6Address>() |
24 | | |
25 | | // 3. § 4.3 Does settings prohibit mixed security contexts? returns "Does Not Restrict Mixed Security Contents" when applied to request’s client. |
26 | 0 | || does_settings_prohibit_mixed_security_contexts(request.client()) == ProhibitsMixedSecurityContexts::DoesNotRestrictMixedSecurityContexts |
27 | | |
28 | | // 4. request’s destination is not "image", "audio", or "video". |
29 | 0 | || (request.destination() != Fetch::Infrastructure::Request::Destination::Image |
30 | 0 | && request.destination() != Fetch::Infrastructure::Request::Destination::Audio |
31 | 0 | && request.destination() != Fetch::Infrastructure::Request::Destination::Video) |
32 | | |
33 | | // 5. request’s destination is "image" and request’s initiator is "imageset". |
34 | 0 | || (request.destination() == Fetch::Infrastructure::Request::Destination::Image |
35 | 0 | && request.initiator() == Fetch::Infrastructure::Request::Initiator::ImageSet)) { |
36 | 0 | return; |
37 | 0 | } |
38 | | |
39 | | // 2. If request’s URL’s scheme is http, set request’s URL’s scheme to https, and return. |
40 | 0 | if (request.url().scheme() == "http") |
41 | 0 | request.url().set_scheme("https"_string); |
42 | 0 | } |
43 | | |
44 | | // https://w3c.github.io/webappsec-mixed-content/#categorize-settings-object |
45 | | ProhibitsMixedSecurityContexts does_settings_prohibit_mixed_security_contexts(JS::GCPtr<HTML::EnvironmentSettingsObject> settings) |
46 | 0 | { |
47 | | // 1. If settings’ origin is a potentially trustworthy origin, then return "Prohibits Mixed Security Contexts". |
48 | 0 | if (SecureContexts::is_origin_potentially_trustworthy(settings->origin()) == SecureContexts::Trustworthiness::PotentiallyTrustworthy) |
49 | 0 | return ProhibitsMixedSecurityContexts::ProhibitsMixedSecurityContexts; |
50 | | |
51 | | // 2. If settings’ global object is a window, then: |
52 | 0 | if (is<HTML::Window>(settings->global_object())) { |
53 | | // 1. Set document to settings’ global object's associated Document. |
54 | 0 | auto document = verify_cast<HTML::Window>(settings->global_object()).document(); |
55 | | |
56 | | // 2. For each navigable navigable in document’s ancestor navigables: |
57 | 0 | for (auto const& navigable : document->ancestor_navigables()) { |
58 | | // 1. If navigable’s active document's origin is a potentially trustworthy origin, then return "Prohibits Mixed Security Contexts". |
59 | 0 | if (SecureContexts::is_origin_potentially_trustworthy(navigable->active_document()->origin()) == SecureContexts::Trustworthiness::PotentiallyTrustworthy) |
60 | 0 | return ProhibitsMixedSecurityContexts::ProhibitsMixedSecurityContexts; |
61 | 0 | } |
62 | 0 | } |
63 | | |
64 | | // 3. Return "Does Not Restrict Mixed Security Contexts". |
65 | 0 | return ProhibitsMixedSecurityContexts::DoesNotRestrictMixedSecurityContexts; |
66 | 0 | } |
67 | | |
68 | | // https://w3c.github.io/webappsec-mixed-content/#should-block-fetch |
69 | | Fetch::Infrastructure::RequestOrResponseBlocking should_fetching_request_be_blocked_as_mixed_content(Fetch::Infrastructure::Request& request) |
70 | 0 | { |
71 | | // 1. Return allowed if one or more of the following conditions are met: |
72 | 0 | if ( |
73 | | // 1. § 4.3 Does settings prohibit mixed security contexts? returns "Does Not Restrict Mixed Security Contexts" when applied to request’s client. |
74 | 0 | does_settings_prohibit_mixed_security_contexts(request.client()) == ProhibitsMixedSecurityContexts::DoesNotRestrictMixedSecurityContexts |
75 | | |
76 | | // 2. request’s URL is a potentially trustworthy URL. |
77 | 0 | || SecureContexts::is_url_potentially_trustworthy(request.url()) == SecureContexts::Trustworthiness::PotentiallyTrustworthy |
78 | | |
79 | | // FIXME: 3. The user agent has been instructed to allow mixed content, as described in § 7.2 User Controls). |
80 | 0 | || false |
81 | | |
82 | | // 4. request’s destination is "document", and request’s target browsing context has no parent browsing context. |
83 | | // TODO: "parent browsing context" doesn't exist anymore and is a spec bug, seems like it should be `is_top_level` |
84 | 0 | || (request.destination() == Fetch::Infrastructure::Request::Destination::Document && request.client()->target_browsing_context && request.client()->target_browsing_context->is_top_level())) { |
85 | 0 | return Fetch::Infrastructure::RequestOrResponseBlocking::Allowed; |
86 | 0 | } |
87 | | |
88 | | // 2. Return blocked. |
89 | 0 | dbgln("MixedContent: Blocked '{}' (request)", MUST(request.url().to_string())); |
90 | 0 | return Fetch::Infrastructure::RequestOrResponseBlocking::Blocked; |
91 | 0 | } |
92 | | |
93 | | // https://w3c.github.io/webappsec-mixed-content/#should-block-response |
94 | | Web::Fetch::Infrastructure::RequestOrResponseBlocking should_response_to_request_be_blocked_as_mixed_content(Fetch::Infrastructure::Request& request, JS::NonnullGCPtr<Fetch::Infrastructure::Response>& response) |
95 | 0 | { |
96 | | // 1. Return allowed if one or more of the following conditions are met: |
97 | 0 | if ( |
98 | | // 1. § 4.3 Does settings prohibit mixed security contexts? returns Does Not Restrict Mixed Content when applied to request’s client. |
99 | 0 | does_settings_prohibit_mixed_security_contexts(request.client()) == ProhibitsMixedSecurityContexts::DoesNotRestrictMixedSecurityContexts |
100 | | |
101 | | // 2. response’s url is a potentially trustworthy URL. |
102 | 0 | || (response->url().has_value() && SecureContexts::is_url_potentially_trustworthy(response->url().value()) == SecureContexts::Trustworthiness::PotentiallyTrustworthy) |
103 | | |
104 | | // FIXME: 3. The user agent has been instructed to allow mixed content, as described in § 7.2 User Controls). |
105 | 0 | || false |
106 | | |
107 | | // 4. request’s destination is "document", and request’s target browsing context has no parent browsing context. |
108 | | // TODO: "parent browsing context" doesn't exist anymore and is a spec bug, seems like it should be `is_top_level` |
109 | 0 | || (request.destination() == Fetch::Infrastructure::Request::Destination::Document && request.client()->target_browsing_context && request.client()->target_browsing_context->is_top_level())) { |
110 | 0 | return Fetch::Infrastructure::RequestOrResponseBlocking::Allowed; |
111 | 0 | } |
112 | | |
113 | | // 2. Return blocked. |
114 | 0 | dbgln("MixedContent: Blocked '{}' (response to request)", MUST(request.url().to_string())); |
115 | 0 | return Fetch::Infrastructure::RequestOrResponseBlocking::Blocked; |
116 | 0 | } |
117 | | |
118 | | } |