LibWeb/CSP: Implement SecurityPolicyViolationEvent

This is used to report violations of policies to the element/global
object that caused it.
This commit is contained in:
Luke Wilde 2024-11-26 15:43:02 +00:00 committed by Alexander Kalenik
commit 02236be737
Notes: github-actions[bot] 2025-03-18 23:56:31 +00:00
9 changed files with 168 additions and 0 deletions

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2025, Luke Wilde <luke@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Bindings/SecurityPolicyViolationEventPrototype.h>
#include <LibWeb/ContentSecurityPolicy/SecurityPolicyViolationEvent.h>
namespace Web::ContentSecurityPolicy {
GC_DEFINE_ALLOCATOR(SecurityPolicyViolationEvent);
GC::Ref<SecurityPolicyViolationEvent> SecurityPolicyViolationEvent::create(JS::Realm& realm, FlyString const& event_name, SecurityPolicyViolationEventInit const& event_init)
{
return realm.create<SecurityPolicyViolationEvent>(realm, event_name, event_init);
}
WebIDL::ExceptionOr<GC::Ref<SecurityPolicyViolationEvent>> SecurityPolicyViolationEvent::construct_impl(JS::Realm& realm, FlyString const& event_name, SecurityPolicyViolationEventInit const& event_init)
{
return realm.create<SecurityPolicyViolationEvent>(realm, event_name, event_init);
}
SecurityPolicyViolationEvent::SecurityPolicyViolationEvent(JS::Realm& realm, FlyString const& event_name, SecurityPolicyViolationEventInit const& event_init)
: Event(realm, event_name, event_init)
, m_document_uri(event_init.document_uri)
, m_referrer(event_init.referrer)
, m_blocked_uri(event_init.blocked_uri)
, m_violated_directive(event_init.violated_directive)
, m_effective_directive(event_init.effective_directive)
, m_original_policy(event_init.original_policy)
, m_source_file(event_init.source_file)
, m_sample(event_init.sample)
, m_disposition(event_init.disposition)
, m_status_code(event_init.status_code)
, m_line_number(event_init.line_number)
, m_column_number(event_init.column_number)
{
}
SecurityPolicyViolationEvent::~SecurityPolicyViolationEvent() = default;
void SecurityPolicyViolationEvent::initialize(JS::Realm& realm)
{
Base::initialize(realm);
WEB_SET_PROTOTYPE_FOR_INTERFACE(SecurityPolicyViolationEvent);
}
}

View file

@ -0,0 +1,71 @@
/*
* Copyright (c) 2025, Luke Wilde <luke@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibWeb/Bindings/SecurityPolicyViolationEventPrototype.h>
#include <LibWeb/DOM/Event.h>
namespace Web::ContentSecurityPolicy {
struct SecurityPolicyViolationEventInit final : public DOM::EventInit {
String document_uri;
String referrer;
String blocked_uri;
String violated_directive;
String effective_directive;
String original_policy;
String source_file;
String sample;
Bindings::SecurityPolicyViolationEventDisposition disposition { Bindings::SecurityPolicyViolationEventDisposition::Enforce };
u16 status_code { 0 };
u32 line_number { 0 };
u32 column_number { 0 };
};
class SecurityPolicyViolationEvent final : public DOM::Event {
WEB_PLATFORM_OBJECT(SecurityPolicyViolationEvent, DOM::Event);
GC_DECLARE_ALLOCATOR(SecurityPolicyViolationEvent);
public:
[[nodiscard]] static GC::Ref<SecurityPolicyViolationEvent> create(JS::Realm&, FlyString const& event_name, SecurityPolicyViolationEventInit const& = {});
static WebIDL::ExceptionOr<GC::Ref<SecurityPolicyViolationEvent>> construct_impl(JS::Realm&, FlyString const& event_name, SecurityPolicyViolationEventInit const& event_init);
virtual ~SecurityPolicyViolationEvent() override;
String const& document_uri() const { return m_document_uri; }
String const& referrer() const { return m_referrer; }
String const& blocked_uri() const { return m_blocked_uri; }
String const& violated_directive() const { return m_violated_directive; }
String const& effective_directive() const { return m_effective_directive; }
String const& original_policy() const { return m_original_policy; }
String const& source_file() const { return m_source_file; }
String const& sample() const { return m_sample; }
Bindings::SecurityPolicyViolationEventDisposition disposition() const { return m_disposition; }
u16 status_code() const { return m_status_code; }
u32 line_number() const { return m_line_number; }
u32 column_number() const { return m_column_number; }
private:
SecurityPolicyViolationEvent(JS::Realm&, FlyString const& event_name, SecurityPolicyViolationEventInit const&);
virtual void initialize(JS::Realm&) override;
String m_document_uri;
String m_referrer;
String m_blocked_uri;
String m_violated_directive;
String m_effective_directive;
String m_original_policy;
String m_source_file;
String m_sample;
Bindings::SecurityPolicyViolationEventDisposition m_disposition { Bindings::SecurityPolicyViolationEventDisposition::Enforce };
u16 m_status_code { 0 };
u32 m_line_number { 0 };
u32 m_column_number { 0 };
};
}

View file

@ -0,0 +1,40 @@
#import <DOM/Event.idl>
// https://w3c.github.io/webappsec-csp/#enumdef-securitypolicyviolationeventdisposition
enum SecurityPolicyViolationEventDisposition {
"enforce",
"report"
};
// https://w3c.github.io/webappsec-csp/#securitypolicyviolationevent
[Exposed=(Window,Worker)]
interface SecurityPolicyViolationEvent : Event {
constructor(DOMString type, optional SecurityPolicyViolationEventInit eventInitDict = {});
readonly attribute USVString documentURI;
readonly attribute USVString referrer;
readonly attribute USVString blockedURI;
readonly attribute DOMString effectiveDirective;
readonly attribute DOMString violatedDirective; // historical alias of effectiveDirective
readonly attribute DOMString originalPolicy;
readonly attribute USVString sourceFile;
readonly attribute DOMString sample;
readonly attribute SecurityPolicyViolationEventDisposition disposition;
readonly attribute unsigned short statusCode;
readonly attribute unsigned long lineNumber;
readonly attribute unsigned long columnNumber;
};
dictionary SecurityPolicyViolationEventInit : EventInit {
USVString documentURI = "";
USVString referrer = "";
USVString blockedURI = "";
DOMString violatedDirective = "";
DOMString effectiveDirective = "";
DOMString originalPolicy = "";
USVString sourceFile = "";
DOMString sample = "";
SecurityPolicyViolationEventDisposition disposition = "enforce";
unsigned short statusCode = 0;
unsigned long lineNumber = 0;
unsigned long columnNumber = 0;
};