diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index 63e5a614034..df8a9eb0b35 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -55,6 +55,7 @@ set(SOURCES ContentSecurityPolicy/Directives/MediaSourceDirective.cpp ContentSecurityPolicy/Directives/Names.cpp ContentSecurityPolicy/Directives/ObjectSourceDirective.cpp + ContentSecurityPolicy/Directives/ScriptSourceAttributeDirective.cpp ContentSecurityPolicy/Directives/ScriptSourceDirective.cpp ContentSecurityPolicy/Directives/ScriptSourceElementDirective.cpp ContentSecurityPolicy/Directives/SerializedDirective.cpp diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp b/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp index 98da5b3a510..e485c525dcd 100644 --- a/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -43,6 +44,9 @@ GC::Ref create_directive(GC::Heap& heap, String name, Vector if (name == Names::ObjectSrc) return heap.allocate(move(name), move(value)); + if (name == Names::ScriptSrcAttr) + return heap.allocate(move(name), move(value)); + if (name == Names::ScriptSrc) return heap.allocate(move(name), move(value)); diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/ScriptSourceAttributeDirective.cpp b/Libraries/LibWeb/ContentSecurityPolicy/Directives/ScriptSourceAttributeDirective.cpp new file mode 100644 index 00000000000..a94a4e21e1b --- /dev/null +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/ScriptSourceAttributeDirective.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024, Luke Wilde + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +namespace Web::ContentSecurityPolicy::Directives { + +GC_DEFINE_ALLOCATOR(ScriptSourceAttributeDirective); + +ScriptSourceAttributeDirective::ScriptSourceAttributeDirective(String name, Vector value) + : Directive(move(name), move(value)) +{ +} + +// https://w3c.github.io/webappsec-csp/#script-src-attr-inline +Directive::Result ScriptSourceAttributeDirective::inline_check(GC::Heap&, GC::Ptr element, InlineType type, GC::Ref policy, String const& source) const +{ + // 1. Assert: element is not null or type is "navigation". + VERIFY(element || type == InlineType::Navigation); + + // 2. Let name be the result of executing § 6.8.2 Get the effective directive for inline checks on type. + auto name = get_the_effective_directive_for_inline_checks(type); + + // 3. If the result of executing § 6.8.4 Should fetch directive execute on name, script-src-attr and policy is "No", + // return "Allowed". + if (should_fetch_directive_execute(name, Names::ScriptSrcAttr, policy) == ShouldExecute::No) + return Result::Allowed; + + // 4. If the result of executing § 6.7.3.3 Does element match source list for type and source? on element, this + // directive’s value, type, and source is "Does Not Match", return "Blocked". + if (does_element_match_source_list_for_type_and_source(element, value(), type, source) == MatchResult::DoesNotMatch) + return Result::Blocked; + + // 5. Return "Allowed". + return Result::Allowed; +} + +} diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/ScriptSourceAttributeDirective.h b/Libraries/LibWeb/ContentSecurityPolicy/Directives/ScriptSourceAttributeDirective.h new file mode 100644 index 00000000000..2675ded8e22 --- /dev/null +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/ScriptSourceAttributeDirective.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2024, Luke Wilde + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace Web::ContentSecurityPolicy::Directives { + +// https://w3c.github.io/webappsec-csp/#directive-script-src-attr +class ScriptSourceAttributeDirective final : public Directive { + GC_CELL(ScriptSourceAttributeDirective, Directive) + GC_DECLARE_ALLOCATOR(ScriptSourceAttributeDirective); + +public: + virtual ~ScriptSourceAttributeDirective() = default; + + virtual Result inline_check(GC::Heap&, GC::Ptr, InlineType, GC::Ref, String const&) const override; + +private: + ScriptSourceAttributeDirective(String name, Vector value); +}; + +} diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h index 51013201c92..5417dd8e635 100644 --- a/Libraries/LibWeb/Forward.h +++ b/Libraries/LibWeb/Forward.h @@ -140,6 +140,7 @@ class ImageSourceDirective; class ManifestSourceDirective; class MediaSourceDirective; class ObjectSourceDirective; +class ScriptSourceAttributeDirective; class ScriptSourceDirective; class ScriptSourceElementDirective; struct SerializedDirective;