Commit 62beb0a0 authored by Takashi Toyoshima's avatar Takashi Toyoshima Committed by Commit Bot

OOR-CORS: move CORS safelist check to services/network

This is a preparation to implement CORS preflight in content/network.
These methods originally in FetchUtils are used to create a blink
ResourceRequest or URLRequest for a CORS preflight request.

Original code roughly implements the mime-type checks, but new
implementation relies on //net API that checks mime-type strictly.
This will cause a behavior change, and some that were in a wrong
format but luckily passed will start failing.

Bug: 803766
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_mojo
Change-Id: Iaac0809d4af9011cf4bcc9e7e431a1b1ad762e0a
Reviewed-on: https://chromium-review.googlesource.com/883861
Commit-Queue: Takashi Toyoshima <toyoshim@chromium.org>
Reviewed-by: default avatarTakeshi Yoshino <tyoshino@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#533986}
parent 03eb3460
......@@ -7,6 +7,8 @@
#include <algorithm>
#include <vector>
#include "net/base/mime_util.h"
#include "net/http/http_request_headers.h"
#include "url/gurl.h"
#include "url/origin.h"
#include "url/url_util.h"
......@@ -16,6 +18,27 @@ namespace {
const char kAsterisk[] = "*";
const char kLowerCaseTrue[] = "true";
// TODO(toyoshim): Consider to move following const variables to
// //net/http/http_request_headers.
const char kHeadMethod[] = "HEAD";
const char kPostMethod[] = "POST";
// TODO(toyoshim): Consider to move the following method to
// //net/base/mime_util, and expose to Blink platform/network in order to
// replace the existing equivalent method in HTTPParser.
// We may prefer to implement a strict RFC2616 media-type
// (https://tools.ietf.org/html/rfc2616#section-3.7) parser.
std::string ExtractMIMETypeFromMediaType(const std::string& media_type) {
std::string::size_type semicolon = media_type.find(';');
std::string top_level_type;
std::string subtype;
if (net::ParseMimeTypeWithoutParameter(media_type.substr(0, semicolon),
&top_level_type, &subtype)) {
return top_level_type + "/" + subtype;
}
return std::string();
}
} // namespace
namespace network {
......@@ -161,6 +184,51 @@ bool IsCORSEnabledRequestMode(mojom::FetchRequestMode mode) {
mode == mojom::FetchRequestMode::kCORSWithForcedPreflight;
}
bool IsCORSSafelistedMethod(const std::string& method) {
// https://fetch.spec.whatwg.org/#cors-safelisted-method
// "A CORS-safelisted method is a method that is `GET`, `HEAD`, or `POST`."
static const std::set<std::string> safe_methods = {
net::HttpRequestHeaders::kGetMethod, kHeadMethod, kPostMethod};
return safe_methods.find(base::ToUpperASCII(method)) != safe_methods.end();
}
bool IsCORSSafelistedContentType(const std::string& media_type) {
static const std::set<std::string> safe_types = {
"application/x-www-form-urlencoded", "multipart/form-data", "text/plain"};
std::string mime_type =
base::ToLowerASCII(ExtractMIMETypeFromMediaType(media_type));
return safe_types.find(mime_type) != safe_types.end();
}
bool IsCORSSafelistedHeader(const std::string& name, const std::string& value) {
// https://fetch.spec.whatwg.org/#cors-safelisted-request-header
// "A CORS-safelisted header is a header whose name is either one of `Accept`,
// `Accept-Language`, and `Content-Language`, or whose name is
// `Content-Type` and value, once parsed, is one of
// `application/x-www-form-urlencoded`, `multipart/form-data`, and
// `text/plain`."
//
// Treat 'Save-Data' as a CORS-safelisted header, since it is added by Chrome
// when Data Saver feature is enabled. Treat inspector headers as a
// CORS-safelisted headers, since they are added by blink when the inspector
// is open.
//
// Treat 'Intervention' as a CORS-safelisted header, since it is added by
// Chrome when an intervention is (or may be) applied.
static const std::set<std::string> safe_names = {
"accept", "accept-language",
"content-language", "x-devtools-emulate-network-conditions-client-id",
"save-data", "intervention"};
std::string lower_name = base::ToLowerASCII(name);
if (safe_names.find(lower_name) != safe_names.end())
return true;
if (lower_name == "content-type")
return IsCORSSafelistedContentType(value);
return false;
}
} // namespace cors
} // namespace network
......@@ -69,6 +69,14 @@ base::Optional<mojom::CORSError> CheckExternalPreflight(
COMPONENT_EXPORT(NETWORK_CPP)
bool IsCORSEnabledRequestMode(mojom::FetchRequestMode mode);
// Checks safelisted request parameters.
COMPONENT_EXPORT(NETWORK_CPP)
bool IsCORSSafelistedMethod(const std::string& method);
COMPONENT_EXPORT(NETWORK_CPP)
bool IsCORSSafelistedContentType(const std::string& name);
COMPONENT_EXPORT(NETWORK_CPP)
bool IsCORSSafelistedHeader(const std::string& name, const std::string& value);
} // namespace cors
} // namespace network
......
......@@ -297,6 +297,40 @@ TEST_F(CORSTest, CheckPreflightDetectsErrors) {
EXPECT_EQ(mojom::CORSError::kPreflightInvalidAllowExternal, *error3);
}
TEST_F(CORSTest, CheckCORSSafelist) {
// Method check should be case-insensitive.
EXPECT_TRUE(cors::IsCORSSafelistedMethod("get"));
EXPECT_TRUE(cors::IsCORSSafelistedMethod("Get"));
EXPECT_TRUE(cors::IsCORSSafelistedMethod("GET"));
EXPECT_TRUE(cors::IsCORSSafelistedMethod("HEAD"));
EXPECT_TRUE(cors::IsCORSSafelistedMethod("POST"));
EXPECT_FALSE(cors::IsCORSSafelistedMethod("OPTIONS"));
// Content-Type check should be case-insensitive, and should ignore spaces and
// parameters such as charset after a semicolon.
EXPECT_TRUE(
cors::IsCORSSafelistedContentType("application/x-www-form-urlencoded"));
EXPECT_TRUE(cors::IsCORSSafelistedContentType("multipart/form-data"));
EXPECT_TRUE(cors::IsCORSSafelistedContentType("text/plain"));
EXPECT_TRUE(cors::IsCORSSafelistedContentType("TEXT/PLAIN"));
EXPECT_TRUE(cors::IsCORSSafelistedContentType("text/plain;charset=utf-8"));
EXPECT_TRUE(cors::IsCORSSafelistedContentType(" text/plain ;charset=utf-8"));
EXPECT_FALSE(cors::IsCORSSafelistedContentType("text/html"));
// Header check should be case-insensitive. Value must be considered only for
// Content-Type.
EXPECT_TRUE(cors::IsCORSSafelistedHeader("accept", "text/html"));
EXPECT_TRUE(cors::IsCORSSafelistedHeader("Accept-Language", "en"));
EXPECT_TRUE(cors::IsCORSSafelistedHeader("Content-Language", "ja"));
EXPECT_TRUE(cors::IsCORSSafelistedHeader(
"x-devtools-emulate-network-conditions-client-id", ""));
EXPECT_TRUE(cors::IsCORSSafelistedHeader("SAVE-DATA", ""));
EXPECT_TRUE(cors::IsCORSSafelistedHeader("Intervention", ""));
EXPECT_FALSE(cors::IsCORSSafelistedHeader("Cache-Control", ""));
EXPECT_TRUE(cors::IsCORSSafelistedHeader("Content-Type", "text/plain"));
EXPECT_FALSE(cors::IsCORSSafelistedHeader("Content-Type", "image/png"));
}
} // namespace
} // namespace network
......@@ -6,7 +6,7 @@
#include <algorithm>
#include <utility>
#include "platform/loader/fetch/FetchUtils.h"
#include "platform/loader/cors/CORS.h"
#include "platform/network/HTTPParsers.h"
#include "platform/wtf/text/StringBuilder.h"
......@@ -131,8 +131,7 @@ void FetchHeaderList::ClearList() {
bool FetchHeaderList::ContainsNonCORSSafelistedHeader() const {
return std::any_of(
header_list_.cbegin(), header_list_.cend(), [](const Header& header) {
return !FetchUtils::IsCORSSafelistedHeader(AtomicString(header.first),
AtomicString(header.second));
return !CORS::IsCORSSafelistedHeader(header.first, header.second);
});
}
......
......@@ -31,6 +31,7 @@
#include "platform/bindings/V8ThrowException.h"
#include "platform/exported/WrappedResourceResponse.h"
#include "platform/loader/SubresourceIntegrity.h"
#include "platform/loader/cors/CORS.h"
#include "platform/loader/fetch/FetchUtils.h"
#include "platform/loader/fetch/ResourceError.h"
#include "platform/loader/fetch/ResourceLoaderOptions.h"
......@@ -741,7 +742,7 @@ void FetchManager::Loader::PerformHTTPFetch() {
: WebURLRequest::ServiceWorkerMode::kAll);
if (request_->Keepalive()) {
if (!WebCORS::IsCORSSafelistedMethod(request.HttpMethod()) ||
if (!CORS::IsCORSSafelistedMethod(request.HttpMethod()) ||
!WebCORS::ContainsOnlyCORSSafelistedOrForbiddenHeaders(
request.HttpHeaderFields())) {
PerformNetworkError(
......
......@@ -8,6 +8,7 @@
#include "bindings/core/v8/V8IteratorResultValue.h"
#include "bindings/core/v8/byte_string_sequence_sequence_or_byte_string_byte_string_record.h"
#include "core/dom/Iterator.h"
#include "platform/loader/cors/CORS.h"
#include "platform/loader/fetch/FetchUtils.h"
#include "platform/wtf/text/WTFString.h"
......@@ -99,14 +100,15 @@ void Headers::append(const String& name,
// "5. Otherwise, if guard is |request-no-CORS| and |name|/|value| is not a
// CORS-safelisted header, return."
if (guard_ == kRequestNoCORSGuard &&
!FetchUtils::IsCORSSafelistedHeader(AtomicString(name),
AtomicString(normalized_value)))
!CORS::IsCORSSafelistedHeader(name, normalized_value)) {
return;
}
// "6. Otherwise, if guard is |response| and |name| is a forbidden response
// header name, return."
if (guard_ == kResponseGuard &&
FetchUtils::IsForbiddenResponseHeaderName(name))
FetchUtils::IsForbiddenResponseHeaderName(name)) {
return;
}
// "7. Append |name|/|value| to header list."
header_list_->Append(name, normalized_value);
}
......@@ -130,13 +132,15 @@ void Headers::remove(const String& name, ExceptionState& exception_state) {
// "4. Otherwise, if guard is |request-no-CORS| and |name|/`invalid` is not
// a CORS-safelisted header, return."
if (guard_ == kRequestNoCORSGuard &&
!FetchUtils::IsCORSSafelistedHeader(AtomicString(name), "invalid"))
!CORS::IsCORSSafelistedHeader(name, "invalid")) {
return;
}
// "5. Otherwise, if guard is |response| and |name| is a forbidden response
// header name, return."
if (guard_ == kResponseGuard &&
FetchUtils::IsForbiddenResponseHeaderName(name))
FetchUtils::IsForbiddenResponseHeaderName(name)) {
return;
}
// "6. Delete |name| from header list."
header_list_->Remove(name);
}
......@@ -196,14 +200,15 @@ void Headers::set(const String& name,
// "5. Otherwise, if guard is |request-no-CORS| and |name|/|value| is not a
// CORS-safelisted header, return."
if (guard_ == kRequestNoCORSGuard &&
!FetchUtils::IsCORSSafelistedHeader(AtomicString(name),
AtomicString(normalized_value)))
!CORS::IsCORSSafelistedHeader(name, normalized_value)) {
return;
}
// "6. Otherwise, if guard is |response| and |name| is a forbidden response
// header name, return."
if (guard_ == kResponseGuard &&
FetchUtils::IsForbiddenResponseHeaderName(name))
FetchUtils::IsForbiddenResponseHeaderName(name)) {
return;
}
// "7. Set |name|/|value| in header list."
header_list_->Set(name, normalized_value);
}
......
......@@ -11,6 +11,7 @@
#include "core/fetch/RequestInit.h"
#include "core/loader/ThreadableLoader.h"
#include "platform/bindings/V8PrivateProperty.h"
#include "platform/loader/cors/CORS.h"
#include "platform/loader/fetch/FetchUtils.h"
#include "platform/loader/fetch/ResourceLoaderOptions.h"
#include "platform/loader/fetch/ResourceRequest.h"
......@@ -329,7 +330,7 @@ Request* Request::CreateRequestWithRequestOrString(
if (r->GetRequest()->Mode() == network::mojom::FetchRequestMode::kNoCORS) {
// "If |r|'s request's method is not a CORS-safelisted method, throw a
// TypeError."
if (!FetchUtils::IsCORSSafelistedMethod(r->GetRequest()->Method())) {
if (!CORS::IsCORSSafelistedMethod(r->GetRequest()->Method())) {
exception_state.ThrowTypeError("'" + r->GetRequest()->Method() +
"' is unsupported in no-cors mode.");
return nullptr;
......
......@@ -51,7 +51,6 @@
#include "platform/exported/WrappedResourceRequest.h"
#include "platform/loader/cors/CORS.h"
#include "platform/loader/fetch/FetchParameters.h"
#include "platform/loader/fetch/FetchUtils.h"
#include "platform/loader/fetch/Resource.h"
#include "platform/loader/fetch/ResourceFetcher.h"
#include "platform/loader/fetch/ResourceLoader.h"
......@@ -497,7 +496,7 @@ void DocumentThreadableLoader::MakeCrossOriginAccessRequestBlinkCORS(
// the user's input). For example, referrer. We need to accept them. For
// security, we must reject forbidden headers/methods at the point we
// accept user's input. Not here.
if (WebCORS::IsCORSSafelistedMethod(request.HttpMethod()) &&
if (CORS::IsCORSSafelistedMethod(request.HttpMethod()) &&
WebCORS::ContainsOnlyCORSSafelistedOrForbiddenHeaders(
request.HttpHeaderFields())) {
PrepareCrossOriginRequest(cross_origin_request);
......
......@@ -68,6 +68,7 @@
#include "platform/blob/BlobData.h"
#include "platform/exported/WrappedResourceResponse.h"
#include "platform/feature_policy/FeaturePolicy.h"
#include "platform/loader/cors/CORS.h"
#include "platform/loader/fetch/FetchUtils.h"
#include "platform/loader/fetch/ResourceError.h"
#include "platform/loader/fetch/ResourceLoaderOptions.h"
......@@ -1064,7 +1065,7 @@ void XMLHttpRequest::CreateRequest(scoped_refptr<EncodedFormData> http_body,
// in case the upload listeners are added after the request is started.
upload_events_allowed_ =
same_origin_request_ || upload_events ||
!FetchUtils::IsCORSSafelistedMethod(method_) ||
!CORS::IsCORSSafelistedMethod(method_) ||
!FetchUtils::ContainsOnlyCORSSafelistedHeaders(request_headers_);
ResourceRequest request(url_);
......
......@@ -20,6 +20,7 @@
#include "modules/serviceworkers/ServiceWorkerRegistration.h"
#include "platform/bindings/ScriptState.h"
#include "platform/bindings/V8ThrowException.h"
#include "platform/loader/cors/CORS.h"
#include "platform/loader/fetch/FetchUtils.h"
#include "platform/network/NetworkUtils.h"
#include "platform/weborigin/KURL.h"
......@@ -128,7 +129,7 @@ bool ShouldBlockCORSPreflight(ExecutionContext* execution_context,
// Requests that are more involved than what is possible with HTML's form
// element require a CORS-preflight request.
// https://fetch.spec.whatwg.org/#main-fetch
if (!FetchUtils::IsCORSSafelistedMethod(web_request.Method()) ||
if (!CORS::IsCORSSafelistedMethod(web_request.Method()) ||
!FetchUtils::ContainsOnlyCORSSafelistedHeaders(web_request.Headers())) {
return true;
}
......
......@@ -16,7 +16,7 @@
#include "core/loader/PingLoader.h"
#include "core/typed_arrays/DOMArrayBufferView.h"
#include "platform/bindings/ScriptState.h"
#include "platform/loader/fetch/FetchUtils.h"
#include "platform/loader/cors/CORS.h"
namespace blink {
......@@ -91,7 +91,7 @@ bool NavigatorBeacon::SendBeaconImpl(
data.GetAsArrayBufferView().View());
} else if (data.IsBlob()) {
Blob* blob = data.GetAsBlob();
if (!FetchUtils::IsCORSSafelistedContentType(AtomicString(blob->type()))) {
if (!CORS::IsCORSSafelistedContentType(blob->type())) {
UseCounter::Count(context,
WebFeature::kSendBeaconWithNonSimpleContentType);
if (RuntimeEnabledFeatures::
......
......@@ -57,7 +57,7 @@ String CreateAccessControlRequestHeadersHeader(
const WebHTTPHeaderMap& headers) {
Vector<String> filtered_headers;
for (const auto& header : headers.GetHTTPHeaderMap()) {
if (FetchUtils::IsCORSSafelistedHeader(header.key, header.value)) {
if (CORS::IsCORSSafelistedHeader(header.key, header.value)) {
// Exclude CORS-safelisted headers.
continue;
}
......@@ -297,11 +297,6 @@ WebString ListOfCORSEnabledURLSchemes() {
return SchemeRegistry::ListOfCORSEnabledURLSchemes();
}
// https://fetch.spec.whatwg.org/#cors-safelisted-method
bool IsCORSSafelistedMethod(const WebString& method) {
return FetchUtils::IsCORSSafelistedMethod(method);
}
bool ContainsOnlyCORSSafelistedOrForbiddenHeaders(const WebHTTPHeaderMap& map) {
return FetchUtils::ContainsOnlyCORSSafelistedOrForbiddenHeaders(
map.GetHTTPHeaderMap());
......
......@@ -29,6 +29,7 @@
#include <memory>
#include "base/time/default_tick_clock.h"
#include "base/time/tick_clock.h"
#include "platform/loader/cors/CORS.h"
#include "platform/loader/fetch/FetchUtils.h"
#include "platform/loader/fetch/ResourceResponse.h"
#include "platform/network/http_names.h"
......@@ -170,7 +171,7 @@ bool WebCORSPreflightResultCacheItem::AllowsCrossOriginMethod(
const WebString& method,
WebString& error_description) const {
if (methods_.find(method.Ascii().data()) != methods_.end() ||
FetchUtils::IsCORSSafelistedMethod(method)) {
CORS::IsCORSSafelistedMethod(method)) {
return true;
}
......@@ -193,7 +194,7 @@ bool WebCORSPreflightResultCacheItem::AllowsCrossOriginHeaders(
for (const auto& header : request_headers.GetHTTPHeaderMap()) {
if (headers_.find(header.key.Ascii().data()) == headers_.end() &&
!FetchUtils::IsCORSSafelistedHeader(header.key, header.value) &&
!CORS::IsCORSSafelistedHeader(header.key, header.value) &&
!FetchUtils::IsForbiddenHeaderName(header.key)) {
error_description = String::Format(
"Request header field %s is not allowed by "
......
......@@ -237,6 +237,29 @@ bool IsCORSEnabledRequestMode(network::mojom::FetchRequestMode request_mode) {
return network::cors::IsCORSEnabledRequestMode(request_mode);
}
bool IsCORSSafelistedMethod(const String& method) {
DCHECK(!method.IsNull());
CString utf8_method = method.Utf8();
return network::cors::IsCORSSafelistedMethod(
std::string(utf8_method.data(), utf8_method.length()));
}
bool IsCORSSafelistedContentType(const String& media_type) {
CString utf8_media_type = media_type.Utf8();
return network::cors::IsCORSSafelistedContentType(
std::string(utf8_media_type.data(), utf8_media_type.length()));
}
bool IsCORSSafelistedHeader(const String& name, const String& value) {
DCHECK(!name.IsNull());
DCHECK(!value.IsNull());
CString utf8_name = name.Utf8();
CString utf8_value = value.Utf8();
return network::cors::IsCORSSafelistedHeader(
std::string(utf8_name.data(), utf8_name.length()),
std::string(utf8_value.data(), utf8_value.length()));
}
} // namespace CORS
} // namespace blink
......@@ -56,6 +56,13 @@ PLATFORM_EXPORT WTF::Optional<network::mojom::CORSError> CheckExternalPreflight(
PLATFORM_EXPORT bool IsCORSEnabledRequestMode(network::mojom::FetchRequestMode);
// Thin wrapper functions that will not be removed even after out-of-renderer
// CORS is enabled.
PLATFORM_EXPORT bool IsCORSSafelistedMethod(const String& method);
PLATFORM_EXPORT bool IsCORSSafelistedContentType(const String&);
PLATFORM_EXPORT bool IsCORSSafelistedHeader(const String& name,
const String& value);
} // namespace CORS
} // namespace blink
......
......@@ -4,6 +4,7 @@
#include "platform/loader/fetch/FetchUtils.h"
#include "platform/loader/cors/CORS.h"
#include "platform/network/HTTPHeaderMap.h"
#include "platform/network/HTTPParsers.h"
#include "platform/network/http_names.h"
......@@ -75,53 +76,6 @@ const ForbiddenHeaderNames& ForbiddenHeaderNames::Get() {
} // namespace
bool FetchUtils::IsCORSSafelistedMethod(const String& method) {
// https://fetch.spec.whatwg.org/#cors-safelisted-method
// "A CORS-safelisted method is a method that is `GET`, `HEAD`, or `POST`."
return method == HTTPNames::GET || method == HTTPNames::HEAD ||
method == HTTPNames::POST;
}
bool FetchUtils::IsCORSSafelistedHeader(const AtomicString& name,
const AtomicString& value) {
// https://fetch.spec.whatwg.org/#cors-safelisted-request-header
// "A CORS-safelisted header is a header whose name is either one of `Accept`,
// `Accept-Language`, and `Content-Language`, or whose name is
// `Content-Type` and value, once parsed, is one of
// `application/x-www-form-urlencoded`, `multipart/form-data`, and
// `text/plain`."
//
// Treat 'Save-Data' as a CORS-safelisted header, since it is added by Chrome
// when Data Saver feature is enabled. Treat inspector headers as a
// CORS-safelisted headers, since they are added by blink when the inspector
// is open.
//
// Treat 'Intervention' as a CORS-safelisted header, since it is added by
// Chrome when an intervention is (or may be) applied.
if (EqualIgnoringASCIICase(name, "accept") ||
EqualIgnoringASCIICase(name, "accept-language") ||
EqualIgnoringASCIICase(name, "content-language") ||
EqualIgnoringASCIICase(
name, HTTPNames::X_DevTools_Emulate_Network_Conditions_Client_Id) ||
EqualIgnoringASCIICase(name, HTTPNames::Save_Data) ||
EqualIgnoringASCIICase(name, "intervention"))
return true;
if (EqualIgnoringASCIICase(name, "content-type"))
return IsCORSSafelistedContentType(value);
return false;
}
bool FetchUtils::IsCORSSafelistedContentType(const AtomicString& media_type) {
AtomicString mime_type = ExtractMIMETypeFromMediaType(media_type);
return EqualIgnoringASCIICase(mime_type,
"application/x-www-form-urlencoded") ||
EqualIgnoringASCIICase(mime_type, "multipart/form-data") ||
EqualIgnoringASCIICase(mime_type, "text/plain");
}
bool FetchUtils::IsForbiddenMethod(const String& method) {
// http://fetch.spec.whatwg.org/#forbidden-method
// "A forbidden method is a method that is a byte case-insensitive match"
......@@ -184,7 +138,7 @@ String FetchUtils::NormalizeHeaderValue(const String& value) {
bool FetchUtils::ContainsOnlyCORSSafelistedHeaders(
const HTTPHeaderMap& header_map) {
for (const auto& header : header_map) {
if (!IsCORSSafelistedHeader(header.key, header.value))
if (!CORS::IsCORSSafelistedHeader(header.key, header.value))
return false;
}
return true;
......@@ -193,7 +147,7 @@ bool FetchUtils::ContainsOnlyCORSSafelistedHeaders(
bool FetchUtils::ContainsOnlyCORSSafelistedOrForbiddenHeaders(
const HTTPHeaderMap& header_map) {
for (const auto& header : header_map) {
if (!IsCORSSafelistedHeader(header.key, header.value) &&
if (!CORS::IsCORSSafelistedHeader(header.key, header.value) &&
!IsForbiddenHeaderName(header.key))
return false;
}
......
......@@ -18,10 +18,6 @@ class PLATFORM_EXPORT FetchUtils {
STATIC_ONLY(FetchUtils);
public:
static bool IsCORSSafelistedMethod(const String& method);
static bool IsCORSSafelistedHeader(const AtomicString& name,
const AtomicString& value);
static bool IsCORSSafelistedContentType(const AtomicString& media_type);
static bool IsForbiddenMethod(const String& method);
static bool IsForbiddenHeaderName(const String& name);
static bool IsForbiddenResponseHeaderName(const String& name);
......
......@@ -80,8 +80,6 @@ BLINK_PLATFORM_EXPORT bool IsNoCORSAllowedContext(
BLINK_PLATFORM_EXPORT WebString ListOfCORSEnabledURLSchemes();
BLINK_PLATFORM_EXPORT bool IsCORSSafelistedMethod(const WebString&);
BLINK_PLATFORM_EXPORT bool ContainsOnlyCORSSafelistedOrForbiddenHeaders(
const WebHTTPHeaderMap&);
......
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