diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index 9e38dc875f8..8d9dfe8d492 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -47,6 +47,7 @@ set(SOURCES ContentSecurityPolicy/Directives/ManifestSourceDirective.cpp ContentSecurityPolicy/Directives/MediaSourceDirective.cpp ContentSecurityPolicy/Directives/Names.cpp + ContentSecurityPolicy/Directives/ObjectSourceDirective.cpp ContentSecurityPolicy/Directives/SerializedDirective.cpp ContentSecurityPolicy/Directives/SourceExpression.cpp ContentSecurityPolicy/Policy.cpp diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp b/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp index 1492062edd9..9c344ff5255 100644 --- a/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace Web::ContentSecurityPolicy::Directives { @@ -37,6 +38,9 @@ GC::Ref create_directive(GC::Heap& heap, String name, Vector if (name == Names::MediaSrc) return heap.allocate(move(name), move(value)); + if (name == Names::ObjectSrc) + return heap.allocate(move(name), move(value)); + return heap.allocate(move(name), move(value)); } diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/ObjectSourceDirective.cpp b/Libraries/LibWeb/ContentSecurityPolicy/Directives/ObjectSourceDirective.cpp new file mode 100644 index 00000000000..4eab075ed72 --- /dev/null +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/ObjectSourceDirective.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(ObjectSourceDirective); + +ObjectSourceDirective::ObjectSourceDirective(String name, Vector value) + : Directive(move(name), move(value)) +{ +} + +// https://w3c.github.io/webappsec-csp/#object-src-pre-request +Directive::Result ObjectSourceDirective::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, object-src and policy is "No", + // return "Allowed". + if (should_fetch_directive_execute(name, Names::ObjectSrc, 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/#object-src-post-request +Directive::Result ObjectSourceDirective::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, object-src and policy is "No", + // return "Allowed". + if (should_fetch_directive_execute(name, Names::ObjectSrc, 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/ObjectSourceDirective.h b/Libraries/LibWeb/ContentSecurityPolicy/Directives/ObjectSourceDirective.h new file mode 100644 index 00000000000..a97314cd9b1 --- /dev/null +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/ObjectSourceDirective.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-object-src +class ObjectSourceDirective final : public Directive { + GC_CELL(ObjectSourceDirective, Directive) + GC_DECLARE_ALLOCATOR(ObjectSourceDirective); + +public: + virtual ~ObjectSourceDirective() = 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; + +private: + ObjectSourceDirective(String name, Vector value); +}; + +} diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h index 4dddc9d1ac7..b5e7d46cf08 100644 --- a/Libraries/LibWeb/Forward.h +++ b/Libraries/LibWeb/Forward.h @@ -137,6 +137,7 @@ class FrameSourceDirective; class ImageSourceDirective; class ManifestSourceDirective; class MediaSourceDirective; +class ObjectSourceDirective; struct SerializedDirective; }