ladybird/Libraries/LibWeb/ContentSecurityPolicy/Policy.h

94 lines
3.9 KiB
C
Raw Normal View History

/*
* Copyright (c) 2025, Luke Wilde <luke@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibGC/Ptr.h>
#include <LibURL/Origin.h>
#include <LibWeb/ContentSecurityPolicy/Directives/Directive.h>
#include <LibWeb/Forward.h>
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<Policy> parse_a_serialized_csp(GC::Heap&, Variant<ByteBuffer, String> serialized, Source source, Disposition disposition);
[[nodiscard]] static GC::Ref<PolicyList> parse_a_responses_content_security_policies(GC::Heap&, GC::Ref<Fetch::Infrastructure::Response const> response);
[[nodiscard]] static GC::Ref<Policy> create_from_serialized_policy(GC::Heap&, SerializedPolicy const&);
[[nodiscard]] Vector<GC::Ref<Directives::Directive>> 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.value(); }
[[nodiscard]] String const& pre_parsed_policy_string(Badge<Violation>) const { return m_pre_parsed_policy_string; }
[[nodiscard]] bool contains_directive_with_name(StringView name) const;
[[nodiscard]] GC::Ptr<Directives::Directive> get_directive_by_name(StringView) const;
[[nodiscard]] GC::Ref<Policy> clone(GC::Heap&) const;
[[nodiscard]] SerializedPolicy serialize() const;
void remove_directive(Badge<HTML::HTMLMetaElement>, FlyString const& name);
void set_self_origin(Badge<HTML::HTMLMetaElement>, 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 policys
// implications when applied.
Vector<GC::Ref<Directives::Directive>> 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
// objects origin.
Optional<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;
};
}