diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index 92679229b0d..d62e4dbaf11 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -61,6 +61,7 @@ set(SOURCES ContentSecurityPolicy/Directives/SerializedDirective.cpp ContentSecurityPolicy/Directives/SourceExpression.cpp ContentSecurityPolicy/Directives/StyleSourceDirective.cpp + ContentSecurityPolicy/Directives/StyleSourceElementDirective.cpp ContentSecurityPolicy/Policy.cpp ContentSecurityPolicy/PolicyList.cpp ContentSecurityPolicy/SecurityPolicyViolationEvent.cpp diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp b/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp index 54c6f6849db..d41d56e4fa9 100644 --- a/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp @@ -19,6 +19,7 @@ #include #include #include +#include namespace Web::ContentSecurityPolicy::Directives { @@ -57,6 +58,9 @@ GC::Ref create_directive(GC::Heap& heap, String name, Vector if (name == Names::StyleSrc) return heap.allocate(move(name), move(value)); + if (name == Names::StyleSrcElem) + return heap.allocate(move(name), move(value)); + return heap.allocate(move(name), move(value)); } diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/StyleSourceElementDirective.cpp b/Libraries/LibWeb/ContentSecurityPolicy/Directives/StyleSourceElementDirective.cpp new file mode 100644 index 00000000000..211fc73bec4 --- /dev/null +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/StyleSourceElementDirective.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2024, Luke Wilde + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +namespace Web::ContentSecurityPolicy::Directives { + +GC_DEFINE_ALLOCATOR(StyleSourceElementDirective); + +StyleSourceElementDirective::StyleSourceElementDirective(String name, Vector value) + : Directive(move(name), move(value)) +{ +} + +// https://w3c.github.io/webappsec-csp/#style-src-elem-pre-request +Directive::Result StyleSourceElementDirective::pre_request_check(GC::Heap&, GC::Ref request, GC::Ref policy) const +{ + // 1. Let name be the result of executing § 6.8.1 Get the effective directive for request on request. + auto name = get_the_effective_directive_for_request(request); + + // 2. If the result of executing § 6.8.4 Should fetch directive execute on name, style-src-elem and policy is "No", + // return "Allowed". + if (should_fetch_directive_execute(name, Names::StyleSrcElem, policy) == ShouldExecute::No) + return Result::Allowed; + + // 3. If the result of executing § 6.7.2.3 Does nonce match source list? on request’s cryptographic nonce metadata + // and this directive’s value is "Matches", return "Allowed". + if (does_nonce_match_source_list(request->cryptographic_nonce_metadata(), value()) == MatchResult::Matches) + return Result::Allowed; + + // 4. If the result of executing § 6.7.2.5 Does request match source list? on request, this directive’s value, and + // policy, is "Does Not Match", return "Blocked". + if (does_request_match_source_list(request, value(), policy) == MatchResult::DoesNotMatch) + return Result::Blocked; + + // 5. Return "Allowed". + return Result::Allowed; +} + +// https://w3c.github.io/webappsec-csp/#style-src-elem-post-request +Directive::Result StyleSourceElementDirective::post_request_check(GC::Heap&, GC::Ref request, GC::Ref response, GC::Ref policy) const +{ + // 1. Let name be the result of executing § 6.8.1 Get the effective directive for request on request. + auto name = get_the_effective_directive_for_request(request); + + // 2. If the result of executing § 6.8.4 Should fetch directive execute on name, style-src-elem and policy is "No", + // return "Allowed". + if (should_fetch_directive_execute(name, Names::StyleSrcElem, policy) == ShouldExecute::No) + return Result::Allowed; + + // 3. If the result of executing § 6.7.2.3 Does nonce match source list? on request’s cryptographic nonce metadata + // and this directive’s value is "Matches", return "Allowed". + if (does_nonce_match_source_list(request->cryptographic_nonce_metadata(), value()) == MatchResult::Matches) + return Result::Allowed; + + // 4. If the result of executing § 6.7.2.6 Does response to request match source list? on response, request, this + // directive’s value, and policy, is "Does Not Match", return "Blocked". + if (does_response_match_source_list(response, request, value(), policy) == MatchResult::DoesNotMatch) + return Result::Blocked; + + // 5. Return "Allowed". + return Result::Allowed; +} + +// https://w3c.github.io/webappsec-csp/#style-src-elem-inline +Directive::Result StyleSourceElementDirective::inline_check(GC::Heap&, GC::Ptr element, InlineType type, GC::Ref policy, String const& source) const +{ + // 1. 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); + + // 2. If the result of executing § 6.8.4 Should fetch directive execute on name, style-src-elem and policy is "No", + // return "Allowed". + if (should_fetch_directive_execute(name, Names::StyleSrcElem, policy) == ShouldExecute::No) + return Result::Allowed; + + // 3. 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; + + // 4. Return "Allowed". + return Result::Allowed; +} + +} diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/StyleSourceElementDirective.h b/Libraries/LibWeb/ContentSecurityPolicy/Directives/StyleSourceElementDirective.h new file mode 100644 index 00000000000..fb7823a4512 --- /dev/null +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/StyleSourceElementDirective.h @@ -0,0 +1,29 @@ +/* + * 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-style-src-elem +class StyleSourceElementDirective final : public Directive { + GC_CELL(StyleSourceElementDirective, Directive) + GC_DECLARE_ALLOCATOR(StyleSourceElementDirective); + +public: + virtual ~StyleSourceElementDirective() = default; + + virtual Result pre_request_check(GC::Heap&, GC::Ref, GC::Ref) const override; + virtual Result post_request_check(GC::Heap&, GC::Ref, GC::Ref, GC::Ref) const override; + virtual Result inline_check(GC::Heap&, GC::Ptr, InlineType, GC::Ref, String const&) const override; + +private: + StyleSourceElementDirective(String name, Vector value); +}; + +} diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h index 27517f5bb9c..b54621aeb7e 100644 --- a/Libraries/LibWeb/Forward.h +++ b/Libraries/LibWeb/Forward.h @@ -144,6 +144,7 @@ class ScriptSourceAttributeDirective; class ScriptSourceDirective; class ScriptSourceElementDirective; class StyleSourceDirective; +class StyleSourceElementDirective; struct SerializedDirective; }