diff options
author | Takashi Toyoshima <toyoshim@chromium.org> | 2022-10-24 06:16:27 +0000 |
---|---|---|
committer | Michal Klocek <michal.klocek@qt.io> | 2023-02-03 13:20:23 +0000 |
commit | 6b00fc85ab8c85ac058b34db51d9d0e6f47f7d4a (patch) | |
tree | 15c782fa14bb497a22bd8fe2dd9edf83f93d425e | |
parent | 085efc288be9fb6f1b243a2e790b49db34d208d4 (diff) | |
download | qtwebengine-chromium-6b00fc85ab8c85ac058b34db51d9d0e6f47f7d4a.tar.gz |
[Backport] CVE-2023-0141: Insufficient policy enforcementn in CORS (2/2)
Manual backport of patch originally reviewed on
https://chromium-review.googlesource.com/c/chromium/src/+/3967950:
Net: Update net::HttpUtil::IsSafeHeader to follow the latest spec
This patch adds new forbidden cases from the fetch standard.
The code is implemented behind a feature flag, but enabled by default.
This is for the case if this change breaks something big in the real
world.
Bug: 1362331
Change-Id: I6d2f4203f89978bd7bd79527f1640a69b4db4c21
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3967950
Reviewed-by: Matt Menke <mmenke@chromium.org>
Commit-Queue: Takashi Toyoshima <toyoshim@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1062673}
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/454296
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
-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; } |