Commit 5b6a88a9 authored by Takashi Toyoshima's avatar Takashi Toyoshima Committed by Commit Bot

OOR-CORS: move fetch forbidden header check to services/network

Since IsForbiddenHeaderName() is needed to be called even in
services/network, this patch moves its implementation from
platform/loader to services/network to be used in network service,
the browser process, and Blink.

DEFINE_THREAD_SAFE_STATIC_LOCAL is not needed outside Blink, and
static local variable can be accessed safely among multiple-threads.

Bug: 803766
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_mojo
Change-Id: Idbd298e9a9528b26b3c0d906dc246303bc9a576b
Reviewed-on: https://chromium-review.googlesource.com/910131
Commit-Queue: Takashi Toyoshima <toyoshim@chromium.org>
Reviewed-by: default avatarYutaka Hirano <yhirano@chromium.org>
Reviewed-by: default avatarTakeshi Yoshino <tyoshino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#536663}
parent a9439cd9
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
#include "base/strings/string_util.h"
#include "net/base/mime_util.h" #include "net/base/mime_util.h"
#include "net/http/http_request_headers.h" #include "net/http/http_request_headers.h"
#include "url/gurl.h" #include "url/gurl.h"
...@@ -217,6 +218,46 @@ bool IsCORSSafelistedHeader(const std::string& name, const std::string& value) { ...@@ -217,6 +218,46 @@ bool IsCORSSafelistedHeader(const std::string& name, const std::string& value) {
return false; return false;
} }
bool IsForbiddenHeader(const std::string& name) {
// http://fetch.spec.whatwg.org/#forbidden-header-name
// "A forbidden header name is a header name that is one of:
// `Accept-Charset`, `Accept-Encoding`, `Access-Control-Request-Headers`,
// `Access-Control-Request-Method`, `Connection`, `Content-Length`,
// `Cookie`, `Cookie2`, `Date`, `DNT`, `Expect`, `Host`, `Keep-Alive`,
// `Origin`, `Referer`, `TE`, `Trailer`, `Transfer-Encoding`, `Upgrade`,
// `User-Agent`, `Via`
// or starts with `Proxy-` or `Sec-` (including when it is just `Proxy-` or
// `Sec-`)."
static const std::set<std::string> forbidden_names = {
"accept-charset",
"accept-encoding",
"access-control-request-headers",
"access-control-request-method",
"connection",
"content-length",
"cookie",
"cookie2",
"date",
"dnt",
"expect",
"host",
"keep-alive",
"origin",
"referer",
"te",
"trailer",
"transfer-encoding",
"upgrade",
"user-agent",
"via"};
const std::string lower_name = base::ToLowerASCII(name);
if (StartsWith(lower_name, "proxy-", base::CompareCase::SENSITIVE) ||
StartsWith(lower_name, "sec-", base::CompareCase::SENSITIVE)) {
return true;
}
return forbidden_names.find(lower_name) != forbidden_names.end();
}
} // namespace cors } // namespace cors
} // namespace network } // namespace network
...@@ -74,6 +74,10 @@ bool IsCORSSafelistedContentType(const std::string& name); ...@@ -74,6 +74,10 @@ bool IsCORSSafelistedContentType(const std::string& name);
COMPONENT_EXPORT(NETWORK_CPP) COMPONENT_EXPORT(NETWORK_CPP)
bool IsCORSSafelistedHeader(const std::string& name, const std::string& value); bool IsCORSSafelistedHeader(const std::string& name, const std::string& value);
// Checks forbidden header in the fetch spec.
// See https://fetch.spec.whatwg.org/#forbidden-header-name.
COMPONENT_EXPORT(NETWORK_CPP) bool IsForbiddenHeader(const std::string& name);
} // namespace cors } // namespace cors
} // namespace network } // namespace network
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "platform/wtf/Threading.h" #include "platform/wtf/Threading.h"
#include "platform/wtf/text/AtomicString.h" #include "platform/wtf/text/AtomicString.h"
#include "platform/wtf/text/WTFString.h" #include "platform/wtf/text/WTFString.h"
#include "services/network/public/cpp/cors/cors.h"
namespace blink { namespace blink {
...@@ -21,59 +22,6 @@ bool IsHTTPWhitespace(UChar chr) { ...@@ -21,59 +22,6 @@ bool IsHTTPWhitespace(UChar chr) {
return chr == ' ' || chr == '\n' || chr == '\t' || chr == '\r'; return chr == ' ' || chr == '\n' || chr == '\t' || chr == '\r';
} }
class ForbiddenHeaderNames {
WTF_MAKE_NONCOPYABLE(ForbiddenHeaderNames);
USING_FAST_MALLOC(ForbiddenHeaderNames);
public:
bool Has(const String& name) const {
return fixed_names_.Contains(name) ||
name.StartsWithIgnoringASCIICase(proxy_header_prefix_) ||
name.StartsWithIgnoringASCIICase(sec_header_prefix_);
}
static const ForbiddenHeaderNames& Get();
private:
ForbiddenHeaderNames();
String proxy_header_prefix_;
String sec_header_prefix_;
HashSet<String, CaseFoldingHash> fixed_names_;
};
ForbiddenHeaderNames::ForbiddenHeaderNames()
: proxy_header_prefix_("proxy-"), sec_header_prefix_("sec-") {
fixed_names_ = {
"accept-charset",
"accept-encoding",
"access-control-request-headers",
"access-control-request-method",
"connection",
"content-length",
"cookie",
"cookie2",
"date",
"dnt",
"expect",
"host",
"keep-alive",
"origin",
"referer",
"te",
"trailer",
"transfer-encoding",
"upgrade",
"user-agent",
"via",
};
}
const ForbiddenHeaderNames& ForbiddenHeaderNames::Get() {
DEFINE_THREAD_SAFE_STATIC_LOCAL(const ForbiddenHeaderNames, instance, ());
return instance;
}
} // namespace } // namespace
bool FetchUtils::IsForbiddenMethod(const String& method) { bool FetchUtils::IsForbiddenMethod(const String& method) {
...@@ -86,17 +34,9 @@ bool FetchUtils::IsForbiddenMethod(const String& method) { ...@@ -86,17 +34,9 @@ bool FetchUtils::IsForbiddenMethod(const String& method) {
} }
bool FetchUtils::IsForbiddenHeaderName(const String& name) { bool FetchUtils::IsForbiddenHeaderName(const String& name) {
// http://fetch.spec.whatwg.org/#forbidden-header-name const CString utf8_name = name.Utf8();
// "A forbidden header name is a header names that is one of: return network::cors::IsForbiddenHeader(
// `Accept-Charset`, `Accept-Encoding`, `Access-Control-Request-Headers`, std::string(utf8_name.data(), utf8_name.length()));
// `Access-Control-Request-Method`, `Connection`,
// `Content-Length, Cookie`, `Cookie2`, `Date`, `DNT`, `Expect`, `Host`,
// `Keep-Alive`, `Origin`, `Referer`, `TE`, `Trailer`,
// `Transfer-Encoding`, `Upgrade`, `User-Agent`, `Via`
// or starts with `Proxy-` or `Sec-` (including when it is just `Proxy-` or
// `Sec-`)."
return ForbiddenHeaderNames::Get().Has(name);
} }
bool FetchUtils::IsForbiddenResponseHeaderName(const String& name) { bool FetchUtils::IsForbiddenResponseHeaderName(const String& name) {
......
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