diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index cd1b1faa0a4..3bcf5fea40a 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -41,6 +41,7 @@ set(SOURCES ContentSecurityPolicy/Directives/DirectiveFactory.cpp ContentSecurityPolicy/Directives/DirectiveOperations.cpp ContentSecurityPolicy/Directives/FontSourceDirective.cpp + ContentSecurityPolicy/Directives/FrameSourceDirective.cpp ContentSecurityPolicy/Directives/KeywordSources.cpp ContentSecurityPolicy/Directives/Names.cpp ContentSecurityPolicy/Directives/SerializedDirective.cpp diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp b/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp index cc4c72783c0..0f8a391a3fb 100644 --- a/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include namespace Web::ContentSecurityPolicy::Directives { @@ -21,6 +22,9 @@ GC::Ref create_directive(GC::Heap& heap, String name, Vector if (name == Names::FontSrc) return heap.allocate(move(name), move(value)); + if (name == Names::FrameSrc) + return heap.allocate(move(name), move(value)); + return heap.allocate(move(name), move(value)); } diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/FrameSourceDirective.cpp b/Libraries/LibWeb/ContentSecurityPolicy/Directives/FrameSourceDirective.cpp new file mode 100644 index 00000000000..163c3cc502d --- /dev/null +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/FrameSourceDirective.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2024, Luke Wilde + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +namespace Web::ContentSecurityPolicy::Directives { + +GC_DEFINE_ALLOCATOR(FrameSourceDirective); + +FrameSourceDirective::FrameSourceDirective(String name, Vector value) + : Directive(move(name), move(value)) +{ +} + +// https://w3c.github.io/webappsec-csp/#frame-src-pre-request +Directive::Result FrameSourceDirective::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, frame-src and policy is "No", + // return "Allowed". + if (should_fetch_directive_execute(name, Names::FrameSrc, policy) == ShouldExecute::No) + return Result::Allowed; + + // 3. 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; + + // 4. Return "Allowed". + return Result::Allowed; +} + +// https://w3c.github.io/webappsec-csp/#frame-src-post-request +Directive::Result FrameSourceDirective::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, frame-src and policy is "No", + // return "Allowed". + if (should_fetch_directive_execute(name, Names::FrameSrc, policy) == ShouldExecute::No) + return Result::Allowed; + + // 3. 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; + + // 4. Return "Allowed". + return Result::Allowed; +} + +} diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/FrameSourceDirective.h b/Libraries/LibWeb/ContentSecurityPolicy/Directives/FrameSourceDirective.h new file mode 100644 index 00000000000..14f6ac68772 --- /dev/null +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/FrameSourceDirective.h @@ -0,0 +1,28 @@ +/* + * 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-frame-src +class FrameSourceDirective final : public Directive { + GC_CELL(FrameSourceDirective, Directive) + GC_DECLARE_ALLOCATOR(FrameSourceDirective); + +public: + virtual ~FrameSourceDirective() = default; + + [[nodiscard]] virtual Result pre_request_check(GC::Heap&, GC::Ref, GC::Ref) const override; + [[nodiscard]] virtual Result post_request_check(GC::Heap&, GC::Ref, GC::Ref, GC::Ref) const override; + +private: + FrameSourceDirective(String name, Vector value); +}; + +} diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h index c233dc80473..78e04083b23 100644 --- a/Libraries/LibWeb/Forward.h +++ b/Libraries/LibWeb/Forward.h @@ -133,6 +133,7 @@ namespace Web::ContentSecurityPolicy::Directives { class ConnectSourceDirective; class Directive; class FontSourceDirective; +class FrameSourceDirective; struct SerializedDirective; }