Commit efd790c3 authored by tzik's avatar tzik Committed by Commit Bot

Use nonce value for SecurityOrigin equality

SecurityOrigin used to use |this| pointer value to identify opaque
unique origins, which does not work well with IsolatedCopy().
After this CL, the nonce value of the unique origin is involved for
the comparison, so that the return value of IsolatedCopy() equals to
the original one.

Change-Id: I54bc49ead8b711b40902503656e3356e9a5c75f3
Reviewed-on: https://chromium-review.googlesource.com/c/1445034Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarNasko Oskov <nasko@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Taiju Tsuiki <tzik@chromium.org>
Cr-Commit-Position: refs/heads/master@{#628247}
parent 4467521a
......@@ -306,6 +306,9 @@ bool SecurityOrigin::CanAccess(const SecurityOrigin* other,
return true;
}
// This is needed to ensure an origin can access to itself under nullified
// document.domain.
// TODO(tzik): Update the nulled domain handling and remove this condition.
if (this == other) {
detail = AccessResultDomainDetail::kDomainNotRelevant;
return true;
......@@ -313,7 +316,7 @@ bool SecurityOrigin::CanAccess(const SecurityOrigin* other,
if (IsOpaque() || other->IsOpaque()) {
detail = AccessResultDomainDetail::kDomainNotRelevant;
return false;
return nonce_if_opaque_ == other->nonce_if_opaque_;
}
// document.domain handling, as per
......@@ -545,14 +548,15 @@ scoped_refptr<SecurityOrigin> SecurityOrigin::Create(const String& protocol,
}
bool SecurityOrigin::IsSameSchemeHostPort(const SecurityOrigin* other) const {
// This is needed to ensure a local origin considered to have the same scheme,
// host, and port to itself.
// TODO(tzik): Make the local origin unique but not opaque, and remove this
// condition.
if (this == other)
return true;
if (IsOpaque() || other->IsOpaque()) {
// TODO(dcheng|nasko): Add nonce equality check here, such that opaque
// origins that are copy of each other can be equal.
return false;
}
if (IsOpaque() || other->IsOpaque())
return nonce_if_opaque_ == other->nonce_if_opaque_;
if (host_ != other->host_)
return false;
......
......@@ -47,6 +47,7 @@ namespace blink {
class KURL;
class URLSecurityOriginMap;
struct SecurityOriginHash;
// An identifier which defines the source of content (e.g. a document) and
// restricts what other objects it is permitted to access (based on their
......@@ -306,6 +307,7 @@ class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> {
constexpr static const int kInvalidPort = 0;
friend struct mojo::UrlOriginAdapter;
friend struct blink::SecurityOriginHash;
// Creates a new opaque SecurityOrigin using the supplied |precursor| origin
// and |nonce|.
......
......@@ -30,6 +30,7 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBORIGIN_SECURITY_ORIGIN_HASH_H_
#include "base/memory/scoped_refptr.h"
#include "build/build_config.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
......@@ -43,10 +44,23 @@ namespace blink {
struct SecurityOriginHash {
STATIC_ONLY(SecurityOriginHash);
static unsigned GetHash(const SecurityOrigin* origin) {
unsigned hash_codes[3] = {
origin->Protocol().Impl() ? origin->Protocol().Impl()->GetHash() : 0,
origin->Host().Impl() ? origin->Host().Impl()->GetHash() : 0,
origin->Port()};
base::Optional<base::UnguessableToken> nonce =
origin->GetNonceForSerialization();
size_t nonce_hash = nonce ? base::UnguessableTokenHash()(*nonce) : 0;
unsigned hash_codes[] = {
origin->Protocol().Impl() ? origin->Protocol().Impl()->GetHash() : 0,
origin->Host().Impl() ? origin->Host().Impl()->GetHash() : 0,
origin->Port(),
#if ARCH_CPU_32_BITS
nonce_hash,
#elif ARCH_CPU_64_BITS
static_cast<unsigned>(nonce_hash),
static_cast<unsigned>(nonce_hash >> 32),
#else
#error "Unknown bits"
#endif
};
return StringHasher::HashMemory<sizeof(hash_codes)>(hash_codes);
}
static unsigned GetHash(const scoped_refptr<const SecurityOrigin>& origin) {
......
......@@ -39,6 +39,7 @@
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin_hash.h"
#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
......@@ -808,4 +809,27 @@ TEST_F(SecurityOriginTest, NonStandardSchemeWithAndroidWebViewHack) {
url::Shutdown();
}
TEST_F(SecurityOriginTest, OpaqueIsolatedCopy) {
scoped_refptr<const SecurityOrigin> origin =
SecurityOrigin::CreateUniqueOpaque();
scoped_refptr<const SecurityOrigin> copied = origin->IsolatedCopy();
EXPECT_TRUE(origin->CanAccess(copied.get()));
EXPECT_TRUE(origin->IsSameSchemeHostPort(copied.get()));
EXPECT_EQ(SecurityOriginHash::GetHash(origin),
SecurityOriginHash::GetHash(copied));
EXPECT_TRUE(SecurityOriginHash::Equal(origin, copied));
}
TEST_F(SecurityOriginTest, EdgeCases) {
scoped_refptr<SecurityOrigin> nulled_domain =
SecurityOrigin::CreateFromString("http://localhost");
nulled_domain->SetDomainFromDOM("null");
EXPECT_TRUE(nulled_domain->CanAccess(nulled_domain.get()));
scoped_refptr<SecurityOrigin> local =
SecurityOrigin::CreateFromString("file:///foo/bar");
local->BlockLocalAccessFromLocalOrigin();
EXPECT_TRUE(local->IsSameSchemeHostPort(local.get()));
}
} // namespace blink
......@@ -57,6 +57,7 @@ _CONFIG = [
'base::TimeTicks',
'base::ThreadTicks',
'base::UnguessableToken',
'base::UnguessableTokenHash',
'base::UnsafeSharedMemoryRegion',
'base::WeakPtr',
'base::WeakPtrFactory',
......
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