summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Toyoshima <toyoshim@chromium.org>2022-10-24 06:16:27 +0000
committerMichal Klocek <michal.klocek@qt.io>2023-02-03 13:20:23 +0000
commit6b00fc85ab8c85ac058b34db51d9d0e6f47f7d4a (patch)
tree15c782fa14bb497a22bd8fe2dd9edf83f93d425e
parent085efc288be9fb6f1b243a2e790b49db34d208d4 (diff)
downloadqtwebengine-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.cc2
-rw-r--r--chromium/net/base/features.h1
-rw-r--r--chromium/net/http/http_util.cc39
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;
}