Commit c2343303 authored by Balazs Engedy's avatar Balazs Engedy Committed by Commit Bot

Align IsIconURLEmptyOrSecure with the spec.

Align the behavior of navigator.credentials.store() with the spec [1]
when deciding if the |iconURL| of the passed in PasswordCredential or
FederatedCredential is an `a priori authenticated URL`.

[1]: https://www.w3.org/TR/mixed-content/#a-priori-authenticated-url

Bug: 740081
Change-Id: I2d9ae6c61cc0f3cf3687dfe99aec09b08b078efd
Reviewed-on: https://chromium-review.googlesource.com/833913Reviewed-by: default avatarMike West <mkwst@chromium.org>
Commit-Queue: Balazs Engedy <engedy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#525301}
parent e5cc4add
......@@ -4,19 +4,23 @@
<script src="../resources/testharnessreport.js"></script>
<script>
var local = new PasswordCredential({
id: 'id',
password: 'pencil',
name: 'name',
iconURL: 'https://example.com/icon.png'
});
var federated = new FederatedCredential({
id: 'id',
provider: 'https://federation.test/',
name: 'name',
iconURL: 'https://example.test/icon.png'
});
function CreatePasswordCredentialWithIconURL(url) {
return new PasswordCredential({
id: 'id',
password: 'pencil',
name: 'name',
iconURL: url
});
}
function CreateFederatedCredentialWithIconURL(url) {
return new FederatedCredential({
id: 'id',
provider: 'https://federation.test/',
name: 'name',
iconURL: url
});
}
promise_test((t) => {
return promise_rejects(t, new TypeError(), navigator.credentials.store());
......@@ -28,32 +32,69 @@ promise_test((t) => {
}, "navigator.credential.store([string]) should reject.");
promise_test(() => {
let local = CreatePasswordCredentialWithIconURL("https://foo/icon.png");
return navigator.credentials.store(local);
}, "navigator.credential.store([PasswordCredential]) should succeed.");
promise_test(() => {
let federated = CreateFederatedCredentialWithIconURL("https://foo/icon.png");
return navigator.credentials.store(federated);
}, "navigator.credentials.store([FederatedCredential]) should succeed.");
promise_test((t) => {
var federated_insecure = new FederatedCredential({
id: 'id',
provider: 'https://federation.test/',
name: 'name',
iconURL: 'http://example.test/icon.png'
});
return promise_rejects(t, "SecurityError",
navigator.credentials.store(federated_insecure));
}, "navigator.credentials.store([FederatedCredential]) with insecure |iconURL| should reject.");
const A_PRIORI_AUTHENTICATED_URLS = [
'https://foo/icon.png',
'wss://foo/icon.png',
'file:///etc/shadow',
'data:image/png;base64,',
'about:blank',
'about:srcdoc',
'http://127.0.0.123/icon.png',
'http://[::1]/icon.png',
'filesystem:https://foo/icon.png',
'filesystem:file:///etc/shadow',
'blob:https://foo/blob-id',
'blob:file:///blob-id',
];
promise_test((t) => {
var local_insecure = new PasswordCredential({
id: 'id',
password: 'pencil',
name: 'name',
iconURL: 'http://example.test/icon.png'
});
return promise_rejects(t, "SecurityError",
navigator.credentials.store(local_insecure));
}, "navigator.credentials.store([PasswordCredential]) with insecure |iconURL| should reject.");
const NON_A_PRIORI_AUTHENTICATED_URLS = [
'http://foo:443/icon.png',
'https-so://foo/icon.png',
'http-so://foo/icon.png',
'javascript:alert()',
'ws://foo/icon.png',
'ftp://foo/icon.png',
'gopher://foo/icon.png',
'http://128.0.0.0/icon.png',
'http://[::2]/icon.png',
'http:///icon.png',
'filesystem:http://foo/icon.png',
'blob:http://foo/blob-id',
'blob:null/blob-id',
];
for (let url of A_PRIORI_AUTHENTICATED_URLS) {
promise_test(() => {
let local = CreatePasswordCredentialWithIconURL(url);
return navigator.credentials.store(local);
}, "navigator.credential.store([PasswordCredential]) with |iconURL| " + url + " should succeed.");
promise_test(() => {
let federated = CreateFederatedCredentialWithIconURL(url);
return navigator.credentials.store(federated);
}, "navigator.credentials.store([FederatedCredential]) with |iconURL| " + url + " should succeed.");
}
for (let url of NON_A_PRIORI_AUTHENTICATED_URLS) {
promise_test((t) => {
let local = CreatePasswordCredentialWithIconURL(url);
return promise_rejects(t, "SecurityError",
navigator.credentials.store(local));
}, "navigator.credentials.store([PasswordCredential]) with insecure |iconURL| " + url + " should reject.");
promise_test((t) => {
let federated = CreateFederatedCredentialWithIconURL(url);
return promise_rejects(t, "SecurityError",
navigator.credentials.store(federated));
}, "navigator.credentials.store([FederatedCredential]) with insecure |iconURL| " + url + " should reject.");
}
</script>
......@@ -121,22 +121,27 @@ bool CheckBoilerplate(ScriptPromiseResolver* resolver) {
return true;
}
bool IsIconURLInsecure(const Credential* credential) {
bool IsIconURLEmptyOrSecure(const Credential* credential) {
PlatformCredential* platform_credential = credential->GetPlatformCredential();
auto is_insecure = [](const KURL& url) {
return !url.IsEmpty() && !url.ProtocolIs("https");
};
if (platform_credential->IsFederated()) {
return is_insecure(
static_cast<PlatformFederatedCredential*>(platform_credential)
->IconURL());
}
if (platform_credential->IsPassword()) {
return is_insecure(
static_cast<PlatformPasswordCredential*>(platform_credential)
->IconURL());
if (!platform_credential->IsPassword() &&
!platform_credential->IsFederated()) {
return true;
}
return false;
const KURL& url =
platform_credential->IsFederated()
? static_cast<const PlatformFederatedCredential*>(platform_credential)
->IconURL()
: static_cast<const PlatformPasswordCredential*>(platform_credential)
->IconURL();
if (url.IsEmpty())
return true;
// https://www.w3.org/TR/mixed-content/#a-priori-authenticated-url
return url.IsAboutSrcdocURL() || url.IsAboutBlankURL() ||
url.ProtocolIsData() ||
SecurityOrigin::Create(url)->IsPotentiallyTrustworthy();
}
} // namespace
......@@ -352,7 +357,7 @@ ScriptPromise CredentialsContainer::store(ScriptState* script_state,
"Store operation not permitted for PublicKey credentials."));
}
if (IsIconURLInsecure(credential)) {
if (!IsIconURLEmptyOrSecure(credential)) {
resolver->Reject(DOMException::Create(kSecurityError,
"'iconURL' should be a secure URL"));
return promise;
......
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