diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index 59dd047e3cd..9e38dc875f8 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -45,6 +45,7 @@ set(SOURCES ContentSecurityPolicy/Directives/ImageSourceDirective.cpp ContentSecurityPolicy/Directives/KeywordSources.cpp ContentSecurityPolicy/Directives/ManifestSourceDirective.cpp + ContentSecurityPolicy/Directives/MediaSourceDirective.cpp ContentSecurityPolicy/Directives/Names.cpp ContentSecurityPolicy/Directives/SerializedDirective.cpp ContentSecurityPolicy/Directives/SourceExpression.cpp diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp b/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp index 3ff78e8e4d7..1492062edd9 100644 --- a/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveFactory.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include namespace Web::ContentSecurityPolicy::Directives { @@ -33,6 +34,9 @@ GC::Ref create_directive(GC::Heap& heap, String name, Vector if (name == Names::ManifestSrc) return heap.allocate(move(name), move(value)); + if (name == Names::MediaSrc) + return heap.allocate(move(name), move(value)); + return heap.allocate(move(name), move(value)); } diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/MediaSourceDirective.cpp b/Libraries/LibWeb/ContentSecurityPolicy/Directives/MediaSourceDirective.cpp new file mode 100644 index 00000000000..60e085754cf --- /dev/null +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/MediaSourceDirective.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(MediaSourceDirective); + +MediaSourceDirective::MediaSourceDirective(String name, Vector value) + : Directive(move(name), move(value)) +{ +} + +// https://w3c.github.io/webappsec-csp/#media-src-pre-request +Directive::Result MediaSourceDirective::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, media-src and policy is "No", + // return "Allowed". + if (should_fetch_directive_execute(name, Names::MediaSrc, 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/#media-src-post-request +Directive::Result MediaSourceDirective::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, media-src and policy is "No", + // return "Allowed". + if (should_fetch_directive_execute(name, Names::MediaSrc, 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/MediaSourceDirective.h b/Libraries/LibWeb/ContentSecurityPolicy/Directives/MediaSourceDirective.h new file mode 100644 index 00000000000..50273691d28 --- /dev/null +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/MediaSourceDirective.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-media-src +class MediaSourceDirective final : public Directive { + GC_CELL(MediaSourceDirective, Directive) + GC_DECLARE_ALLOCATOR(MediaSourceDirective); + +public: + virtual ~MediaSourceDirective() = 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: + MediaSourceDirective(String name, Vector value); +}; + +} diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h index be2516dec29..4dddc9d1ac7 100644 --- a/Libraries/LibWeb/Forward.h +++ b/Libraries/LibWeb/Forward.h @@ -136,6 +136,7 @@ class FontSourceDirective; class FrameSourceDirective; class ImageSourceDirective; class ManifestSourceDirective; +class MediaSourceDirective; struct SerializedDirective; }