From f9247116b136ada4f6b93b5a98f02be7a871b42c Mon Sep 17 00:00:00 2001 From: Luke Wilde Date: Wed, 4 Dec 2024 11:24:19 +0000 Subject: [PATCH] LibWeb/CSP: Implement the form-action directive --- Libraries/LibWeb/CMakeLists.txt | 1 + .../Directives/DirectiveFactory.cpp | 4 ++ .../Directives/FormActionDirective.cpp | 38 +++++++++++++++++++ .../Directives/FormActionDirective.h | 27 +++++++++++++ Libraries/LibWeb/Forward.h | 1 + 5 files changed, 71 insertions(+) create mode 100644 Libraries/LibWeb/ContentSecurityPolicy/Directives/FormActionDirective.cpp create mode 100644 Libraries/LibWeb/ContentSecurityPolicy/Directives/FormActionDirective.h diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index 8c94976c276..174cb9a12b3 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -50,6 +50,7 @@ set(SOURCES ContentSecurityPolicy/Directives/DirectiveFactory.cpp ContentSecurityPolicy/Directives/DirectiveOperations.cpp ContentSecurityPolicy/Directives/FontSourceDirective.cpp + ContentSecurityPolicy/Directives/FormActionDirective.cpp ContentSecurityPolicy/Directives/FrameSourceDirective.cpp ContentSecurityPolicy/Directives/ImageSourceDirective.cpp ContentSecurityPolicy/Directives/KeywordSources.cpp diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp b/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp index 757568ef065..3501f79a5c6 100644 --- a/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,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::FormAction) + return heap.allocate(move(name), move(value)); + if (name == Names::FrameSrc) return heap.allocate(move(name), move(value)); diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/FormActionDirective.cpp b/Libraries/LibWeb/ContentSecurityPolicy/Directives/FormActionDirective.cpp new file mode 100644 index 00000000000..9180065e3d9 --- /dev/null +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/FormActionDirective.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024, Luke Wilde + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +namespace Web::ContentSecurityPolicy::Directives { + +GC_DEFINE_ALLOCATOR(FormActionDirective); + +FormActionDirective::FormActionDirective(String name, Vector value) + : Directive(move(name), move(value)) +{ +} + +Directive::Result FormActionDirective::pre_navigation_check(GC::Ref request, NavigationType navigation_type, GC::Ref policy) const +{ + // 1. Assert: policy is unused in this algorithm. + // FIXME: File spec issue, because this is not the case. The policy is required to resolve 'self'. + + // 2. If navigation type is "form-submission": + if (navigation_type == NavigationType::FormSubmission) { + // 1. If the result of executing § 6.7.2.5 Does request match source list? on request, this directive’s value, + // and a policy, is "Does Not Match", return "Blocked". + if (does_request_match_source_list(request, value(), policy) == MatchResult::DoesNotMatch) + return Result::Blocked; + } + + // 3. Return "Allowed". + return Result::Allowed; +} + +} diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/FormActionDirective.h b/Libraries/LibWeb/ContentSecurityPolicy/Directives/FormActionDirective.h new file mode 100644 index 00000000000..44eec17a3e8 --- /dev/null +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/FormActionDirective.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-form-action +class FormActionDirective final : public Directive { + GC_CELL(FormActionDirective, Directive) + GC_DECLARE_ALLOCATOR(FormActionDirective); + +public: + virtual ~FormActionDirective() = default; + + virtual Result pre_navigation_check(GC::Ref, NavigationType, GC::Ref) const override; + +private: + FormActionDirective(String name, Vector value); +}; + +} diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h index b3c585d3489..6b95693ef9f 100644 --- a/Libraries/LibWeb/Forward.h +++ b/Libraries/LibWeb/Forward.h @@ -141,6 +141,7 @@ class ConnectSourceDirective; class DefaultSourceDirective; class Directive; class FontSourceDirective; +class FormActionDirective; class FrameSourceDirective; class ImageSourceDirective; class ManifestSourceDirective;