Commit c1b6d6a2 authored by Yutaka Hirano's avatar Yutaka Hirano Committed by Commit Bot

Remove per-client CORS checks

Those are needed because a request could match with another request made
by a foreign origin, but [1] fixed the issue. This is basically reverting
[2]. Two layout tests are added to detect regressions.

This CL changes the behavior a bit. Without this CL,

 - A response with a proper access-control-allow-origin header for a
   cross-origin request with "no-cors" mode is treated as
   non-opaque, and
 - A response without a proper access-control-allow-origin header for a
   same-origin request with "no-cors" mode redirected from a cross-origin
   resource is treated as opaque

while with this CL,

 - A response with a proper access-control-allow-origin header for a
   cross-origin request with "no-cors" mode is treated as opaque, and
 - A response without a proper access-control-allow-origin header for a
   same-origin request with "no-cors" mode redirected from a cross-origin
   resource is treated as non-opaque.

Also, before this CL, CORSStatus is calculated with an opaque origin for
top-level worklet scripts. This CL changes that: now CORSStatus is
calculated with the origin of the parent context, and so it stops muting
error messages in worklets.

1: https://chromium.googlesource.com/chromium/src.git/+/c1df004861ab704945d31a0d207bb7f4c205e60c
2: https://chromium.googlesource.com/chromium/src.git/+/fad67a5b73639d7211b24fd9bdb242e82039b765

Bug: 809350, 799477
Change-Id: If28f59f6e6ac03a4d5992cca85801231748019bd
Reviewed-on: https://chromium-review.googlesource.com/1158165
Commit-Queue: Yutaka Hirano <yhirano@chromium.org>
Reviewed-by: default avatarHiroshige Hayashizaki <hiroshige@chromium.org>
Reviewed-by: default avatarFredrik Söderquist <fs@opera.com>
Reviewed-by: default avatarKouhei Ueno <kouhei@chromium.org>
Reviewed-by: default avatarTakashi Toyoshima <toyoshim@chromium.org>
Cr-Commit-Position: refs/heads/master@{#583202}
parent f4694086
<!doctype html>
<html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<img src="http://localhost:8080/security/resources/cors-image.php?max-age=60" crossorigin></img>
<script>
async_test((test) => {
document.querySelector('img').addEventListener('load', () => {
const iframe = document.createElement('iframe');
iframe.sandbox = 'allow-scripts';
iframe.src = 'resources/cors-check-for-cached-image-iframe.html';
document.body.appendChild(iframe);
});
window.addEventListener('message', test.step_func_done((e) => {
assert_equals(e.data, 'PASS');
}));
}, 'We should not reuse CORS check result when requested from another origin');
</script>
<!doctype html>
<html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="http://localhost:8080/security/resources/cors-script.php?max-age=60" crossorigin></script>
<script>
async_test((test) => {
window.addEventListener('message', test.step_func_done((e) => {
assert_equals(e.data, 'PASS');
}));
}, 'We should not reuse CORS check result when requested from another origin');
</script>
<iframe sandbox="allow-scripts allow-modals" src="resources/cors-check-for-cached-script-iframe.html"></iframe>
<!doctype html>
<img src="http://localhost:8080/security/resources/cors-image.php?max-age=60" crossorigin
onload="parent.postMessage('FAIL', '*')"
onerror="parent.postMessage('PASS', '*')">
<!doctype html>
<html>
<script src="http://localhost:8080/security/resources/cors-script.php?max-age=60" crossorigin
onload="parent.postMessage('FAIL', '*')"
onerror="parent.postMessage('PASS', '*')"></script>
<?php
$max_age = $_GET['max-age'];
if (!(empty($max_age))) {
header('Cache-Control: max-age=' . $max_age);
}
header("Access-Control-Allow-Origin: http://127.0.0.1:8000");
$name = 'abe.png';
$fp = fopen($name, 'rb');
header("Content-Type: image/png");
header("Content-Length: " . filesize($name));
fpassthru($fp);
exit;
?>
......@@ -8,6 +8,11 @@ if ($cors_arg != 'false') {
}
}
$max_age = $_GET['max-age'];
if (!(empty($max_age))) {
header('Cache-Control: max-age=' . $max_age);
}
if (strtolower($_GET['credentials']) == 'true') {
header('Access-Control-Allow-Credentials: true');
}
......
......@@ -44,8 +44,7 @@ void DocumentModuleScriptFetcher::NotifyFinished(Resource* resource) {
ModuleScriptCreationParams params(
script_resource->GetResponse().Url(), script_resource->SourceText(),
script_resource->GetResourceRequest().GetFetchCredentialsMode(),
script_resource->CalculateAccessControlStatus(
fetcher_->Context().GetSecurityOrigin()));
script_resource->CalculateAccessControlStatus());
client_->NotifyFetchFinished(params, error_messages);
}
......
......@@ -99,8 +99,7 @@ void WorkerModuleScriptFetcher::NotifyFinished(Resource* resource) {
ModuleScriptCreationParams params(
script_resource->GetResponse().Url(), script_resource->SourceText(),
script_resource->GetResourceRequest().GetFetchCredentialsMode(),
script_resource->CalculateAccessControlStatus(
global_scope_->EnsureFetcher()->Context().GetSecurityOrigin()));
script_resource->CalculateAccessControlStatus());
// Step 13.7. "Asynchronously complete the perform the fetch steps with
// response." [spec text]
......
......@@ -51,8 +51,7 @@ void WorkletModuleScriptFetcher::NotifyFinished(Resource* resource) {
params.emplace(
script_resource->GetResponse().Url(), script_resource->SourceText(),
script_resource->GetResourceRequest().GetFetchCredentialsMode(),
script_resource->CalculateAccessControlStatus(
fetcher_->Context().GetSecurityOrigin()));
script_resource->CalculateAccessControlStatus());
}
// This will eventually notify |client| passed to
......
......@@ -669,8 +669,7 @@ bool ImageResource::IsAccessAllowed(
ImageResourceInfo::kHasSingleSecurityOrigin)
return false;
DCHECK(security_origin);
if (PassesAccessControlCheck(*security_origin))
if (IsSameOriginOrCORSSuccessful())
return true;
return security_origin->CanReadContent(GetResponse().Url());
......
......@@ -237,17 +237,12 @@ void ScriptResource::DestroyDecodedDataForFailedRevalidation() {
SetDecodedSize(0);
}
AccessControlStatus ScriptResource::CalculateAccessControlStatus(
const SecurityOrigin* security_origin) const {
if (GetResponse().WasFetchedViaServiceWorker()) {
AccessControlStatus ScriptResource::CalculateAccessControlStatus() const {
if (GetCORSStatus() == CORSStatus::kServiceWorkerOpaque)
return kOpaqueResource;
return kSharableCrossOrigin;
}
if (security_origin && PassesAccessControlCheck(*security_origin))
if (IsSameOriginOrCORSSuccessful())
return kSharableCrossOrigin;
return kNotSharableCrossOrigin;
}
......
......@@ -71,7 +71,7 @@ class CORE_EXPORT ScriptResource final : public TextResource {
const MovableString& SourceText();
AccessControlStatus CalculateAccessControlStatus(const SecurityOrigin*) const;
AccessControlStatus CalculateAccessControlStatus() const;
SingleCachedMetadataHandler* CacheHandler();
......
......@@ -399,10 +399,8 @@ ClassicScript* ClassicPendingScript::GetSource(const KURL& document_url,
// "the URL from which the script was obtained" [spec text]
// https://html.spec.whatwg.org/multipage/webappapis.html#concept-script-base-url
const KURL& base_url = source_code.Url();
return ClassicScript::Create(
source_code, base_url, options_,
resource->CalculateAccessControlStatus(
GetElement()->GetDocument().GetSecurityOrigin()));
return ClassicScript::Create(source_code, base_url, options_,
resource->CalculateAccessControlStatus());
}
void ClassicPendingScript::SetStreamer(ScriptStreamer* streamer) {
......
......@@ -403,16 +403,6 @@ AtomicString Resource::HttpContentType() const {
return GetResponse().HttpContentType();
}
bool Resource::PassesAccessControlCheck(
const SecurityOrigin& security_origin) const {
base::Optional<network::CORSErrorStatus> cors_status = CORS::CheckAccess(
GetResponse().Url(), GetResponse().HttpStatusCode(),
GetResponse().HttpHeaderFields(),
LastResourceRequest().GetFetchCredentialsMode(), security_origin);
return !cors_status;
}
bool Resource::MustRefetchDueToIntegrityMetadata(
const FetchParameters& params) const {
if (params.IntegrityMetadata().IsEmpty())
......
......@@ -215,8 +215,6 @@ class PLATFORM_EXPORT Resource : public GarbageCollectedFinalized<Resource>,
virtual void Finish(TimeTicks finish_time, base::SingleThreadTaskRunner*);
void FinishForTest() { Finish(TimeTicks(), nullptr); }
bool PassesAccessControlCheck(const SecurityOrigin&) const;
virtual scoped_refptr<const SharedBuffer> ResourceBuffer() const {
return data_;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment