0

Completely disable all Web Component v0 APIs access via WebIDL

This CL removes the Web Components V0 APIs (Shadow DOM v0, Custom
Elements v0, and HTML Imports) from the web platform. The features
are still available for use by limited internal code directly, for
a limited additional period. See crbug.com/1111843 for reference.

These features were deprecated in August, 2018, in [1], and removed
by default in Chromium M80, in [2] and [3]. For those sites that
needed additional time, there was then a "deprecation extension" [4]
(sometimes called a "reverse origin trial") that allowed sites to
continue using these APIs through M87. Now that M87 has branched
to Beta, the origin trial has now ended. These public APIs are
now disabled for all sites.

With this CL, several test suites are being skipped in
TestExpectations, including several folders that have been prepared
in advance:
  crbug.com/1081941 web-components-v0-only/* [ Skip ]
  crbug.com/1081941 virtual/web-components-v0-disabled/* [ Skip ]
  crbug.com/1081941 http/tests/htmlimports/* [ Skip ]

Once this CL has landed and stabilized, these folders/tests will be
deleted entirely.

[1] https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/h-JwMiPUnuU/sl79aLoLBQAJ
[2] https://chromium-review.googlesource.com/c/chromium/src/+/1850795
[3] https://chromium-review.googlesource.com/c/chromium/src/+/1869562
[4] https://developers.chrome.com/origintrials/#/view_trial/2431943798780067841

Bug: 911943, 1111843

Change-Id: Ia7bde5af655eba43538d18ce1335ed3e72846503
Cq-Do-Not-Cancel-Tryjobs: true
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2195005
Reviewed-by: Annie Sullivan <sullivan@chromium.org>
Reviewed-by: Chris Harrelson <chrishtr@chromium.org>
Reviewed-by: Bo <boliu@chromium.org>
Reviewed-by: Andrey Kosyakov <caseq@chromium.org>
Auto-Submit: Mason Freed <masonfreed@chromium.org>
Commit-Queue: Mason Freed <masonfreed@chromium.org>
Cr-Commit-Position: refs/heads/master@{#813894}
This commit is contained in:
Mason Freed
2020-10-05 20:42:56 +00:00
committed by Commit Bot
parent 30f39afd38
commit e8c86032cb
26 changed files with 27 additions and 636 deletions

@ -461,12 +461,6 @@ class CrossSiteDocumentBlockingTestBase : public ContentBrowserTest {
network::switches::kHostResolverRules,
"MAP * " + embedded_test_server()->host_port_pair().ToString() +
",EXCLUDE localhost");
// TODO(yoichio): This is temporary switch to support chrome internal
// components migration from the old web APIs.
// After completion of the migration, we should remove this.
// See crbug.com/911943 for detail.
command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures,
"HTMLImports");
}
void VerifyImgRequest(std::string resource, CorbExpectations expectations) {
@ -1426,197 +1420,6 @@ IN_PROC_BROWSER_TEST_P(CrossSiteDocumentBlockingTest, PrefetchIsNotImpacted) {
EXPECT_EQ("<p>contents of the response</p>", response_body);
}
// This test covers a scenario where foo.com document HTML-Imports a bar.com
// document. Because of historical reasons, bar.com fetches use foo.com's
// URLLoaderFactory. This means that |request_initiator_origin_lock|
// enforcement can incorrectly classify such fetches as malicious
// (kIncorrectLock). This test ensures that UMAs properly detect such mishaps.
//
// TODO(lukasza, yoichio): https://crbug.com/766694: Remove this test once HTML
// Imports are removed from the codebase.
IN_PROC_BROWSER_TEST_P(CrossSiteDocumentBlockingTest,
HtmlImports_IncorrectLock) {
embedded_test_server()->StartAcceptingConnections();
// Prepare to intercept the network request at the IPC layer.
// This has to be done before the RenderFrameHostImpl is created.
//
// Note: we want to verify that the blocking prevents the data from being sent
// over IPC. Testing later (e.g. via Response/Headers Web APIs) might give a
// false sense of security, since some sanitization happens inside the
// renderer (e.g. via FetchResponseData::CreateCorsFilteredResponse).
GURL json_url("http://bar.com/site_isolation/nosniff.json");
RequestInterceptor interceptor(json_url);
// Navigate to the test page.
GURL foo_url("http://foo.com/title1.html");
EXPECT_TRUE(NavigateToURL(shell(), foo_url));
// Trigger a HTML import from another site. The imported document will
// perform a fetch of nosniff.json same-origin (bar.com) via <script> element.
// CORB should normally allow such fetch (request_initiator == bar.com ==
// origin_of_fetch_target), but here the fetch will be blocked, because
// request_initiator_origin_lock (a.com) will differ from request_initiator.
// Such mishap is okay, because CORB only blocks HTML/XML/JSON and such
// content type wouldn't have worked in <script> (or other non-XHR/fetch
// context) anyway.
GURL html_import_url(
"http://bar.com/cross_site_document_blocking/html_import.html");
const char* html_import_injection_template = R"(
var link = document.createElement('link');
link.rel = 'import';
link.href = $1;
document.head.appendChild(link);
)";
{
base::HistogramTester histograms;
std::string script =
JsReplace(html_import_injection_template, html_import_url);
ExecuteScriptAsync(shell()->web_contents(), script);
interceptor.WaitForRequestCompletion();
// NetworkService enforces |request_initiator_origin_lock| for CORB,
// which means that legitimate fetches from HTML Imported scripts may get
// incorrectly blocked.
interceptor.Verify(CorbExpectations::kShouldBeBlockedWithoutSniffing,
"no resource body needed for blocking verification");
}
}
// This test doesn't cover desirable behavior, but rather highlights bugs in
// implementation of HTML Imports:
// 1. On one hand:
// - "/site_isolation/nosniff.json" is resolved relative to foo.com
// - request_initiator is set to foo.com
// 2. But
// - CORB sees that the request was made from bar.com and blocks it.
//
// The test helps show that the bug above means that in XHR/fetch scenarios
// request_initiator is accidentally compatible with
// request_initiator_origin_lock and therefore the lock can be safely enforced.
//
// There are 2 almost identical tests here:
// - HtmlImports_CompatibleLock1
// - HtmlImports_CompatibleLock2
// They differ in which document is HTML Imported (and how the fetch of
// nosniff.json is triggered).
//
// TODO(lukasza, yoichio): https://crbug.com/766694: Remove this test once HTML
// Imports are removed from the codebase.
IN_PROC_BROWSER_TEST_P(CrossSiteDocumentBlockingTest,
HtmlImports_CompatibleLock1) {
embedded_test_server()->StartAcceptingConnections();
// Prepare to intercept the network request at the IPC layer.
// This has to be done before the RenderFrameHostImpl is created.
//
// Note: we want to verify that the blocking prevents the data from being sent
// over IPC. Testing later (e.g. via Response/Headers Web APIs) might give a
// false sense of security, since some sanitization happens inside the
// renderer (e.g. via FetchResponseData::CreateCorsFilteredResponse).
GURL json_url("http://foo.com/site_isolation/nosniff.json");
RequestInterceptor interceptor(json_url);
// Navigate to the test page.
GURL foo_url("http://foo.com/title1.html");
EXPECT_TRUE(NavigateToURL(shell(), foo_url));
// Trigger a HTML import from another site. The imported document will
// perform a fetch of nosniff.json same-origin (bar.com). CORB should
// allow all same-origin fetches.
GURL html_import_url(
"http://bar.com/cross_site_document_blocking/html_import2.html");
const char* html_import_injection_template = R"(
var link = document.createElement('link');
link.rel = 'import';
link.href = $1;
document.head.appendChild(link);
)";
{
DOMMessageQueue msg_queue;
base::HistogramTester histograms;
std::string script =
JsReplace(html_import_injection_template, html_import_url);
ExecuteScriptAsync(shell()->web_contents(), script);
interceptor.WaitForRequestCompletion();
// |request_initiator| is same-origin (foo.com), and so the fetch should not
// be blocked by CORB.
interceptor.Verify(CorbExpectations::kShouldBeAllowedWithoutSniffing,
GetTestFileContents("site_isolation", "nosniff.json"));
std::string fetch_result;
EXPECT_TRUE(msg_queue.WaitForMessage(&fetch_result));
EXPECT_THAT(fetch_result, ::testing::HasSubstr("BODY: runMe"));
}
}
// This test doesn't cover desirable behavior, but rather highlights bugs in
// implementation of HTML Imports:
// 1. On one hand:
// - "/site_isolation/nosniff.json" is resolved relative to foo.com
// - request_initiator is set to foo.com
// 2. But
// - CORB sees that the request was made from bar.com and blocks it.
//
// The test helps show that the bug above means that in XHR/fetch scenarios
// request_initiator is accidentally compatible with
// request_initiator_origin_lock and therefore the lock can be safely enforced.
//
// There are 2 almost identical tests here:
// - HtmlImports_CompatibleLock1
// - HtmlImports_CompatibleLock2
// They differ in which document is HTML Imported (and how the fetch of
// nosniff.json is triggered).
//
// TODO(lukasza, yoichio): https://crbug.com/766694: Remove this test once HTML
// Imports are removed from the codebase.
IN_PROC_BROWSER_TEST_P(CrossSiteDocumentBlockingTest,
HtmlImports_CompatibleLock2) {
embedded_test_server()->StartAcceptingConnections();
// Prepare to intercept the network request at the IPC layer.
// This has to be done before the RenderFrameHostImpl is created.
//
// Note: we want to verify that the blocking prevents the data from being sent
// over IPC. Testing later (e.g. via Response/Headers Web APIs) might give a
// false sense of security, since some sanitization happens inside the
// renderer (e.g. via FetchResponseData::CreateCorsFilteredResponse).
GURL json_url("http://foo.com/site_isolation/nosniff.json");
RequestInterceptor interceptor(json_url);
// Navigate to the test page.
GURL foo_url("http://foo.com/title1.html");
EXPECT_TRUE(NavigateToURL(shell(), foo_url));
// Trigger a HTML import from another site. The imported document will
// perform a fetch of nosniff.json same-origin (bar.com). CORB should
// allow all same-origin fetches.
GURL html_import_url(
"http://bar.com/cross_site_document_blocking/html_import3.html");
const char* html_import_injection_template = R"(
var link = document.createElement('link');
link.rel = 'import';
link.href = $1;
document.head.appendChild(link);
)";
{
DOMMessageQueue msg_queue;
base::HistogramTester histograms;
std::string script =
JsReplace(html_import_injection_template, html_import_url);
ExecuteScriptAsync(shell()->web_contents(), script);
interceptor.WaitForRequestCompletion();
// |request_initiator| is same-origin (foo.com), and so the fetch should not
// be blocked by CORB.
interceptor.Verify(CorbExpectations::kShouldBeAllowedWithoutSniffing,
GetTestFileContents("site_isolation", "nosniff.json"));
std::string fetch_result;
EXPECT_TRUE(msg_queue.WaitForMessage(&fetch_result));
EXPECT_THAT(fetch_result, ::testing::HasSubstr("BODY: runMe"));
}
}
INSTANTIATE_TEST_SUITE_P(
WithCORBProtectionSniffing,
CrossSiteDocumentBlockingTest,

@ -436,15 +436,6 @@ class CorsExploitBrowserTest : public ContentBrowserTest {
public:
CorsExploitBrowserTest() = default;
void SetUpCommandLine(base::CommandLine* command_line) override {
// TODO(yoichio): This is temporary switch to support chrome internal
// components migration from the old web APIs.
// After completion of the migration, we should remove this.
// See https://crbug.com/911943 for detail.
command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures,
"HTMLImports");
}
void SetUpOnMainThread() override {
host_resolver()->AddRule("*", "127.0.0.1");
SetupCrossSiteRedirector(embedded_test_server());
@ -454,59 +445,6 @@ class CorsExploitBrowserTest : public ContentBrowserTest {
DISALLOW_COPY_AND_ASSIGN(CorsExploitBrowserTest);
};
// This is a regression test for https://crbug.com/961614 - it makes sure that
// the trustworthy |request_initiator_origin_lock| takes precedent over
// the untrustworthy |request.request_initiator|.
//
// For spoofing a |request.request_initiator| that doesn't match
// |request_initiator_origin_lock|, the test relies on a misfeature of HTML
// Imports. It is unclear how to replicate such spoofing once HTML imports are
// deprecated.
IN_PROC_BROWSER_TEST_F(CorsExploitBrowserTest,
OriginHeaderSpoofViaHtmlImports) {
std::string victim_path = "/victim/secret.json";
net::test_server::ControllableHttpResponse victim_response(
embedded_test_server(), victim_path, false);
ASSERT_TRUE(embedded_test_server()->Start());
GURL attacker_url(
embedded_test_server()->GetURL("attacker.com", "/title1.html"));
GURL module_url(embedded_test_server()->GetURL(
"module.com", "/cross_site_document_blocking/html_import3.html"));
GURL victim_url(embedded_test_server()->GetURL("victim.com", victim_path));
EXPECT_TRUE(NavigateToURL(shell(), attacker_url));
// From a renderer process locked to attacker.com, load a HTML Import from
// module.com. HTML Imports implementation allows attacker.com to issue
// requests on behalf of the module.com module - here attacker.com initiates a
// request for a victim.com resource.
const char kScriptTemplate[] = R"(
link = document.createElement('link');
link.rel = 'import';
link.href = $1;
link.onload = () => {
with(link.import.documentElement.appendChild(
link.import.createElement('script'))) {
crossOrigin = 'use-credentials';
src = $2
}
};
document.documentElement.appendChild(link);
)";
std::string script = JsReplace(kScriptTemplate, module_url, victim_url);
ASSERT_TRUE(ExecJs(shell(), script));
// Verify that attacker.com-controlled request for a victim.com resource uses
// CORS and has `Origin: http://attacker.com` request header (rather than
// `Origin: http://module.com`).
victim_response.WaitForRequest();
net::test_server::HttpRequest::HeaderMap headers =
victim_response.http_request()->headers;
ASSERT_TRUE(base::Contains(headers, "Origin"));
EXPECT_EQ(url::Origin::Create(attacker_url).Serialize(), headers["Origin"]);
}
// Test that receiving a commit with incorrect origin properly terminates the
// renderer process.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, MismatchedOriginOnCommit) {