1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/frame/integrity_policy.h"
#include "base/containers/contains.h"
#include "services/network/public/cpp/integrity_policy.h"
#include "services/network/public/cpp/request_destination.h"
#include "services/network/public/mojom/integrity_algorithm.mojom-blink.h"
#include "services/network/public/mojom/integrity_policy.mojom-blink.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/integrity_violation_report_body.h"
#include "third_party/blink/renderer/core/frame/policy_container.h"
#include "third_party/blink/renderer/core/frame/report.h"
#include "third_party/blink/renderer/core/frame/reporting_context.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
namespace blink {
namespace {
Vector<String> ConvertToBlink(const std::vector<std::string>& in) {
Vector<String> out;
for (const std::string& str : in) {
out.push_back(String::FromUTF8(str));
}
return out;
}
void SendReport(ExecutionContext* context,
Vector<String> report_endpoints,
const KURL& blocked_url,
const String& destination,
bool report_only) {
const SecurityOrigin* origin = context->GetSecurityOrigin();
const KURL& document_url = context->Url();
String safe_document_url = ContentSecurityPolicy::StripURLForUseInReport(
origin, document_url, CSPDirectiveName::Unknown);
String safe_blocked_url = ContentSecurityPolicy::StripURLForUseInReport(
origin, blocked_url, CSPDirectiveName::Unknown);
auto* body = MakeGarbageCollected<IntegrityViolationReportBody>(
safe_document_url, safe_blocked_url, destination, report_only);
Report* observed_report = MakeGarbageCollected<Report>(
ReportType::kIntegrityViolation, safe_document_url, body);
ReportingContext::From(context)->QueueReport(observed_report,
std::move(report_endpoints));
}
bool ShouldBlockOrReport(const network::IntegrityPolicy& integrity_policy) {
return (base::Contains(
integrity_policy.blocked_destinations,
::network::mojom::blink::IntegrityPolicy::Destination::kScript) &&
base::Contains(
integrity_policy.sources,
::network::mojom::blink::IntegrityPolicy::Source::kInline));
}
} // namespace
// static
bool IntegrityPolicy::AllowRequest(
ExecutionContext* context,
const DOMWrapperWorld* world,
network::mojom::RequestDestination request_destination,
network::mojom::RequestMode request_mode,
const IntegrityMetadataSet& integrity_metadata,
const KURL& url) {
if (!context) {
return true;
}
if (world && world->IsIsolatedWorld()) {
return true;
}
if ((!integrity_metadata.empty() &&
request_mode != network::mojom::RequestMode::kNoCors) ||
url.ProtocolIsData() || url.ProtocolIs("blob")) {
return true;
}
PolicyContainer* policy_container = context->GetPolicyContainer();
if (!policy_container) {
return true;
}
const network::IntegrityPolicy& integrity_policy =
policy_container->GetPolicies().integrity_policy;
const network::IntegrityPolicy& integrity_policy_report_only =
policy_container->GetPolicies().integrity_policy_report_only;
bool allow = true;
if (request_destination == network::mojom::RequestDestination::kScript) {
if (ShouldBlockOrReport(integrity_policy)) {
allow = false;
SendReport(
context, ConvertToBlink(integrity_policy.endpoints), url,
String(network::RequestDestinationToString(request_destination)),
/*report_only=*/false);
}
if (ShouldBlockOrReport(integrity_policy_report_only)) {
SendReport(
context, ConvertToBlink(integrity_policy_report_only.endpoints), url,
String(network::RequestDestinationToString(request_destination)),
/*report_only=*/true);
}
}
return allow;
}
void IntegrityPolicy::LogParsingErrorsIfAny(
ExecutionContext* context,
const network::IntegrityPolicy& policy) {
for (const std::string& error : policy.parsing_errors) {
context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::blink::ConsoleMessageSource::kSecurity,
mojom::blink::ConsoleMessageLevel::kError, String(error)));
}
}
} // namespace blink
|