Commit 4c1b6e1d authored by mkwst@chromium.org's avatar mkwst@chromium.org

Allow 'chrome-extension:' URLs to bypass content settings (1/2)

We changed the behavior of 'Document::firstPartyForCookies' to return an
empty URL in the case where any URL in the ancestor chain doesn't match
the current document's URL. Previously, we'd simply return the top-level
document's URL.

This means that the content-settings bypass check in
'ContentSettingsObserver::IsWhitelistedForContentSettings' sees an empty
URL as opposed to a 'chrome-extension://' URL for cases in which an
extension loads a resource, so content settings are applied as per usual.
This breaks things fairly badly for folks who have turned on third-party
cookie blocking.

In these patches, we introduce a new scheme registry for those schemes
which ought to override Blink's concept of "first-party" when they're
loaded into the top-level browsing context.

Patch 1 (Blink): [This patch]
Patch 2 (Chromium): https://codereview.chromium.org/1332563006

BUG=527963
R=jochen@chromium.org

Review URL: https://codereview.chromium.org/1305253012

git-svn-id: svn://svn.chromium.org/blink/trunk@201964 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 561c1b05
......@@ -3970,6 +3970,9 @@ String Document::lastModified() const
const KURL& Document::firstPartyForCookies() const
{
if (SchemeRegistry::shouldTreatURLSchemeAsFirstPartyWhenTopLevel(topDocument().url().protocol()))
return topDocument().url();
// We're intentionally using the URL of each document rather than the document's SecurityOrigin.
// Sandboxing a document into a unique origin shouldn't effect first-/third-party status for
// cookies and site data.
......
......@@ -189,6 +189,13 @@ static URLSchemesSet& fetchAPISchemes()
return fetchAPISchemes;
}
static URLSchemesSet& firstPartyWhenTopLevelSchemes()
{
assertLockHeld();
DEFINE_STATIC_LOCAL_NOASSERT(URLSchemesSet, firstPartyWhenTopLevelSchemes, ());
return firstPartyWhenTopLevelSchemes;
}
static URLSchemesMap<SchemeRegistry::PolicyAreas>& ContentSecurityPolicyBypassingSchemes()
{
assertLockHeld();
......@@ -380,6 +387,20 @@ bool SchemeRegistry::shouldTreatURLSchemeAsSupportingFetchAPI(const String& sche
return fetchAPISchemes().contains(scheme);
}
void SchemeRegistry::registerURLSchemeAsFirstPartyWhenTopLevel(const String& scheme)
{
MutexLocker locker(mutex());
firstPartyWhenTopLevelSchemes().add(scheme);
}
bool SchemeRegistry::shouldTreatURLSchemeAsFirstPartyWhenTopLevel(const String& scheme)
{
if (scheme.isEmpty())
return false;
MutexLocker locker(mutex());
return firstPartyWhenTopLevelSchemes().contains(scheme);
}
void SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme, PolicyAreas policyAreas)
{
MutexLocker locker(mutex());
......
......@@ -95,6 +95,10 @@ public:
static void registerURLSchemeAsSupportingFetchAPI(const String& scheme);
static bool shouldTreatURLSchemeAsSupportingFetchAPI(const String& scheme);
// Schemes which override the first-/third-party checks on a Document.
static void registerURLSchemeAsFirstPartyWhenTopLevel(const String& scheme);
static bool shouldTreatURLSchemeAsFirstPartyWhenTopLevel(const String& scheme);
// Allow resources from some schemes to load on a page, regardless of its
// Content Security Policy.
// This enum should be kept in sync with public/web/WebSecurityPolicy.h.
......
......@@ -96,6 +96,11 @@ void WebSecurityPolicy::registerURLSchemeAsBypassingContentSecurityPolicy(const
SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(scheme, static_cast<SchemeRegistry::PolicyAreas>(policyAreas));
}
void WebSecurityPolicy::registerURLSchemeAsFirstPartyWhenTopLevel(const WebString& scheme)
{
SchemeRegistry::registerURLSchemeAsFirstPartyWhenTopLevel(scheme);
}
void WebSecurityPolicy::registerURLSchemeAsEmptyDocument(const WebString& scheme)
{
SchemeRegistry::registerURLSchemeAsEmptyDocument(scheme);
......
......@@ -12,11 +12,12 @@
#include "core/frame/LocalFrame.h"
#include "core/html/HTMLElement.h"
#include "core/html/HTMLLinkElement.h"
#include "core/style/ComputedStyle.h"
#include "core/page/Page.h"
#include "core/style/ComputedStyle.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "platform/graphics/Color.h"
#include "platform/testing/URLTestHelpers.h"
#include "platform/weborigin/SchemeRegistry.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "web/tests/FrameTestHelpers.h"
#include <gtest/gtest.h>
......@@ -296,4 +297,15 @@ TEST_F(WebDocumentFirstPartyTest, NestedData)
ASSERT_EQ(SecurityOrigin::urlWithUniqueSecurityOrigin(), nestedDocument()->firstPartyForCookies());
}
TEST_F(WebDocumentFirstPartyTest, NestedOriginAInOriginBWithFirstPartyOverride)
{
load(nestedOriginAInOriginB);
SchemeRegistry::registerURLSchemeAsFirstPartyWhenTopLevel("http");
ASSERT_EQ(toOriginA(nestedOriginAInOriginB), topDocument()->firstPartyForCookies());
ASSERT_EQ(toOriginA(nestedOriginAInOriginB), nestedDocument()->firstPartyForCookies());
ASSERT_EQ(toOriginA(nestedOriginAInOriginB), nestedNestedDocument()->firstPartyForCookies());
}
} // namespace blink
......@@ -82,6 +82,9 @@ public:
// Registers a URL scheme whose resources can be loaded regardless of a page's Content Security Policy.
BLINK_EXPORT static void registerURLSchemeAsBypassingContentSecurityPolicy(const WebString&);
// Registers a URL scheme which will always be considered the first-party when loaded in a top-level context.
BLINK_EXPORT static void registerURLSchemeAsFirstPartyWhenTopLevel(const WebString&);
// Registers a URL scheme for which some kinds of resources bypass Content Security Policy.
// This enum should be kept in sync with Source/platform/weborigin/SchemeRegistry.h.
// Enforced in AssertMatchingEnums.cpp.
......
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