Преглед на файлове

LibWeb: Implement should block mixed content request

Jamie Mansfield преди 1 година
родител
ревизия
8f0d035145

+ 1 - 0
Meta/gn/secondary/Userland/Libraries/LibWeb/BUILD.gn

@@ -334,6 +334,7 @@ shared_library("LibWeb") {
            "Loader",
            "MathML",
            "MimeSniff",
+           "MixedContent",
            "NavigationTiming",
            "Page",
            "Painting",

+ 5 - 0
Meta/gn/secondary/Userland/Libraries/LibWeb/MixedContent/BUILD.gn

@@ -0,0 +1,5 @@
+source_set("MixedContent") {
+  configs += [ "//Userland/Libraries/LibWeb:configs" ]
+  deps = [ "//Userland/Libraries/LibWeb:all_generated" ]
+  sources = [ "AbstractOperations.cpp" ]
+}

+ 1 - 0
Userland/Libraries/LibWeb/CMakeLists.txt

@@ -520,6 +520,7 @@ set(SOURCES
     MathML/TagNames.cpp
     MimeSniff/MimeType.cpp
     MimeSniff/Resource.cpp
+    MixedContent/AbstractOperations.cpp
     Namespace.cpp
     NavigationTiming/EntryNames.cpp
     NavigationTiming/PerformanceTiming.cpp

+ 5 - 0
Userland/Libraries/LibWeb/DOM/Document.cpp

@@ -3083,6 +3083,11 @@ Vector<JS::Handle<HTML::Navigable>> Document::ancestor_navigables()
     return ancestors;
 }
 
+Vector<JS::Handle<HTML::Navigable>> const Document::ancestor_navigables() const
+{
+    return const_cast<Document&>(*this).ancestor_navigables();
+}
+
 // https://html.spec.whatwg.org/multipage/document-sequences.html#inclusive-ancestor-navigables
 Vector<JS::Handle<HTML::Navigable>> Document::inclusive_ancestor_navigables()
 {

+ 1 - 0
Userland/Libraries/LibWeb/DOM/Document.h

@@ -517,6 +517,7 @@ public:
     Vector<JS::Handle<HTML::Navigable>> const descendant_navigables() const;
     Vector<JS::Handle<HTML::Navigable>> inclusive_descendant_navigables();
     Vector<JS::Handle<HTML::Navigable>> ancestor_navigables();
+    Vector<JS::Handle<HTML::Navigable>> const ancestor_navigables() const;
     Vector<JS::Handle<HTML::Navigable>> inclusive_ancestor_navigables();
     Vector<JS::Handle<HTML::Navigable>> document_tree_child_navigables();
 

+ 2 - 1
Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp

@@ -46,6 +46,7 @@
 #include <LibWeb/HighResolutionTime/TimeOrigin.h>
 #include <LibWeb/Loader/LoadRequest.h>
 #include <LibWeb/Loader/ResourceLoader.h>
+#include <LibWeb/MixedContent/AbstractOperations.h>
 #include <LibWeb/Platform/EventLoopPlugin.h>
 #include <LibWeb/ReferrerPolicy/AbstractOperations.h>
 #include <LibWeb/SRI/SRI.h>
@@ -241,7 +242,7 @@ WebIDL::ExceptionOr<JS::GCPtr<PendingResponse>> main_fetch(JS::Realm& realm, Inf
     // 7. If should request be blocked due to a bad port, should fetching request be blocked as mixed content, or
     //    should request be blocked by Content Security Policy returns blocked, then set response to a network error.
     if (Infrastructure::block_bad_port(request) == Infrastructure::RequestOrResponseBlocking::Blocked
-        || false // FIXME: "should fetching request be blocked as mixed content"
+        || MixedContent::should_fetching_request_be_blocked_as_mixed_content(request) == Infrastructure::RequestOrResponseBlocking::Blocked
         || false // FIXME: "should request be blocked by Content Security Policy returns blocked"
     ) {
         response = Infrastructure::Response::network_error(vm, "Request was blocked"sv);

+ 61 - 0
Userland/Libraries/LibWeb/MixedContent/AbstractOperations.cpp

@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2024, Jamie Mansfield <jmansfield@cadixdev.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <LibWeb/HTML/Window.h>
+#include <LibWeb/MixedContent/AbstractOperations.h>
+#include <LibWeb/SecureContexts/AbstractOperations.h>
+
+namespace Web::MixedContent {
+
+// https://w3c.github.io/webappsec-mixed-content/#categorize-settings-object
+ProhibitsMixedSecurityContexts does_settings_prohibit_mixed_security_contexts(JS::GCPtr<HTML::EnvironmentSettingsObject> settings)
+{
+    // 1. If settings’ origin is a potentially trustworthy origin, then return "Prohibits Mixed Security Contexts".
+    if (SecureContexts::is_origin_potentially_trustworthy(settings->origin()) == SecureContexts::Trustworthiness::PotentiallyTrustworthy)
+        return ProhibitsMixedSecurityContexts::ProhibitsMixedSecurityContexts;
+
+    // 2. If settings’ global object is a window, then:
+    if (is<HTML::Window>(settings->global_object())) {
+        // 1. Set document to settings’ global object's associated Document.
+        auto document = verify_cast<HTML::Window>(settings->global_object()).document();
+
+        // 2. For each navigable navigable in document’s ancestor navigables:
+        for (auto const& navigable : document->ancestor_navigables()) {
+            // 1. If navigable’s active document's origin is a potentially trustworthy origin, then return "Prohibits Mixed Security Contexts".
+            if (SecureContexts::is_origin_potentially_trustworthy(navigable->active_document()->origin()) == SecureContexts::Trustworthiness::PotentiallyTrustworthy)
+                return ProhibitsMixedSecurityContexts::ProhibitsMixedSecurityContexts;
+        }
+    }
+
+    // 3. Return "Does Not Restrict Mixed Security Contexts".
+    return ProhibitsMixedSecurityContexts::DoesNotRestrictMixedSecurityContexts;
+}
+
+// https://w3c.github.io/webappsec-mixed-content/#should-block-fetch
+Fetch::Infrastructure::RequestOrResponseBlocking should_fetching_request_be_blocked_as_mixed_content(Fetch::Infrastructure::Request& request)
+{
+    // 1. Return allowed if one or more of the following conditions are met:
+    if (
+        // 1. § 4.3 Does settings prohibit mixed security contexts? returns "Does Not Restrict Mixed Security Contexts" when applied to request’s client.
+        does_settings_prohibit_mixed_security_contexts(request.client()) == ProhibitsMixedSecurityContexts::DoesNotRestrictMixedSecurityContexts
+
+        // 2. request’s URL is a potentially trustworthy URL.
+        || SecureContexts::is_url_potentially_trustworthy(request.url()) == SecureContexts::Trustworthiness::PotentiallyTrustworthy
+
+        // FIXME: 3. The user agent has been instructed to allow mixed content, as described in § 7.2 User Controls).
+        || false
+
+        // 4. request’s destination is "document", and request’s target browsing context has no parent browsing context.
+        || (request.destination() == Fetch::Infrastructure::Request::Destination::Document && !request.client()->target_browsing_context->parent())) {
+        return Fetch::Infrastructure::RequestOrResponseBlocking::Allowed;
+    }
+
+    // 2. Return blocked.
+    dbgln("MixedContent: Blocked '{}' (request)", MUST(request.url().to_string()));
+    return Fetch::Infrastructure::RequestOrResponseBlocking::Blocked;
+}
+
+}

+ 24 - 0
Userland/Libraries/LibWeb/MixedContent/AbstractOperations.h

@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2024, Jamie Mansfield <jmansfield@cadixdev.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <LibJS/Heap/GCPtr.h>
+#include <LibWeb/Fetch/Infrastructure/RequestOrResponseBlocking.h>
+#include <LibWeb/HTML/Scripting/Environments.h>
+
+namespace Web::MixedContent {
+
+enum class ProhibitsMixedSecurityContexts {
+    ProhibitsMixedSecurityContexts,
+    DoesNotRestrictMixedSecurityContexts,
+};
+
+ProhibitsMixedSecurityContexts does_settings_prohibit_mixed_security_contexts(JS::GCPtr<HTML::EnvironmentSettingsObject>);
+
+Fetch::Infrastructure::RequestOrResponseBlocking should_fetching_request_be_blocked_as_mixed_content(Fetch::Infrastructure::Request&);
+
+}