/* * Copyright (c) 2025, Luke Wilde * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include namespace Web::ContentSecurityPolicy { #define ENUMERATE_DISPOSITION_TYPES \ __ENUMERATE_DISPOSITION_TYPE(Enforce, "enforce") \ __ENUMERATE_DISPOSITION_TYPE(Report, "report") // https://w3c.github.io/webappsec-csp/#content-security-policy-object // A policy defines allowed and restricted behaviors, and may be applied to a Document, WorkerGlobalScope, // or WorkletGlobalScope. class Policy final : public GC::Cell { GC_CELL(Policy, GC::Cell); GC_DECLARE_ALLOCATOR(Policy); public: enum class Disposition { #define __ENUMERATE_DISPOSITION_TYPE(type, _) type, ENUMERATE_DISPOSITION_TYPES #undef __ENUMERATE_DISPOSITION_TYPE }; enum class Source { Header, Meta, }; ~Policy() = default; [[nodiscard]] static GC::Ref parse_a_serialized_csp(GC::Heap&, Variant serialized, Source source, Disposition disposition); [[nodiscard]] static GC::Ref parse_a_responses_content_security_policies(GC::Heap&, GC::Ref response); [[nodiscard]] static GC::Ref create_from_serialized_policy(GC::Heap&, SerializedPolicy const&); [[nodiscard]] Vector> const& directives() const { return m_directives; } [[nodiscard]] Disposition disposition() const { return m_disposition; } [[nodiscard]] Source source() const { return m_source; } [[nodiscard]] URL::Origin const& self_origin() const { return m_self_origin; } [[nodiscard]] String const& pre_parsed_policy_string(Badge) const { return m_pre_parsed_policy_string; } [[nodiscard]] bool contains_directive_with_name(StringView name) const; [[nodiscard]] GC::Ptr get_directive_by_name(StringView) const; [[nodiscard]] GC::Ref clone(GC::Heap&) const; [[nodiscard]] SerializedPolicy serialize() const; void remove_directive(Badge, FlyString const& name); void set_self_origin(Badge, URL::Origin const& origin); protected: virtual void visit_edges(Cell::Visitor&) override; private: Policy() = default; // https://w3c.github.io/webappsec-csp/#policy-directive-set // Each policy has an associated directive set, which is an ordered set of directives that define the policy’s // implications when applied. Vector> m_directives; // https://w3c.github.io/webappsec-csp/#policy-disposition // Each policy has an associated disposition, which is either "enforce" or "report". Disposition m_disposition { Disposition::Enforce }; // https://w3c.github.io/webappsec-csp/#policy-source // Each policy has an associated source, which is either "header" or "meta". Source m_source { Source::Header }; // https://w3c.github.io/webappsec-csp/#policy-self-origin // Each policy has an associated self-origin, which is an origin that is used when matching the 'self' keyword. // Spec Note: This is needed to facilitate the 'self' checks of local scheme documents/workers that have inherited // their policy but have an opaque origin. Most of the time this will simply be the environment settings // object’s origin. URL::Origin m_self_origin; // This is used for reporting which policy was violated. It's not exactly specified, only linking to an ABNF grammar // definition. WebKit and Blink return the original string that was parsed, whereas Firefox seems to try and return // a nice serialization of what it parsed. For simplicity and wider compatibility, we follow what WebKit and Blink // do. String m_pre_parsed_policy_string; }; }