mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Fix cookie exclusion for fetch CORS pre-flight requests (fixes #3596)
Cookies (and other credentials) will be excluded when appropriate by downgrading |credentials_mode| from kSameOrigin to kOmit. Improve logic for Origin header inclusion, including a fix for Referrer/Origin calculation in URLRequestJob::ComputeReferrerForPolicy when used with custom standard schemes. Specify correct CookiePartitionKeyCollection when loading cookies. To test: - Run tests from https://browseraudit.com/ with and without `--disable-request-handling-for-testing`. Results are the same. - Run `ceftests --gtest_filter=CorsTest.*`.
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/resource_context.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/common/referrer.h"
|
||||
#include "mojo/public/cpp/base/big_buffer.h"
|
||||
#include "mojo/public/cpp/bindings/receiver.h"
|
||||
#include "net/http/http_status_code.h"
|
||||
@@ -30,6 +31,7 @@
|
||||
#include "services/network/public/cpp/cors/cors.h"
|
||||
#include "services/network/public/cpp/features.h"
|
||||
#include "services/network/public/mojom/early_hints.mojom.h"
|
||||
#include "third_party/blink/public/common/loader/referrer_utils.h"
|
||||
|
||||
namespace net_service {
|
||||
|
||||
@@ -65,6 +67,21 @@ bool DisableRequestHandlingForTesting() {
|
||||
return disabled;
|
||||
}
|
||||
|
||||
// Match logic in devtools_url_loader_interceptor.cc
|
||||
// InterceptionJob::CalculateResponseTainting.
|
||||
network::mojom::FetchResponseType CalculateResponseTainting(
|
||||
bool should_check_cors,
|
||||
network::mojom::RequestMode mode,
|
||||
bool tainted_origin) {
|
||||
if (should_check_cors) {
|
||||
return network::mojom::FetchResponseType::kCors;
|
||||
}
|
||||
if (mode == network::mojom::RequestMode::kNoCors && tainted_origin) {
|
||||
return network::mojom::FetchResponseType::kOpaque;
|
||||
}
|
||||
return network::mojom::FetchResponseType::kBasic;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Owns all of the ProxyURLLoaderFactorys for a given BrowserContext. Since
|
||||
@@ -451,25 +468,71 @@ void InterceptedRequest::Restart() {
|
||||
current_request_uses_header_client_ =
|
||||
factory_->url_loader_header_client_receiver_.is_bound();
|
||||
|
||||
if (request_.request_initiator &&
|
||||
network::cors::ShouldCheckCors(request_.url, request_.request_initiator,
|
||||
request_.mode)) {
|
||||
if (scheme::IsCorsEnabledScheme(request_.url.scheme())) {
|
||||
// Add the Origin header for CORS-enabled scheme requests.
|
||||
request_.headers.SetHeaderIfMissing(
|
||||
net::HttpRequestHeaders::kOrigin,
|
||||
request_.request_initiator->Serialize());
|
||||
} else if (!HasCrossOriginWhitelistEntry(
|
||||
*request_.request_initiator,
|
||||
url::Origin::Create(request_.url))) {
|
||||
// Fail requests if a CORS check is required and the scheme is not CORS
|
||||
// enabled. This matches the error condition that would be generated by
|
||||
// CorsURLLoader::StartRequest in the network process.
|
||||
SendErrorStatusAndCompleteImmediately(
|
||||
network::URLLoaderCompletionStatus(network::CorsErrorStatus(
|
||||
network::mojom::CorsError::kCorsDisabledScheme)));
|
||||
return;
|
||||
const bool is_cross_origin =
|
||||
request_.request_initiator &&
|
||||
!request_.request_initiator->IsSameOriginWith(request_.url);
|
||||
const bool is_cors_enabled_scheme =
|
||||
scheme::IsCorsEnabledScheme(request_.url.scheme());
|
||||
|
||||
// Match logic in network::cors::ShouldCheckCors.
|
||||
bool should_check_cors =
|
||||
is_cross_origin &&
|
||||
request_.mode != network::mojom::RequestMode::kNavigate &&
|
||||
request_.mode != network::mojom::RequestMode::kNoCors;
|
||||
|
||||
if (should_check_cors && !is_cors_enabled_scheme &&
|
||||
!HasCrossOriginWhitelistEntry(*request_.request_initiator,
|
||||
url::Origin::Create(request_.url))) {
|
||||
// Fail requests if a CORS check is required and the scheme is not CORS
|
||||
// enabled. This matches the error condition that would be generated by
|
||||
// CorsURLLoader::StartRequest in the network process.
|
||||
SendErrorStatusAndCompleteImmediately(
|
||||
network::URLLoaderCompletionStatus(network::CorsErrorStatus(
|
||||
network::mojom::CorsError::kCorsDisabledScheme)));
|
||||
return;
|
||||
}
|
||||
|
||||
// Maybe update |credentials_mode| for fetch requests.
|
||||
if (request_.credentials_mode ==
|
||||
network::mojom::CredentialsMode::kSameOrigin) {
|
||||
// Match logic in devtools_url_loader_interceptor.cc
|
||||
// InterceptionJob::FollowRedirect.
|
||||
bool tainted_origin = false;
|
||||
if (redirect_in_progress_ && request_.request_initiator &&
|
||||
!url::IsSameOriginWith(request_.url, original_url_) &&
|
||||
!request_.request_initiator->IsSameOriginWith(original_url_)) {
|
||||
tainted_origin = true;
|
||||
}
|
||||
|
||||
// Match logic in CorsURLLoader::StartNetworkRequest.
|
||||
const auto response_tainting = CalculateResponseTainting(
|
||||
should_check_cors, request_.mode, tainted_origin);
|
||||
request_.credentials_mode =
|
||||
network::cors::CalculateCredentialsFlag(request_.credentials_mode,
|
||||
response_tainting)
|
||||
? network::mojom::CredentialsMode::kInclude
|
||||
: network::mojom::CredentialsMode::kOmit;
|
||||
}
|
||||
|
||||
const bool should_add_origin_header =
|
||||
// Cross-origin requests that are not kNavigate nor kNoCors.
|
||||
should_check_cors ||
|
||||
// Same-origin requests except for GET and HEAD.
|
||||
(!is_cross_origin &&
|
||||
request_.method != net::HttpRequestHeaders::kGetMethod &&
|
||||
request_.method != net::HttpRequestHeaders::kHeadMethod);
|
||||
|
||||
if (should_add_origin_header) {
|
||||
// Match logic in navigation_request.cc AddAdditionalRequestHeaders.
|
||||
url::Origin origin_header_value =
|
||||
request_.request_initiator.value_or(url::Origin());
|
||||
origin_header_value = content::Referrer::SanitizeOriginForRequest(
|
||||
request_.url, origin_header_value,
|
||||
blink::ReferrerUtils::NetToMojoReferrerPolicy(
|
||||
request_.referrer_policy));
|
||||
|
||||
request_.headers.SetHeaderIfMissing(net::HttpRequestHeaders::kOrigin,
|
||||
origin_header_value.Serialize());
|
||||
}
|
||||
|
||||
const GURL original_url = request_.url;
|
||||
|
Reference in New Issue
Block a user