mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-23 00:19:18 +00:00
LibWeb: Enforce Integrity Policy on Fetch requests
This commit is contained in:
parent
ec051bdec2
commit
1228063a85
Notes:
github-actions[bot]
2025-08-14 12:38:53 +00:00
Author: https://github.com/kennethmyhra
Commit: 1228063a85
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5772
Reviewed-by: https://github.com/AtkinsSJ
Reviewed-by: https://github.com/Lubrsi ✅
5 changed files with 88 additions and 4 deletions
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Luke Wilde <luke@ladybird.org>
|
||||
* Copyright (c) 2025, Kenneth Myhra <kennethmyhra@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -14,8 +15,11 @@
|
|||
#include <LibWeb/DOM/Element.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/HTTP/Requests.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/HTTP/Responses.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/URL.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
#include <LibWeb/HTML/WorkerGlobalScope.h>
|
||||
#include <LibWeb/Infra/Strings.h>
|
||||
#include <LibWeb/SRI/SRI.h>
|
||||
#include <LibWeb/WebAssembly/WebAssembly.h>
|
||||
|
||||
namespace Web::ContentSecurityPolicy {
|
||||
|
@ -131,6 +135,66 @@ Directives::Directive::Result should_request_be_blocked_by_content_security_poli
|
|||
return result;
|
||||
}
|
||||
|
||||
// https://w3c.github.io/webappsec-subresource-integrity/#should-request-be-blocked-by-integrity-policy
|
||||
Directives::Directive::Result should_request_be_blocked_by_integrity_policy(GC::Ref<Fetch::Infrastructure::Request> request)
|
||||
{
|
||||
VERIFY(request->policy_container().has<GC::Ref<HTML::PolicyContainer>>());
|
||||
|
||||
// 1. Let policyContainer be request’s policy container.
|
||||
auto const& policy_container = request->policy_container().get<GC::Ref<HTML::PolicyContainer>>();
|
||||
|
||||
// 2. Let parsedMetadata be the result of calling parse metadata with request’s integrity metadata.
|
||||
auto parsed_metadata = MUST(SRI::parse_metadata(request->integrity_metadata()));
|
||||
|
||||
// 3. If parsedMetadata is not the empty set and request’s mode is either "cors" or "same-origin", return "Allowed".
|
||||
if (!parsed_metadata.is_empty() && (request->mode() == Fetch::Infrastructure::Request::Mode::CORS || request->mode() == Fetch::Infrastructure::Request::Mode::SameOrigin))
|
||||
return Directives::Directive::Result::Allowed;
|
||||
|
||||
// 4. If request’s url is local, return "Allowed".
|
||||
if (Fetch::Infrastructure::is_local_url(request->url()))
|
||||
return Directives::Directive::Result::Allowed;
|
||||
|
||||
// 5. Let policy be policyContainer’s integrity policy.
|
||||
auto const& policy = policy_container->integrity_policy;
|
||||
|
||||
// 6. Let reportPolicy be policyContainer’s report only integrity policy.
|
||||
auto const& report_policy = policy_container->report_only_integrity_policy;
|
||||
|
||||
// 7. If both policy and reportPolicy are empty integrity policys, return "Allowed".
|
||||
if (policy.is_empty() && report_policy.is_empty())
|
||||
return Directives::Directive::Result::Allowed;
|
||||
|
||||
// 8. Let global be request’s client’s global object.
|
||||
auto& global = request->client()->global_object();
|
||||
|
||||
// 9. If global is not a Window nor a WorkerGlobalScope, return "Allowed".
|
||||
if (!is<HTML::Window>(global) && !is<HTML::WorkerGlobalScope>(global))
|
||||
return Directives::Directive::Result::Allowed;
|
||||
|
||||
// 10. Let block be a boolean, initially false.
|
||||
bool block = false;
|
||||
|
||||
// FIXME: 11. Let reportBlock be a boolean, initially false.
|
||||
[[maybe_unused]] auto report_block = false;
|
||||
|
||||
// 12. If policy’s sources contains "inline" and policy’s blocked destinations contains request’s destination, set block to true.
|
||||
if (policy.sources.contains_slow("inline"sv)
|
||||
&& request->destination().has_value()
|
||||
&& policy.blocked_destinations.contains_slow(request->destination().value()))
|
||||
block = true;
|
||||
|
||||
// 13. If reportPolicy’s sources contains "inline" and reportPolicy’s blocked destinations contains request’s destination, set reportBlock to true.
|
||||
if (report_policy.sources.contains_slow("inline"sv)
|
||||
&& request->destination().has_value()
|
||||
&& report_policy.blocked_destinations.contains_slow(request->destination().value()))
|
||||
report_block = true;
|
||||
|
||||
// FIXME: 14. If block is true or reportBlock is true, then report violation with request, block, reportBlock, policy and reportPolicy.
|
||||
|
||||
// 15. If block is true, then return "Blocked"; otherwise "Allowed".
|
||||
return block ? Directives::Directive::Result::Blocked : Directives::Directive::Result::Allowed;
|
||||
}
|
||||
|
||||
// https://w3c.github.io/webappsec-csp/#should-block-response
|
||||
Directives::Directive::Result should_response_to_request_be_blocked_by_content_security_policy(JS::Realm& realm, GC::Ref<Fetch::Infrastructure::Response> response, GC::Ref<Fetch::Infrastructure::Request> request)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue