diff options
-rw-r--r-- | chromium/net/base/features.cc | 2 | ||||
-rw-r--r-- | chromium/net/base/features.h | 1 | ||||
-rw-r--r-- | chromium/net/http/http_util.cc | 39 |
3 files changed, 42 insertions, 0 deletions
diff --git a/chromium/net/base/features.cc b/chromium/net/base/features.cc index bf4a03756d2..3fb48cc1078 100644 --- a/chromium/net/base/features.cc +++ b/chromium/net/base/features.cc @@ -305,5 +305,7 @@ const base::Feature kAlpsClientHintParsing{"AlpsClientHintParsing", const base::Feature kShouldKillSessionOnAcceptChMalformed{ "ShouldKillSessionOnAcceptChMalformed", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kBlockNewForbiddenHeaders{ + "BlockNewForbiddenHeaders", base::FEATURE_ENABLED_BY_DEFAULT}; } // namespace features } // namespace net diff --git a/chromium/net/base/features.h b/chromium/net/base/features.h index f462262c244..b169dfdac3e 100644 --- a/chromium/net/base/features.h +++ b/chromium/net/base/features.h @@ -441,6 +441,7 @@ NET_EXPORT extern const base::Feature kAlpsClientHintParsing; // Whether to kill the session on Error::kAcceptChMalformed. NET_EXPORT extern const base::Feature kShouldKillSessionOnAcceptChMalformed; +NET_EXPORT extern const base::Feature kBlockNewForbiddenHeaders; } // namespace features } // namespace net diff --git a/chromium/net/http/http_util.cc b/chromium/net/http/http_util.cc index 40ebbb4a3e9..c8aac63bcff 100644 --- a/chromium/net/http/http_util.cc +++ b/chromium/net/http/http_util.cc @@ -312,6 +312,23 @@ const char* const kForbiddenHeaderFields[] = { "via", }; +// A header string containing any of the following fields with a forbidden +// method name in the value will cause an error. The list comes from the fetch +// standard. +const char* const kForbiddenHeaderFieldsWithForbiddenMethod[] = { + "x-http-method", + "x-http-method-override", + "x-method-override", +}; + +// The forbidden method names that is defined in the fetch standard, and used +// to check the kForbiddenHeaderFileWithForbiddenMethod above. +const char* const kForbiddenMethods[] = { + "connect", + "trace", + "track", +}; + } // namespace // static @@ -335,6 +352,28 @@ bool HttpUtil::IsSafeHeader(base::StringPiece name, base::StringPiece value) { if (base::LowerCaseEqualsASCII(name, field)) return false; } + + if (base::FeatureList::IsEnabled(features::kBlockNewForbiddenHeaders)) { + bool is_forbidden_header_fields_with_forbidden_method = false; + for (const char* field : kForbiddenHeaderFieldsWithForbiddenMethod) { + if (base::EqualsCaseInsensitiveASCII(name, field)) { + is_forbidden_header_fields_with_forbidden_method = true; + break; + } + } + if (is_forbidden_header_fields_with_forbidden_method) { + std::string value_string(value); + ValuesIterator method_iterator(value_string.begin(), value_string.end(), + ','); + while (method_iterator.GetNext()) { + base::StringPiece method = method_iterator.value_piece(); + for (const char* forbidden_method : kForbiddenMethods) { + if (base::EqualsCaseInsensitiveASCII(method, forbidden_method)) + return false; + } + } + } + } return true; } |