diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index 5f83ec696ca..2a3e9b1021c 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -555,6 +555,7 @@ set(SOURCES HTML/PromiseRejectionEvent.cpp HTML/RadioNodeList.cpp HTML/RenderingThread.cpp + HTML/SandboxingFlagSet.cpp HTML/Scripting/Agent.cpp HTML/Scripting/ClassicScript.cpp HTML/Scripting/Environments.cpp diff --git a/Libraries/LibWeb/HTML/BrowsingContext.cpp b/Libraries/LibWeb/HTML/BrowsingContext.cpp index bd04b877d5b..c4de984be6c 100644 --- a/Libraries/LibWeb/HTML/BrowsingContext.cpp +++ b/Libraries/LibWeb/HTML/BrowsingContext.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -487,11 +488,28 @@ bool BrowsingContext::is_familiar_with(BrowsingContext const& other) const return false; } -// https://html.spec.whatwg.org/multipage/browsing-the-web.html#snapshotting-target-snapshot-params -SandboxingFlagSet determine_the_creation_sandboxing_flags(BrowsingContext const&, GC::Ptr) +// https://html.spec.whatwg.org/multipage/browsers.html#determining-the-creation-sandboxing-flags +SandboxingFlagSet determine_the_creation_sandboxing_flags(BrowsingContext const& browsing_context, GC::Ptr embedder) { - // FIXME: Populate this once we have the proper flag sets on BrowsingContext - return {}; + // To determine the creation sandboxing flags for a browsing context browsing context, given null or an element + // embedder, return the union of the flags that are present in the following sandboxing flag sets: + SandboxingFlagSet sandboxing_flags {}; + + // - If embedder is null, then: the flags set on browsing context's popup sandboxing flag set. + if (!embedder) { + sandboxing_flags |= browsing_context.popup_sandboxing_flag_set(); + } else { + // - If embedder is an element, then: the flags set on embedder's iframe sandboxing flag set. + if (is(embedder.ptr())) { + auto const& iframe_element = static_cast(*embedder); + sandboxing_flags |= iframe_element.iframe_sandboxing_flag_set(); + } + + // - If embedder is an element, then: the flags set on embedder's node document's active sandboxing flag set. + sandboxing_flags |= embedder->document().active_sandboxing_flag_set(); + } + + return sandboxing_flags; } bool BrowsingContext::has_navigable_been_destroyed() const diff --git a/Libraries/LibWeb/HTML/HTMLIFrameElement.cpp b/Libraries/LibWeb/HTML/HTMLIFrameElement.cpp index 1a8a7743fb2..91c387bedf4 100644 --- a/Libraries/LibWeb/HTML/HTMLIFrameElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLIFrameElement.cpp @@ -53,6 +53,11 @@ void HTMLIFrameElement::attribute_changed(FlyString const& name, Optionalassociated_attribute_changed(value.value_or(String {})); + } + // https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-iframe-element:process-the-iframe-attributes-2 // https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-iframe-element:process-the-iframe-attributes-3 // Whenever an iframe element with a non-null content navigable has its srcdoc attribute set, changed, or removed, @@ -62,6 +67,21 @@ void HTMLIFrameElement::attribute_changed(FlyString const& name, Optional sandbox(); + SandboxingFlagSet iframe_sandboxing_flag_set() const { return m_iframe_sandboxing_flag_set; } + virtual void visit_edges(Cell::Visitor&) override; private: @@ -64,6 +66,9 @@ private: Optional m_pending_resource_start_time = {}; GC::Ptr m_sandbox; + + // https://html.spec.whatwg.org/multipage/browsers.html#iframe-sandboxing-flag-set + SandboxingFlagSet m_iframe_sandboxing_flag_set {}; }; void run_iframe_load_event_steps(HTML::HTMLIFrameElement&); diff --git a/Libraries/LibWeb/HTML/SandboxingFlagSet.cpp b/Libraries/LibWeb/HTML/SandboxingFlagSet.cpp new file mode 100644 index 00000000000..cb73808eab7 --- /dev/null +++ b/Libraries/LibWeb/HTML/SandboxingFlagSet.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2024, Luke Wilde + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +namespace Web::HTML { + +// https://html.spec.whatwg.org/multipage/browsers.html#parse-a-sandboxing-directive +SandboxingFlagSet parse_a_sandboxing_directive(String const& input) +{ + // 1. Split input on ASCII whitespace, to obtain tokens. + auto lowercase_input = input.to_ascii_lowercase(); + auto tokens = lowercase_input.bytes_as_string_view().split_view_if(Infra::is_ascii_whitespace); + + // 2. Let output be empty. + SandboxingFlagSet output {}; + + // 3. Add the following flags to output: + // - The sandboxed navigation browsing context flag. + output |= SandboxingFlagSet::SandboxedNavigation; + + // - The sandboxed auxiliary navigation browsing context flag, unless tokens contains the allow-popups keyword. + if (!tokens.contains_slow("allow-popups"sv)) + output |= SandboxingFlagSet::SandboxedAuxiliaryNavigation; + + // - The sandboxed top-level navigation without user activation browsing context flag, unless tokens contains the + // allow-top-navigation keyword. + if (!tokens.contains_slow("allow-top-navigation"sv)) + output |= SandboxingFlagSet::SandboxedTopLevelNavigationWithoutUserActivation; + + // - The sandboxed top-level navigation with user activation browsing context flag, unless tokens contains either + // the allow-top-navigation-by-user-activation keyword or the allow-top-navigation keyword. + // Spec Note: This means that if the allow-top-navigation is present, the allow-top-navigation-by-user-activation + // keyword will have no effect. For this reason, specifying both is a document conformance error. + if (!tokens.contains_slow("allow-top-navigation"sv) && !tokens.contains_slow("allow-top-navigation-by-user-activation"sv)) + output |= SandboxingFlagSet::SandboxedTopLevelNavigationWithUserActivation; + + // - The sandboxed origin browsing context flag, unless the tokens contains the allow-same-origin keyword. + // Spec Note: The allow-same-origin keyword is intended for two cases. + // + // First, it can be used to allow content from the same site to be sandboxed to disable scripting, + // while still allowing access to the DOM of the sandboxed content. + // + // Second, it can be used to embed content from a third-party site, sandboxed to prevent that site from + // opening popups, etc, without preventing the embedded page from communicating back to its originating + // site, using the database APIs to store data, etc. + if (!tokens.contains_slow("allow-same-origin"sv)) + output |= SandboxingFlagSet::SandboxedOrigin; + + // - The sandboxed forms browsing context flag, unless tokens contains the allow-forms keyword. + if (!tokens.contains_slow("allow-forms"sv)) + output |= SandboxingFlagSet::SandboxedForms; + + // - The sandboxed pointer lock browsing context flag, unless tokens contains the allow-pointer-lock keyword. + if (!tokens.contains_slow("allow-pointer-lock"sv)) + output |= SandboxingFlagSet::SandboxedPointerLock; + + // - The sandboxed scripts browsing context flag, unless tokens contains the allow-scripts keyword. + // - The sandboxed automatic features browsing context flag, unless tokens contains the allow-scripts keyword + // (defined above). + // Spec Note: This flag is relaxed by the same keyword as scripts, because when scripts are enabled these features + // are trivially possible anyway, and it would be unfortunate to force authors to use script to do them + // when sandboxed rather than allowing them to use the declarative features. + if (!tokens.contains_slow("allow-scripts"sv)) { + output |= SandboxingFlagSet::SandboxedScripts; + output |= SandboxingFlagSet::SandboxedAutomaticFeatures; + } + + // - The sandboxed document.domain browsing context flag. + output |= SandboxingFlagSet::SandboxedDocumentDomain; + + // - The sandbox propagates to auxiliary browsing contexts flag, unless tokens contains the + // allow-popups-to-escape-sandbox keyword. + if (!tokens.contains_slow("allow-popups-to-escape-sandbox"sv)) + output |= SandboxingFlagSet::SandboxPropagatesToAuxiliaryBrowsingContexts; + + // - The sandboxed modals flag, unless tokens contains the allow-modals keyword. + if (!tokens.contains_slow("allow-modals"sv)) + output |= SandboxingFlagSet::SandboxedModals; + + // - The sandboxed orientation lock browsing context flag, unless tokens contains the allow-orientation-lock + // keyword. + if (!tokens.contains_slow("allow-orientation-lock"sv)) + output |= SandboxingFlagSet::SandboxedOrientationLock; + + // - The sandboxed presentation browsing context flag, unless tokens contains the allow-presentation keyword. + if (!tokens.contains_slow("allow-presentation"sv)) + output |= SandboxingFlagSet::SandboxedPresentation; + + // - The sandboxed downloads browsing context flag, unless tokens contains the allow-downloads keyword. + if (!tokens.contains_slow("allow-downloads"sv)) + output |= SandboxingFlagSet::SandboxedDownloads; + + // - The sandboxed custom protocols navigation browsing context flag, unless tokens contains either the + // allow-top-navigation-to-custom-protocols keyword, the allow-popups keyword, or the allow-top-navigation + // keyword. + if (!tokens.contains_slow("allow-top-navigation-to-custom-protocols"sv) && !tokens.contains_slow("allow-popups"sv) && !tokens.contains_slow("allow-top-navigation"sv)) + output |= SandboxingFlagSet::SandboxedCustomProtocols; + + return output; +} + +} diff --git a/Libraries/LibWeb/HTML/SandboxingFlagSet.h b/Libraries/LibWeb/HTML/SandboxingFlagSet.h index 75c7f1a3402..696eec0e27d 100644 --- a/Libraries/LibWeb/HTML/SandboxingFlagSet.h +++ b/Libraries/LibWeb/HTML/SandboxingFlagSet.h @@ -7,6 +7,7 @@ #pragma once #include +#include #include namespace Web::HTML { @@ -35,4 +36,6 @@ enum class SandboxingFlagSet { AK_ENUM_BITWISE_OPERATORS(SandboxingFlagSet); inline bool is_empty(SandboxingFlagSet s) { return (to_underlying(s) & 0x1FFU) == 0; } +SandboxingFlagSet parse_a_sandboxing_directive(String const& input); + } diff --git a/Libraries/LibWeb/HTML/Scripting/Environments.cpp b/Libraries/LibWeb/HTML/Scripting/Environments.cpp index e36488751ce..fc6ab3a5781 100644 --- a/Libraries/LibWeb/HTML/Scripting/Environments.cpp +++ b/Libraries/LibWeb/HTML/Scripting/Environments.cpp @@ -293,7 +293,9 @@ bool is_scripting_enabled(JS::Realm const& realm) if (!document.page().is_scripting_enabled()) return false; - // FIXME: Either settings's global object is not a Window object, or settings's global object's associated Document's active sandboxing flag set does not have its sandboxed scripts browsing context flag set. + // Either settings's global object is not a Window object, or settings's global object's associated Document's active sandboxing flag set does not have its sandboxed scripts browsing context flag set. + if (has_flag(document.active_sandboxing_flag_set(), SandboxingFlagSet::SandboxedScripts)) + return false; return true; } diff --git a/Tests/LibWeb/Ref/expected/wpt-import/html/browsers/sandboxing/sandbox-parse-noscript-ref.html b/Tests/LibWeb/Ref/expected/wpt-import/html/browsers/sandboxing/sandbox-parse-noscript-ref.html new file mode 100644 index 00000000000..9cf92768f78 --- /dev/null +++ b/Tests/LibWeb/Ref/expected/wpt-import/html/browsers/sandboxing/sandbox-parse-noscript-ref.html @@ -0,0 +1,6 @@ + + +noscript parsing when sandbox disables scripting + + + diff --git a/Tests/LibWeb/Ref/input/wpt-import/html/browsers/sandboxing/noscript-iframe.html b/Tests/LibWeb/Ref/input/wpt-import/html/browsers/sandboxing/noscript-iframe.html new file mode 100644 index 00000000000..677b5fc83aa --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/html/browsers/sandboxing/noscript-iframe.html @@ -0,0 +1,3 @@ + + + diff --git a/Tests/LibWeb/Ref/input/wpt-import/html/browsers/sandboxing/sandbox-parse-noscript.html b/Tests/LibWeb/Ref/input/wpt-import/html/browsers/sandboxing/sandbox-parse-noscript.html new file mode 100644 index 00000000000..e8b8537325e --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/html/browsers/sandboxing/sandbox-parse-noscript.html @@ -0,0 +1,7 @@ + + +noscript parsing when sandbox disables scripting + + + + diff --git a/Tests/LibWeb/TestConfig.ini b/Tests/LibWeb/TestConfig.ini index 3cc3d1c7638..7640268c283 100644 --- a/Tests/LibWeb/TestConfig.ini +++ b/Tests/LibWeb/TestConfig.ini @@ -320,3 +320,16 @@ Text/input/wpt-import/webaudio/the-audio-api/the-periodicwave-interface/periodic ; https://github.com/LadybirdBrowser/ladybird/issues/5333 Text/input/wpt-import/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect.html Text/input/wpt-import/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html + +; Currently always timeout +Text/input/wpt-import/html/browsers/sandboxing/inner-iframe.html +Text/input/wpt-import/html/browsers/sandboxing/sandbox-inherited-from-initiator-response.html +Text/input/wpt-import/html/browsers/sandboxing/sandbox-javascript-window-open.html +Text/input/wpt-import/html/browsers/sandboxing/sandbox-initial-empty-document-toward-same-origin.html +Text/input/wpt-import/html/browsers/sandboxing/sandbox-disallow-scripts-via-unsandboxed-popup.tentative.html +Text/input/wpt-import/html/browsers/sandboxing/sandbox-document-open.html +Text/input/wpt-import/html/browsers/sandboxing/sandbox-inherited-from-required-csp.html +Text/input/wpt-import/html/browsers/sandboxing/sandbox-navigation-timing.tentative.html + +; Not a ref test, but a subfile of the sandbox-parse-noscript ref test +Ref/input/wpt-import/html/browsers/sandboxing/noscript-iframe.html diff --git a/Tests/LibWeb/Text/expected/wpt-import/fetch/api/cors/sandboxed-iframe.txt b/Tests/LibWeb/Text/expected/wpt-import/fetch/api/cors/sandboxed-iframe.txt new file mode 100644 index 00000000000..314d7c85602 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/fetch/api/cors/sandboxed-iframe.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Fail +Fail CORS with sandboxed iframe \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-allow-same-origin.txt b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-allow-same-origin.txt new file mode 100644 index 00000000000..09b76c612b1 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-allow-same-origin.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Pass +Pass DOM access in sandbox='allow-same-origin' iframe is allowed \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-allow-scripts.txt b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-allow-scripts.txt new file mode 100644 index 00000000000..14f8e7eab55 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-allow-scripts.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Pass +Pass Running script from sandbox='allow-scripts' iframe is allowed \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-disallow-popups.txt b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-disallow-popups.txt new file mode 100644 index 00000000000..64ab2747b51 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-disallow-popups.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Fail +Fail window.open in sandbox iframe \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-disallow-same-origin.txt b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-disallow-same-origin.txt new file mode 100644 index 00000000000..d953707b9ab --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-disallow-same-origin.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Pass +Pass Access to sandbox iframe is disallowed \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-disallow-scripts-via-unsandboxed-popup.tentative.txt b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-disallow-scripts-via-unsandboxed-popup.tentative.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-disallow-scripts.txt b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-disallow-scripts.txt new file mode 100644 index 00000000000..af8a060ee9a --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-disallow-scripts.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Pass +Pass Running script from sandbox iframe is disallowed \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-document-open-mutation.window.txt b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-document-open-mutation.window.txt new file mode 100644 index 00000000000..edebc2bb72d --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-document-open-mutation.window.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Fail +Fail Using document.open() against a document from a different window must not mutate the other window's sandbox flags \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-document-open.txt b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-document-open.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-inherited-from-initiator-frame.txt b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-inherited-from-initiator-frame.txt new file mode 100644 index 00000000000..a481d947c9e --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-inherited-from-initiator-frame.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Pass +Pass Inherit sandbox flags from the initiator's frame \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-inherited-from-initiator-response.txt b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-inherited-from-initiator-response.txt new file mode 100644 index 00000000000..d22bcdeef21 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-inherited-from-initiator-response.txt @@ -0,0 +1,6 @@ +Harness status: Timeout + +Found 1 tests + +1 Timeout +Timeout Inherit sandbox flags from the initiator's response \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-inherited-from-required-csp.txt b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-inherited-from-required-csp.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-initial-empty-document-toward-same-origin.txt b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-initial-empty-document-toward-same-origin.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-javascript-window-open.txt b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-javascript-window-open.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-navigation-timing.tentative.txt b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-navigation-timing.tentative.txt new file mode 100644 index 00000000000..968666a50f5 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-navigation-timing.tentative.txt @@ -0,0 +1,6 @@ +Harness status: Timeout + +Found 1 tests + +1 Timeout +Timeout setting sandbox attribute should not affect current document in iframe \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-new-execution-context.txt b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-new-execution-context.txt new file mode 100644 index 00000000000..b10475fff6b --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-new-execution-context.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Pass +Pass iframe with sandbox should load with new execution context \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-window-open-srcdoc.txt b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-window-open-srcdoc.txt new file mode 100644 index 00000000000..37b8cbe0876 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/sandboxing/sandbox-window-open-srcdoc.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Fail +Fail window.open('about:srcdoc') from sandboxed srcdoc doesn't crash. \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/embedded-content/the-iframe-element/sandbox-ascii-case-insensitive.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/embedded-content/the-iframe-element/sandbox-ascii-case-insensitive.txt index d1c5e6b5a0f..db605be4650 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/embedded-content/the-iframe-element/sandbox-ascii-case-insensitive.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/embedded-content/the-iframe-element/sandbox-ascii-case-insensitive.txt @@ -2,7 +2,6 @@ Harness status: OK Found 2 tests -1 Pass -1 Fail +2 Pass Pass iframe 'sandbox' ASCII case insensitive, allow-same-orİgin -Fail iframe 'sandbox' ASCII case insensitive, allow-ſcripts \ No newline at end of file +Pass iframe 'sandbox' ASCII case insensitive, allow-ſcripts \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/syntax/parsing/inhead-noscript-head.txt b/Tests/LibWeb/Text/expected/wpt-import/html/syntax/parsing/inhead-noscript-head.txt index 4f6659ceeda..4ecff49466e 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/html/syntax/parsing/inhead-noscript-head.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/html/syntax/parsing/inhead-noscript-head.txt @@ -2,5 +2,5 @@ Harness status: OK Found 1 tests -1 Fail -Fail When the scripting flag is disabled, a head start tag in "in head noscript" mode should be ignored \ No newline at end of file +1 Pass +Pass When the scripting flag is disabled, a head start tag in "in head noscript" mode should be ignored \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/common/utils.js b/Tests/LibWeb/Text/input/wpt-import/common/utils.js new file mode 100644 index 00000000000..62e742bee7f --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/common/utils.js @@ -0,0 +1,98 @@ +/** + * Create an absolute URL from `options` and defaulting unspecified properties to `window.location`. + * @param {Object} options - a `Location`-like object + * @param {string} options.hostname + * @param {string} options.subdomain - prepend subdomain to the hostname + * @param {string} options.port + * @param {string} options.path + * @param {string} options.query + * @param {string} options.hash + * @returns {string} + */ +function make_absolute_url(options) { + var loc = window.location; + var protocol = get(options, "protocol", loc.protocol); + if (protocol[protocol.length - 1] != ":") { + protocol += ":"; + } + + var hostname = get(options, "hostname", loc.hostname); + + var subdomain = get(options, "subdomain"); + if (subdomain) { + hostname = subdomain + "." + hostname; + } + + var port = get(options, "port", loc.port) + var path = get(options, "path", loc.pathname); + var query = get(options, "query", loc.search); + var hash = get(options, "hash", loc.hash) + + var url = protocol + "//" + hostname; + if (port) { + url += ":" + port; + } + + if (path[0] != "/") { + url += "/"; + } + url += path; + if (query) { + if (query[0] != "?") { + url += "?"; + } + url += query; + } + if (hash) { + if (hash[0] != "#") { + url += "#"; + } + url += hash; + } + return url; +} + +/** @private */ +function get(obj, name, default_val) { + if (obj.hasOwnProperty(name)) { + return obj[name]; + } + return default_val; +} + +/** + * Generate a new UUID. + * @returns {string} + */ +function token() { + var uuid = [to_hex(rand_int(32), 8), + to_hex(rand_int(16), 4), + to_hex(0x4000 | rand_int(12), 4), + to_hex(0x8000 | rand_int(14), 4), + to_hex(rand_int(48), 12)].join("-") + return uuid; +} + +/** @private */ +function rand_int(bits) { + if (bits < 1 || bits > 53) { + throw new TypeError(); + } else { + if (bits >= 1 && bits <= 30) { + return 0 | ((1 << bits) * Math.random()); + } else { + var high = (0 | ((1 << (bits - 30)) * Math.random())) * (1 << 30); + var low = 0 | ((1 << 30) * Math.random()); + return high + low; + } + } +} + +/** @private */ +function to_hex(x, length) { + var rv = x.toString(16); + while (rv.length < length) { + rv = "0" + rv; + } + return rv; +} diff --git a/Tests/LibWeb/Text/input/wpt-import/fetch/api/cors/sandboxed-iframe.html b/Tests/LibWeb/Text/input/wpt-import/fetch/api/cors/sandboxed-iframe.html new file mode 100644 index 00000000000..e4582a13eb8 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/fetch/api/cors/sandboxed-iframe.html @@ -0,0 +1,14 @@ + + + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/fetch/api/resources/sandboxed-iframe.html b/Tests/LibWeb/Text/input/wpt-import/fetch/api/resources/sandboxed-iframe.html new file mode 100644 index 00000000000..6e5d5065474 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/fetch/api/resources/sandboxed-iframe.html @@ -0,0 +1,34 @@ + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/inner-iframe.html b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/inner-iframe.html new file mode 100644 index 00000000000..229f6b3d852 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/inner-iframe.html @@ -0,0 +1,13 @@ + + + + + + +
foo
+ + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-allow-same-origin.html b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-allow-same-origin.html new file mode 100644 index 00000000000..b36a4793a71 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-allow-same-origin.html @@ -0,0 +1,30 @@ + + + + DOM access in sandbox="allow-same-origin" iframe + + + + + + + +

DOM access in sandbox="allow-same-origin" iframe

+ + + + +
+ + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-allow-scripts.html b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-allow-scripts.html new file mode 100644 index 00000000000..a9ecfd34492 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-allow-scripts.html @@ -0,0 +1,29 @@ + + + + Script execution in sandbox="allow-scripts" iframe + + + + + + + +

Script execution in sandbox="allow-scripts" iframe

+ + + + +
+ + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-disallow-popups.html b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-disallow-popups.html new file mode 100644 index 00000000000..186b1cd4674 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-disallow-popups.html @@ -0,0 +1,39 @@ + + +window.open in sandbox iframe + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-disallow-same-origin.html b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-disallow-same-origin.html new file mode 100644 index 00000000000..b253b040789 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-disallow-same-origin.html @@ -0,0 +1,35 @@ + + + + Access to sandbox iframe + + + + + + + + +

Access to sandbox iframe

+ + + + + +
+ diff --git a/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-disallow-scripts-via-unsandboxed-popup.tentative.html b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-disallow-scripts-via-unsandboxed-popup.tentative.html new file mode 100644 index 00000000000..940b6f3e274 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-disallow-scripts-via-unsandboxed-popup.tentative.html @@ -0,0 +1,33 @@ + + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-disallow-scripts.html b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-disallow-scripts.html new file mode 100644 index 00000000000..5635a5b19d2 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-disallow-scripts.html @@ -0,0 +1,29 @@ + + + + Script execution in sandbox iframe + + + + + + + +

Script execution in sandbox iframe

+ + + + +
+ + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-document-open-mutation.window.html b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-document-open-mutation.window.html new file mode 100644 index 00000000000..6af3282b774 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-document-open-mutation.window.html @@ -0,0 +1,8 @@ + + + + + + +
+ diff --git a/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-document-open-mutation.window.js b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-document-open-mutation.window.js new file mode 100644 index 00000000000..713ca612c5a --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-document-open-mutation.window.js @@ -0,0 +1,37 @@ +// Return whether the current context is sandboxed or not. The implementation do +// not matter much, but might have to change over time depending on what side +// effect sandbox flag have. Feel free to update as needed. +const is_sandboxed = () => { + try { + document.domain = document.domain; + return "not sandboxed"; + } catch (error) { + return "sandboxed"; + } +}; + +promise_test(async test => { + const message = new Promise(r => window.addEventListener("message", r)); + + const iframe_unsandboxed = document.createElement("iframe"); + document.body.appendChild(iframe_unsandboxed); + + const iframe_sandboxed = document.createElement("iframe"); + iframe_sandboxed.sandbox = "allow-same-origin allow-scripts"; + document.body.appendChild(iframe_sandboxed); + + iframe_sandboxed.srcdoc = ` + + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-inherited-from-initiator-frame.html b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-inherited-from-initiator-frame.html new file mode 100644 index 00000000000..234016e09e2 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-inherited-from-initiator-frame.html @@ -0,0 +1,64 @@ + + +Inherit sandbox flags from the initiator's frame + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-inherited-from-initiator-response.html b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-inherited-from-initiator-response.html new file mode 100644 index 00000000000..f8da116b5c4 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-inherited-from-initiator-response.html @@ -0,0 +1,46 @@ + + +Inherit sandbox flags from the initiator's response + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-inherited-from-required-csp.html b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-inherited-from-required-csp.html new file mode 100644 index 00000000000..eb9bbb15275 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-inherited-from-required-csp.html @@ -0,0 +1,154 @@ + + +Inherit sandbox from CSP embedded enforcement + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-initial-empty-document-toward-same-origin.html b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-initial-empty-document-toward-same-origin.html new file mode 100644 index 00000000000..21653cea213 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-initial-empty-document-toward-same-origin.html @@ -0,0 +1,30 @@ + + + + Check sandbox-flags inheritance in case of javascript window reuse. + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-javascript-window-open.html b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-javascript-window-open.html new file mode 100644 index 00000000000..7355ff7c7a7 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-javascript-window-open.html @@ -0,0 +1,19 @@ + + +window.open in sandbox iframe + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-navigation-timing.tentative.html b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-navigation-timing.tentative.html new file mode 100644 index 00000000000..b69ce406c3b --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-navigation-timing.tentative.html @@ -0,0 +1,29 @@ + + +Sandbox Navigation Timing + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-new-execution-context.html b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-new-execution-context.html new file mode 100644 index 00000000000..f89bff24ad3 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-new-execution-context.html @@ -0,0 +1,39 @@ + + + + Reuse of iframe about:blank document execution context + + + + + + + +

Reuse of iframe about:blank document execution context in sandbox="allow-scripts" iframe

+ +
+ + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-window-open-srcdoc.html b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-window-open-srcdoc.html new file mode 100644 index 00000000000..00fe6a6bf6b --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/browsers/sandboxing/sandbox-window-open-srcdoc.html @@ -0,0 +1,52 @@ + + +window.open("about:srcdoc") from a sandboxed iframe + + + +