Commit c4434880 authored by Lukasz Anforowicz's avatar Lukasz Anforowicz Committed by Commit Bot

CORB: Allow text/plain 206 responses.

Bug: 801709
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_mojo
Change-Id: Ie059475b03953372cf9fcc9ddafd875ebc849e34
Reviewed-on: https://chromium-review.googlesource.com/973942
Commit-Queue: Łukasz Anforowicz <lukasza@chromium.org>
Reviewed-by: default avatarNick Carter <nick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#544959}
parent 12098b47
...@@ -845,11 +845,6 @@ bool CrossSiteDocumentResourceHandler::ShouldBlockBasedOnHeaders( ...@@ -845,11 +845,6 @@ bool CrossSiteDocumentResourceHandler::ShouldBlockBasedOnHeaders(
bool has_nosniff_header = bool has_nosniff_header =
base::LowerCaseEqualsASCII(nosniff_header, "nosniff"); base::LowerCaseEqualsASCII(nosniff_header, "nosniff");
// If this is an HTTP range request, sniffing isn't possible.
std::string range_header;
response->head.headers->GetNormalizedHeader("content-range", &range_header);
bool has_range_header = !range_header.empty();
// CORB should look directly at the Content-Type header if one has been // CORB should look directly at the Content-Type header if one has been
// received from the network. Ignoring |response->head.mime_type| helps avoid // received from the network. Ignoring |response->head.mime_type| helps avoid
// breaking legitimate websites (which might happen more often when blocking // breaking legitimate websites (which might happen more often when blocking
...@@ -868,15 +863,29 @@ bool CrossSiteDocumentResourceHandler::ShouldBlockBasedOnHeaders( ...@@ -868,15 +863,29 @@ bool CrossSiteDocumentResourceHandler::ShouldBlockBasedOnHeaders(
// If this is a partial response, sniffing is not possible, so allow the // If this is a partial response, sniffing is not possible, so allow the
// response if it's not a protected mime type. // response if it's not a protected mime type.
if (has_range_header && canonical_mime_type_ == MimeType::kOthers) { std::string range_header;
response->head.headers->GetNormalizedHeader("content-range", &range_header);
if (!range_header.empty()) {
needs_sniffing_ = false;
switch (canonical_mime_type_) {
case MimeType::kOthers:
case MimeType::kPlain: // See also https://crbug.com/801709
return false; return false;
case MimeType::kHtml:
case MimeType::kJson:
case MimeType::kXml:
return true;
case MimeType::kMax:
NOTREACHED();
return true;
}
} }
// We need to sniff unprotected mime types (e.g. for parser breakers), and // We need to sniff unprotected mime types (e.g. for parser breakers), and
// unless the nosniff header is set, we also need to sniff protected mime // unless the nosniff header is set, we also need to sniff protected mime
// types to verify that they're not mislabeled. // types to verify that they're not mislabeled.
needs_sniffing_ = (canonical_mime_type_ == MimeType::kOthers) || needs_sniffing_ =
!(has_range_header || has_nosniff_header); (canonical_mime_type_ == MimeType::kOthers) || !has_nosniff_header;
// Stylesheets shouldn't be sniffed for JSON parser breakers - see // Stylesheets shouldn't be sniffed for JSON parser breakers - see
// https://crbug.com/809259. // https://crbug.com/809259.
......
...@@ -85,6 +85,7 @@ struct TestScenario { ...@@ -85,6 +85,7 @@ struct TestScenario {
const char* response_mime_type; const char* response_mime_type;
MimeType canonical_mime_type; MimeType canonical_mime_type;
bool include_no_sniff_header; bool include_no_sniff_header;
bool simulate_range_response;
AccessControlAllowOriginHeader cors_response; AccessControlAllowOriginHeader cors_response;
// |packets| specifies the response data which may arrive over the course of // |packets| specifies the response data which may arrive over the course of
// several writes. // several writes.
...@@ -165,6 +166,8 @@ struct TestScenario { ...@@ -165,6 +166,8 @@ struct TestScenario {
<< "\n canonical_mime_type = " << scenario.canonical_mime_type << "\n canonical_mime_type = " << scenario.canonical_mime_type
<< "\n include_no_sniff = " << "\n include_no_sniff = "
<< (scenario.include_no_sniff_header ? "true" : "false") << (scenario.include_no_sniff_header ? "true" : "false")
<< "\n range_response = "
<< (scenario.simulate_range_response ? "true" : "false")
<< "\n cors_response = " << cors_response << "\n cors_response = " << cors_response
<< "\n packets = " << packets << "\n packets = " << packets
<< "\n verdict = " << verdict << "\n verdict = " << verdict
...@@ -208,6 +211,7 @@ const TestScenario kScenarios[] = { ...@@ -208,6 +211,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kInvalid, // canonical_mime_type MimeType::kInvalid, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"<html><head>this should sniff as HTML"}, // packets {"<html><head>this should sniff as HTML"}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -223,6 +227,7 @@ const TestScenario kScenarios[] = { ...@@ -223,6 +227,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kInvalid, // canonical_mime_type MimeType::kInvalid, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{")]}',\n[true, true, false, \"user@chromium.org\"]"}, // packets {")]}',\n[true, true, false, \"user@chromium.org\"]"}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -238,6 +243,7 @@ const TestScenario kScenarios[] = { ...@@ -238,6 +243,7 @@ const TestScenario kScenarios[] = {
"text/json", // response_mime_type "text/json", // response_mime_type
MimeType::kInvalid, // canonical_mime_type MimeType::kInvalid, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{")]}'\n[true, true, false, \"user@chromium.org\"]"}, // packets {")]}'\n[true, true, false, \"user@chromium.org\"]"}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -253,6 +259,7 @@ const TestScenario kScenarios[] = { ...@@ -253,6 +259,7 @@ const TestScenario kScenarios[] = {
"application/javascript", // response_mime_type "application/javascript", // response_mime_type
MimeType::kOthers, // canonical_mime_type MimeType::kOthers, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"var x=3;"}, // packets {"var x=3;"}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -268,6 +275,7 @@ const TestScenario kScenarios[] = { ...@@ -268,6 +275,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kInvalid, // canonical_mime_type MimeType::kInvalid, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kAllowInitiatorOrigin, // cors_response AccessControlAllowOriginHeader::kAllowInitiatorOrigin, // cors_response
{"<html><head>this should sniff as HTML"}, // packets {"<html><head>this should sniff as HTML"}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -283,6 +291,7 @@ const TestScenario kScenarios[] = { ...@@ -283,6 +291,7 @@ const TestScenario kScenarios[] = {
"application/rss+xml", // response_mime_type "application/rss+xml", // response_mime_type
MimeType::kInvalid, // canonical_mime_type MimeType::kInvalid, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kAllowAny, // cors_response AccessControlAllowOriginHeader::kAllowAny, // cors_response
{"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"}, // packets {"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -298,6 +307,7 @@ const TestScenario kScenarios[] = { ...@@ -298,6 +307,7 @@ const TestScenario kScenarios[] = {
"text/json", // response_mime_type "text/json", // response_mime_type
MimeType::kInvalid, // canonical_mime_type MimeType::kInvalid, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kAllowNull, // cors_response AccessControlAllowOriginHeader::kAllowNull, // cors_response
{"{\"x\" : 3}"}, // packets {"{\"x\" : 3}"}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -313,6 +323,7 @@ const TestScenario kScenarios[] = { ...@@ -313,6 +323,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kInvalid, // canonical_mime_type MimeType::kInvalid, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"<html><head>this should sniff as HTML"}, // packets {"<html><head>this should sniff as HTML"}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -328,6 +339,7 @@ const TestScenario kScenarios[] = { ...@@ -328,6 +339,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kInvalid, // canonical_mime_type MimeType::kInvalid, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"<html><head>this should sniff as HTML"}, // packets {"<html><head>this should sniff as HTML"}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -343,6 +355,7 @@ const TestScenario kScenarios[] = { ...@@ -343,6 +355,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kInvalid, // canonical_mime_type MimeType::kInvalid, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"<html><head>this should sniff as HTML"}, // packets {"<html><head>this should sniff as HTML"}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -358,6 +371,7 @@ const TestScenario kScenarios[] = { ...@@ -358,6 +371,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kInvalid, // canonical_mime_type MimeType::kInvalid, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kAllowInitiatorOrigin, // cors_response AccessControlAllowOriginHeader::kAllowInitiatorOrigin, // cors_response
{"<html><head>this should sniff as HTML"}, // first_chunk {"<html><head>this should sniff as HTML"}, // first_chunk
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -373,6 +387,7 @@ const TestScenario kScenarios[] = { ...@@ -373,6 +387,7 @@ const TestScenario kScenarios[] = {
"application/javascript", // response_mime_type "application/javascript", // response_mime_type
MimeType::kInvalid, // canonical_mime_type MimeType::kInvalid, // canonical_mime_type
true, // include_no_sniff_header true, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kAllowAny, // cors_response AccessControlAllowOriginHeader::kAllowAny, // cors_response
{")]}'\n[true, false]"}, // packets {")]}'\n[true, false]"}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -388,6 +403,7 @@ const TestScenario kScenarios[] = { ...@@ -388,6 +403,7 @@ const TestScenario kScenarios[] = {
"application/javascript", // response_mime_type "application/javascript", // response_mime_type
MimeType::kOthers, // canonical_mime_type MimeType::kOthers, // canonical_mime_type
true, // include_no_sniff_header true, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"{ \"key\"", ": true }"}, // packets {"{ \"key\"", ": true }"}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -403,6 +419,7 @@ const TestScenario kScenarios[] = { ...@@ -403,6 +419,7 @@ const TestScenario kScenarios[] = {
"image/png", // response_mime_type "image/png", // response_mime_type
MimeType::kOthers, // canonical_mime_type MimeType::kOthers, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{}, // packets {}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -418,6 +435,7 @@ const TestScenario kScenarios[] = { ...@@ -418,6 +435,7 @@ const TestScenario kScenarios[] = {
"image/png", // response_mime_type "image/png", // response_mime_type
MimeType::kOthers, // canonical_mime_type MimeType::kOthers, // canonical_mime_type
true, // include_no_sniff_header true, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{}, // packets {}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -435,6 +453,7 @@ const TestScenario kScenarios[] = { ...@@ -435,6 +453,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kHtml, // canonical_mime_type MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"foo({\"x\" : 3})"}, // packets {"foo({\"x\" : 3})"}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -450,6 +469,7 @@ const TestScenario kScenarios[] = { ...@@ -450,6 +469,7 @@ const TestScenario kScenarios[] = {
"text/plain", // response_mime_type "text/plain", // response_mime_type
MimeType::kPlain, // canonical_mime_type MimeType::kPlain, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"var x = 3;"}, // packets {"var x = 3;"}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -465,6 +485,7 @@ const TestScenario kScenarios[] = { ...@@ -465,6 +485,7 @@ const TestScenario kScenarios[] = {
"text/plain", // response_mime_type "text/plain", // response_mime_type
MimeType::kPlain, // canonical_mime_type MimeType::kPlain, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"{", " \n", "var x = 3;\n", "console.log('hello');"}, // packets {"{", " \n", "var x = 3;\n", "console.log('hello');"}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -481,6 +502,7 @@ const TestScenario kScenarios[] = { ...@@ -481,6 +502,7 @@ const TestScenario kScenarios[] = {
"text/json", // response_mime_type "text/json", // response_mime_type
MimeType::kJson, // canonical_mime_type MimeType::kJson, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"invoke({ \"key\": true });"}, // packets {"invoke({ \"key\": true });"}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -496,6 +518,7 @@ const TestScenario kScenarios[] = { ...@@ -496,6 +518,7 @@ const TestScenario kScenarios[] = {
"text/plain", // response_mime_type "text/plain", // response_mime_type
MimeType::kPlain, // canonical_mime_type MimeType::kPlain, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"[1, 2, {}, true, false, \"yay\"]"}, // packets {"[1, 2, {}, true, false, \"yay\"]"}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -511,6 +534,7 @@ const TestScenario kScenarios[] = { ...@@ -511,6 +534,7 @@ const TestScenario kScenarios[] = {
"text/plain", // response_mime_type "text/plain", // response_mime_type
MimeType::kPlain, // canonical_mime_type MimeType::kPlain, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"[1, 2, {}, true, false, \"yay\"]", ".map(x => console.log(x))", {"[1, 2, {}, true, false, \"yay\"]", ".map(x => console.log(x))",
".map(x => console.log(x));"}, // packets ".map(x => console.log(x));"}, // packets
...@@ -527,6 +551,7 @@ const TestScenario kScenarios[] = { ...@@ -527,6 +551,7 @@ const TestScenario kScenarios[] = {
"application/xml", // response_mime_type "application/xml", // response_mime_type
MimeType::kXml, // canonical_mime_type MimeType::kXml, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"Won't sniff as XML"}, // packets {"Won't sniff as XML"}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -542,6 +567,7 @@ const TestScenario kScenarios[] = { ...@@ -542,6 +567,7 @@ const TestScenario kScenarios[] = {
"text/x-json", // response_mime_type "text/x-json", // response_mime_type
MimeType::kJson, // canonical_mime_type MimeType::kJson, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"Won't sniff as JSON"}, // packets {"Won't sniff as JSON"}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -557,6 +583,7 @@ const TestScenario kScenarios[] = { ...@@ -557,6 +583,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kHtml, // canonical_mime_type MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"<htm"}, // packets {"<htm"}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -572,6 +599,7 @@ const TestScenario kScenarios[] = { ...@@ -572,6 +599,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kHtml, // canonical_mime_type MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{kHTMLWithTooLongComment}, // packets {kHTMLWithTooLongComment}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -587,6 +615,7 @@ const TestScenario kScenarios[] = { ...@@ -587,6 +615,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kHtml, // canonical_mime_type MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{}, // packets {}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -602,6 +631,7 @@ const TestScenario kScenarios[] = { ...@@ -602,6 +631,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kInvalid, // canonical_mime_type MimeType::kInvalid, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"<html><head>this should sniff as HTML"}, // packets {"<html><head>this should sniff as HTML"}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -617,6 +647,7 @@ const TestScenario kScenarios[] = { ...@@ -617,6 +647,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kInvalid, // canonical_mime_type MimeType::kInvalid, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"<html><head>this should sniff as HTML"}, // packets {"<html><head>this should sniff as HTML"}, // packets
Verdict::kAllow, // verdict Verdict::kAllow, // verdict
...@@ -634,6 +665,7 @@ const TestScenario kScenarios[] = { ...@@ -634,6 +665,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kHtml, // canonical_mime_type MimeType::kHtml, // canonical_mime_type
true, // include_no_sniff_header true, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"<html><head>this should sniff as HTML"}, // packets {"<html><head>this should sniff as HTML"}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -649,6 +681,7 @@ const TestScenario kScenarios[] = { ...@@ -649,6 +681,7 @@ const TestScenario kScenarios[] = {
"text/html; charset=utf-8", // response_mime_type "text/html; charset=utf-8", // response_mime_type
MimeType::kHtml, // canonical_mime_type MimeType::kHtml, // canonical_mime_type
true, // include_no_sniff_header true, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"<html><head>this should sniff as HTML"}, // packets {"<html><head>this should sniff as HTML"}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -664,6 +697,7 @@ const TestScenario kScenarios[] = { ...@@ -664,6 +697,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kHtml, // canonical_mime_type MimeType::kHtml, // canonical_mime_type
true, // include_no_sniff_header true, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"Wouldn't sniff as HTML"}, // packets {"Wouldn't sniff as HTML"}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -679,6 +713,7 @@ const TestScenario kScenarios[] = { ...@@ -679,6 +713,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kHtml, // canonical_mime_type MimeType::kHtml, // canonical_mime_type
true, // include_no_sniff_header true, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"<html><head>this should sniff as HTML"}, // packets {"<html><head>this should sniff as HTML"}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -696,6 +731,7 @@ const TestScenario kScenarios[] = { ...@@ -696,6 +731,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kHtml, // canonical_mime_type MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kAllowExampleDotCom, // cors_response AccessControlAllowOriginHeader::kAllowExampleDotCom, // cors_response
{"<hTmL><head>this should sniff as HTML"}, // packets {"<hTmL><head>this should sniff as HTML"}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -715,6 +751,7 @@ const TestScenario kScenarios[] = { ...@@ -715,6 +751,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kHtml, // canonical_mime_type MimeType::kHtml, // canonical_mime_type
true, // include_no_sniff_header true, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{}, // packets {}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -732,6 +769,7 @@ const TestScenario kScenarios[] = { ...@@ -732,6 +769,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kHtml, // canonical_mime_type MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"<html><head>this should sniff as HTML"}, // packets {"<html><head>this should sniff as HTML"}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -747,6 +785,7 @@ const TestScenario kScenarios[] = { ...@@ -747,6 +785,7 @@ const TestScenario kScenarios[] = {
"application/xml", // response_mime_type "application/xml", // response_mime_type
MimeType::kXml, // canonical_mime_type MimeType::kXml, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"}, // packets {"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -762,6 +801,7 @@ const TestScenario kScenarios[] = { ...@@ -762,6 +801,7 @@ const TestScenario kScenarios[] = {
"application/json", // response_mime_type "application/json", // response_mime_type
MimeType::kJson, // canonical_mime_type MimeType::kJson, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"{\"x\" : 3}"}, // packets {"{\"x\" : 3}"}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -777,6 +817,7 @@ const TestScenario kScenarios[] = { ...@@ -777,6 +817,7 @@ const TestScenario kScenarios[] = {
"text/plain", // response_mime_type "text/plain", // response_mime_type
MimeType::kPlain, // canonical_mime_type MimeType::kPlain, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{" ", "\t", "{", "\"x\" ", " ", ": 3}"}, // packets {" ", "\t", "{", "\"x\" ", " ", ": 3}"}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -792,6 +833,7 @@ const TestScenario kScenarios[] = { ...@@ -792,6 +833,7 @@ const TestScenario kScenarios[] = {
"text/plain", // response_mime_type "text/plain", // response_mime_type
MimeType::kPlain, // canonical_mime_type MimeType::kPlain, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{" ", "\t", "<", "?", "x", "m", "l", ">"}, // packets {" ", "\t", "<", "?", "x", "m", "l", ">"}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -807,6 +849,7 @@ const TestScenario kScenarios[] = { ...@@ -807,6 +849,7 @@ const TestScenario kScenarios[] = {
"text/plain", // response_mime_type "text/plain", // response_mime_type
MimeType::kPlain, // canonical_mime_type MimeType::kPlain, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{" <!--", "\t -", "-", "->", "<", "s", "c", "r", "i", "p", {" <!--", "\t -", "-", "->", "<", "s", "c", "r", "i", "p",
"t"}, // packets "t"}, // packets
...@@ -823,6 +866,7 @@ const TestScenario kScenarios[] = { ...@@ -823,6 +866,7 @@ const TestScenario kScenarios[] = {
"text/plain", // response_mime_type "text/plain", // response_mime_type
MimeType::kPlain, // canonical_mime_type MimeType::kPlain, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{" <!--", " <?xml ", "-->", "<", "h", "e", "a", "d"}, // packets {" <!--", " <?xml ", "-->", "<", "h", "e", "a", "d"}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -838,6 +882,7 @@ const TestScenario kScenarios[] = { ...@@ -838,6 +882,7 @@ const TestScenario kScenarios[] = {
"text/plain", // response_mime_type "text/plain", // response_mime_type
MimeType::kPlain, // canonical_mime_type MimeType::kPlain, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"<html><head>this should sniff as HTML"}, // packets {"<html><head>this should sniff as HTML"}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -853,6 +898,7 @@ const TestScenario kScenarios[] = { ...@@ -853,6 +898,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kHtml, // canonical_mime_type MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"<!doc", "type html><html itemscope=\"\" ", {"<!doc", "type html><html itemscope=\"\" ",
"itemtype=\"http://schema.org/SearchResultsPage\" ", "itemtype=\"http://schema.org/SearchResultsPage\" ",
...@@ -870,6 +916,7 @@ const TestScenario kScenarios[] = { ...@@ -870,6 +916,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kHtml, // canonical_mime_type MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kAllowExampleDotCom, // cors_response AccessControlAllowOriginHeader::kAllowExampleDotCom, // cors_response
{"<hTmL><head>this should sniff as HTML"}, // packets {"<hTmL><head>this should sniff as HTML"}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -885,6 +932,7 @@ const TestScenario kScenarios[] = { ...@@ -885,6 +932,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kHtml, // canonical_mime_type MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"<html><head>this should sniff as HTML"}, // first_chunk {"<html><head>this should sniff as HTML"}, // first_chunk
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -900,6 +948,7 @@ const TestScenario kScenarios[] = { ...@@ -900,6 +948,7 @@ const TestScenario kScenarios[] = {
"text/json", // response_mime_type "text/json", // response_mime_type
MimeType::kJson, // canonical_mime_type MimeType::kJson, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{")]", "}'\n[true, true, false, \"user@chromium.org\"]"}, // packets {")]", "}'\n[true, true, false, \"user@chromium.org\"]"}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -915,6 +964,7 @@ const TestScenario kScenarios[] = { ...@@ -915,6 +964,7 @@ const TestScenario kScenarios[] = {
"audio/x-wav", // response_mime_type "audio/x-wav", // response_mime_type
MimeType::kOthers, // canonical_mime_type MimeType::kOthers, // canonical_mime_type
true, // include_no_sniff_header true, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{")]", "}'\n[true, true, false, \"user@chromium.org\"]"}, // packets {")]", "}'\n[true, true, false, \"user@chromium.org\"]"}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -930,6 +980,7 @@ const TestScenario kScenarios[] = { ...@@ -930,6 +980,7 @@ const TestScenario kScenarios[] = {
"application/javascript", // response_mime_type "application/javascript", // response_mime_type
MimeType::kOthers, // canonical_mime_type MimeType::kOthers, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"for(;;)", ";[true, true, false, \"user@chromium.org\"]"}, // packets {"for(;;)", ";[true, true, false, \"user@chromium.org\"]"}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -945,6 +996,7 @@ const TestScenario kScenarios[] = { ...@@ -945,6 +996,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kHtml, // canonical_mime_type MimeType::kHtml, // canonical_mime_type
true, // include_no_sniff_header true, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{")]", "}'\n[true, true, false, \"user@chromium.org\"]"}, // packets {")]", "}'\n[true, true, false, \"user@chromium.org\"]"}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -961,6 +1013,7 @@ const TestScenario kScenarios[] = { ...@@ -961,6 +1013,7 @@ const TestScenario kScenarios[] = {
"application/javascript", // response_mime_type "application/javascript", // response_mime_type
MimeType::kOthers, // canonical_mime_type MimeType::kOthers, // canonical_mime_type
true, // include_no_sniff_header true, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kAllowExampleDotCom, // cors_response AccessControlAllowOriginHeader::kAllowExampleDotCom, // cors_response
{")]}'\n[true, false]"}, // packets {")]}'\n[true, false]"}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -976,6 +1029,7 @@ const TestScenario kScenarios[] = { ...@@ -976,6 +1029,7 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kHtml, // canonical_mime_type MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"<html><head>this should sniff as HTML"}, // packets {"<html><head>this should sniff as HTML"}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
...@@ -991,11 +1045,44 @@ const TestScenario kScenarios[] = { ...@@ -991,11 +1045,44 @@ const TestScenario kScenarios[] = {
"text/html", // response_mime_type "text/html", // response_mime_type
MimeType::kHtml, // canonical_mime_type MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header false, // include_no_sniff_header
false, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response AccessControlAllowOriginHeader::kOmit, // cors_response
{"<html><head>this should sniff as HTML"}, // packets {"<html><head>this should sniff as HTML"}, // packets
Verdict::kBlock, // verdict Verdict::kBlock, // verdict
0, // verdict_packet 0, // verdict_packet
}, },
{
"Allowed: text/plain 206 media",
__LINE__,
"http://www.b.com/movie.txt", // target_url
RESOURCE_TYPE_MEDIA, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
"text/plain", // response_mime_type
MimeType::kPlain, // canonical_mime_type
false, // include_no_sniff_header
true, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response
{"movie content"}, // packets
Verdict::kAllow, // verdict
-1, // verdict_packet
},
{
"Blocked: text/html 206 media",
__LINE__,
"http://www.b.com/movie.html", // target_url
RESOURCE_TYPE_MEDIA, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
"text/html", // response_mime_type
MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header
true, // simulate_range_response
AccessControlAllowOriginHeader::kOmit, // cors_response
{"simulated *middle*-of-html content"}, // packets
Verdict::kBlock, // verdict
-1, // verdict_packet
},
}; };
// TestResourceDispatcherHost is a ResourceDispatcherHostImpl that the test // TestResourceDispatcherHost is a ResourceDispatcherHostImpl that the test
...@@ -1105,12 +1192,14 @@ class CrossSiteDocumentResourceHandlerTest ...@@ -1105,12 +1192,14 @@ class CrossSiteDocumentResourceHandlerTest
scoped_refptr<network::ResourceResponse> CreateResponse( scoped_refptr<network::ResourceResponse> CreateResponse(
const char* response_mime_type, const char* response_mime_type,
bool include_no_sniff_header, bool include_no_sniff_header,
bool simulate_range_response,
AccessControlAllowOriginHeader cors_response, AccessControlAllowOriginHeader cors_response,
const char* initiator_origin) { const char* initiator_origin) {
scoped_refptr<network::ResourceResponse> response = scoped_refptr<network::ResourceResponse> response =
base::MakeRefCounted<network::ResourceResponse>(); base::MakeRefCounted<network::ResourceResponse>();
scoped_refptr<net::HttpResponseHeaders> response_headers = scoped_refptr<net::HttpResponseHeaders> response_headers =
base::MakeRefCounted<net::HttpResponseHeaders>(""); base::MakeRefCounted<net::HttpResponseHeaders>(
simulate_range_response ? "HTTP/1.1 206 OK" : "HTTP/1.1 200 OK");
// Content-Type header. // Content-Type header.
std::string charset; std::string charset;
...@@ -1127,6 +1216,12 @@ class CrossSiteDocumentResourceHandlerTest ...@@ -1127,6 +1216,12 @@ class CrossSiteDocumentResourceHandlerTest
if (include_no_sniff_header) if (include_no_sniff_header)
response_headers->AddHeader("X-Content-Type-Options: nosniff"); response_headers->AddHeader("X-Content-Type-Options: nosniff");
// Range response. The product code doesn't currently look at the exact
// range specified, so we can get away with testing with arbitrary/random
// values.
if (simulate_range_response)
response_headers->AddHeader("Content-Range: bytes 200-1000/67589");
// CORS header. // CORS header.
if (cors_response == AccessControlAllowOriginHeader::kAllowAny) { if (cors_response == AccessControlAllowOriginHeader::kAllowAny) {
response_headers->AddHeader("Access-Control-Allow-Origin: *"); response_headers->AddHeader("Access-Control-Allow-Origin: *");
...@@ -1231,7 +1326,8 @@ TEST_P(CrossSiteDocumentResourceHandlerTest, ResponseBlocking) { ...@@ -1231,7 +1326,8 @@ TEST_P(CrossSiteDocumentResourceHandlerTest, ResponseBlocking) {
// Set up response based on scenario. // Set up response based on scenario.
scoped_refptr<network::ResourceResponse> response = CreateResponse( scoped_refptr<network::ResourceResponse> response = CreateResponse(
scenario.response_mime_type, scenario.include_no_sniff_header, scenario.response_mime_type, scenario.include_no_sniff_header,
scenario.cors_response, scenario.initiator_origin); scenario.simulate_range_response, scenario.cors_response,
scenario.initiator_origin);
ASSERT_EQ(MockResourceLoader::Status::IDLE, ASSERT_EQ(MockResourceLoader::Status::IDLE,
mock_loader_->OnResponseStarted(response)); mock_loader_->OnResponseStarted(response));
...@@ -1521,7 +1617,8 @@ TEST_P(CrossSiteDocumentResourceHandlerTest, OnWillReadDefer) { ...@@ -1521,7 +1617,8 @@ TEST_P(CrossSiteDocumentResourceHandlerTest, OnWillReadDefer) {
// Set up response based on scenario. // Set up response based on scenario.
scoped_refptr<network::ResourceResponse> response = CreateResponse( scoped_refptr<network::ResourceResponse> response = CreateResponse(
scenario.response_mime_type, scenario.include_no_sniff_header, scenario.response_mime_type, scenario.include_no_sniff_header,
scenario.cors_response, scenario.initiator_origin); scenario.simulate_range_response, scenario.cors_response,
scenario.initiator_origin);
ASSERT_EQ(MockResourceLoader::Status::IDLE, ASSERT_EQ(MockResourceLoader::Status::IDLE,
mock_loader_->OnResponseStarted(response)); mock_loader_->OnResponseStarted(response));
...@@ -1662,7 +1759,8 @@ TEST_P(CrossSiteDocumentResourceHandlerTest, MimeSnifferInterop) { ...@@ -1662,7 +1759,8 @@ TEST_P(CrossSiteDocumentResourceHandlerTest, MimeSnifferInterop) {
// Set up response based on scenario. // Set up response based on scenario.
scoped_refptr<network::ResourceResponse> response = CreateResponse( scoped_refptr<network::ResourceResponse> response = CreateResponse(
scenario.response_mime_type, scenario.include_no_sniff_header, scenario.response_mime_type, scenario.include_no_sniff_header,
scenario.cors_response, scenario.initiator_origin); scenario.simulate_range_response, scenario.cors_response,
scenario.initiator_origin);
// Call OnResponseStarted. Note that MimeSniffingResourceHandler will not // Call OnResponseStarted. Note that MimeSniffingResourceHandler will not
// immediately forward the call to CrossSiteDocumentResourceHandler. // immediately forward the call to CrossSiteDocumentResourceHandler.
......
...@@ -275,25 +275,29 @@ CORB decides whether a response needs protection (i.e. if a response is a JSON, ...@@ -275,25 +275,29 @@ CORB decides whether a response needs protection (i.e. if a response is a JSON,
HTML or XML resource) based on the following: HTML or XML resource) based on the following:
* If the response contains `X-Content-Type-Options: nosniff` response header, * If the response contains `X-Content-Type-Options: nosniff` response header,
or if the response is a 206 response, then the response will be CORB-protected then the response will be CORB-protected
if its `Content-Type` header is one of the following: if its `Content-Type` header is one of the following:
* [HTML MIME type](https://mimesniff.spec.whatwg.org/#html-mime-type) * [HTML MIME type](https://mimesniff.spec.whatwg.org/#html-mime-type)
* [XML MIME type](https://mimesniff.spec.whatwg.org/#xml-mime-type) * [XML MIME type](https://mimesniff.spec.whatwg.org/#xml-mime-type)
(except `image/svg+xml` which is CORB-exempt as described above) (except `image/svg+xml` which is CORB-exempt as described above)
* JSON MIME type - one of `text/json`, `text/json+*`, `text/x-json`, * [JSON MIME type](https://mimesniff.spec.whatwg.org/#json-mime-type)
`text/x-json+*`, `application/json`, `application/json+*` or `*+json`
* `text/plain` * `text/plain`
> [lukasza@chromium.org] Maybe `text/plain` should be allowed if sniffing is not * If the response is a 206 response,
> possible - this would avoid the potentially troublesome and not-yet-understood then the response will be CORB-protected
> blocking reported in some media contexts. if its `Content-Type` header is one of the following:
* [HTML MIME type](https://mimesniff.spec.whatwg.org/#html-mime-type)
* [XML MIME type](https://mimesniff.spec.whatwg.org/#xml-mime-type)
(except `image/svg+xml` which is CORB-exempt as described above)
* [JSON MIME type](https://mimesniff.spec.whatwg.org/#json-mime-type)
* Otherwise, CORB attempts to sniff the response body: * Otherwise, CORB attempts to sniff the response body:
* [HTML MIME type](https://mimesniff.spec.whatwg.org/#html-mime-type) * [HTML MIME type](https://mimesniff.spec.whatwg.org/#html-mime-type)
that sniffs as HTML is CORB-protected that sniffs as HTML is CORB-protected
* [XML MIME type](https://mimesniff.spec.whatwg.org/#xml-mime-type) * [XML MIME type](https://mimesniff.spec.whatwg.org/#xml-mime-type)
(except `image/svg+xml`) that sniffs as XML is CORB-protected (except `image/svg+xml`) that sniffs as XML is CORB-protected
* JSON MIME type that sniffs as JSON is CORB-protected * [JSON MIME type](https://mimesniff.spec.whatwg.org/#json-mime-type)
that sniffs as JSON is CORB-protected
* `text/plain` that sniffs as JSON, HTML or XML is CORB-protected * `text/plain` that sniffs as JSON, HTML or XML is CORB-protected
* Any response (except `text/css`) that begins with * Any response (except `text/css`) that begins with
[a JSON security prefix](https://www.owasp.org/index.php/AJAX_Security_Cheat_Sheet#Protect_against_JSON_Hijacking_for_Older_Browsers) [a JSON security prefix](https://www.owasp.org/index.php/AJAX_Security_Cheat_Sheet#Protect_against_JSON_Hijacking_for_Older_Browsers)
...@@ -399,12 +403,6 @@ HTML's `<canvas>`, etc. ...@@ -399,12 +403,6 @@ HTML's `<canvas>`, etc.
Audio and video resources should see similar impact as images, though 206 Audio and video resources should see similar impact as images, though 206
responses are more likely to occur for media. responses are more likely to occur for media.
> [lukasza@chromium.org] Decide what to do with 206s:
> - html + nosniff = block
> - html + 206 = block
> - text/plain + nosniff = block?
> - text/plain + 206 = allow?
### Observable CORB impact on scripts ### Observable CORB impact on scripts
CORB should have no observable impact on `<script>` tags except for cases where CORB should have no observable impact on `<script>` tags except for cases where
...@@ -736,8 +734,7 @@ spec. ...@@ -736,8 +734,7 @@ spec.
* [HTML MIME type](https://mimesniff.spec.whatwg.org/#html-mime-type) * [HTML MIME type](https://mimesniff.spec.whatwg.org/#html-mime-type)
* [XML MIME type](https://mimesniff.spec.whatwg.org/#xml-mime-type) * [XML MIME type](https://mimesniff.spec.whatwg.org/#xml-mime-type)
(except `image/svg+xml` which is CORB-exempt, per rules above) (except `image/svg+xml` which is CORB-exempt, per rules above)
* JSON MIME type - one of `text/json`, `text/json+*`, `text/x-json`, * [JSON MIME type](https://mimesniff.spec.whatwg.org/#json-mime-type)
`text/x-json+*`, `application/json`, `application/json+*` or `*+json`
* `text/plain` * `text/plain`
* Sniffing to confirm the Content-Type of the response * Sniffing to confirm the Content-Type of the response
...@@ -755,6 +752,6 @@ spec. ...@@ -755,6 +752,6 @@ spec.
then CORB SHOULD allow the response then CORB SHOULD allow the response
if it doesn't if it doesn't
[sniff as XML](https://mimesniff.spec.whatwg.org/#rules-for-identifying-an-unknown-mime-type). [sniff as XML](https://mimesniff.spec.whatwg.org/#rules-for-identifying-an-unknown-mime-type).
* If Content-Type is "JSON MIME type" (see above), * If Content-Type is [JSON MIME type](https://mimesniff.spec.whatwg.org/#json-mime-type),
then CORB SHOULD allow the response then CORB SHOULD allow the response
if it doesn't sniff as JSON. TODO: define "sniff as JSON". if it doesn't sniff as JSON. TODO: define "sniff as JSON".
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