[tor-commits] [tor-browser] 08/14: Bug 1790311 - update handling of request headers in Fetch/XHR. r=necko-reviewers, valentin, a=dmeehan

gitolite role git at cupani.torproject.org
Thu Nov 17 14:03:47 UTC 2022


This is an automated email from the git hooks/post-receive script.

richard pushed a commit to branch tor-browser-91.13.0esr-11.5-1
in repository tor-browser.

commit 3a9d2139eee9b9f82b8da794e0af77a3c5a7988a
Author: sunil mayya <smayya at mozilla.com>
AuthorDate: Mon Oct 24 09:17:22 2022 +0000

    Bug 1790311 - update handling of request headers in Fetch/XHR. r=necko-reviewers,valentin, a=dmeehan
    
    Differential Revision: https://phabricator.services.mozilla.com/D157729
---
 dom/base/nsContentUtils.cpp          | 45 ++++++++++++++++++++++++++++++++----
 dom/base/nsContentUtils.h            | 11 ++++++++-
 dom/fetch/FetchUtil.h                |  1 -
 dom/fetch/InternalHeaders.cpp        | 18 +++++++++------
 dom/fetch/InternalHeaders.h          |  5 ++--
 dom/xhr/XMLHttpRequestMainThread.cpp |  3 ++-
 6 files changed, 66 insertions(+), 17 deletions(-)

diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp
index 6dd69d1d81a8..1605b06d6379 100644
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -7166,15 +7166,25 @@ bool nsContentUtils::IsNodeInEditableRegion(nsINode* aNode) {
 }
 
 // static
-bool nsContentUtils::IsForbiddenRequestHeader(const nsACString& aHeader) {
+bool nsContentUtils::IsForbiddenRequestHeader(const nsACString& aHeader,
+                                              const nsACString& aValue) {
   if (IsForbiddenSystemRequestHeader(aHeader)) {
     return true;
   }
 
-  return StringBeginsWith(aHeader, "proxy-"_ns,
-                          nsCaseInsensitiveCStringComparator) ||
-         StringBeginsWith(aHeader, "sec-"_ns,
-                          nsCaseInsensitiveCStringComparator);
+  if ((nsContentUtils::IsOverrideMethodHeader(aHeader) &&
+       nsContentUtils::ContainsForbiddenMethod(aValue))) {
+    return true;
+  }
+
+  if (StringBeginsWith(aHeader, "proxy-"_ns,
+                       nsCaseInsensitiveCStringComparator) ||
+      StringBeginsWith(aHeader, "sec-"_ns,
+                       nsCaseInsensitiveCStringComparator)) {
+    return true;
+  }
+
+  return false;
 }
 
 // static
@@ -7213,6 +7223,31 @@ bool nsContentUtils::IsForbiddenResponseHeader(const nsACString& aHeader) {
           aHeader.LowerCaseEqualsASCII("set-cookie2"));
 }
 
+// static
+bool nsContentUtils::IsOverrideMethodHeader(const nsACString& headerName) {
+  return headerName.EqualsIgnoreCase("x-http-method-override") ||
+         headerName.EqualsIgnoreCase("x-http-method") ||
+         headerName.EqualsIgnoreCase("x-method-override");
+}
+
+// static
+bool nsContentUtils::ContainsForbiddenMethod(const nsACString& headerValue) {
+  bool hasInsecureMethod = false;
+  nsCCharSeparatedTokenizer tokenizer(headerValue, ',');
+
+  while (tokenizer.hasMoreTokens()) {
+    const nsDependentCSubstring& value = tokenizer.nextToken();
+
+    if (value.EqualsIgnoreCase("connect") || value.EqualsIgnoreCase("trace") ||
+        value.EqualsIgnoreCase("track")) {
+      hasInsecureMethod = true;
+      break;
+    }
+  }
+
+  return hasInsecureMethod;
+}
+
 // static
 bool nsContentUtils::IsCorsUnsafeRequestHeaderValue(
     const nsACString& aHeaderValue) {
diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h
index bb5c84886af9..03c6d6822d2f 100644
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -2749,7 +2749,8 @@ class nsContentUtils {
    * Returns whether a given header is forbidden for an XHR or fetch
    * request.
    */
-  static bool IsForbiddenRequestHeader(const nsACString& aHeader);
+  static bool IsForbiddenRequestHeader(const nsACString& aHeader,
+                                       const nsACString& aValue);
 
   /**
    * Returns whether a given header is forbidden for a system XHR
@@ -2757,6 +2758,14 @@ class nsContentUtils {
    */
   static bool IsForbiddenSystemRequestHeader(const nsACString& aHeader);
 
+  /**
+   * Checks whether the header overrides any http methods
+   */
+  static bool IsOverrideMethodHeader(const nsACString& headerName);
+  /**
+   * Checks whether the  header value contains any forbidden method
+   */
+  static bool ContainsForbiddenMethod(const nsACString& headerValue);
   /**
    * Returns whether a given header has characters that aren't permitted
    */
diff --git a/dom/fetch/FetchUtil.h b/dom/fetch/FetchUtil.h
index 5907e209a4f7..f2508d5cd24c 100644
--- a/dom/fetch/FetchUtil.h
+++ b/dom/fetch/FetchUtil.h
@@ -39,7 +39,6 @@ class FetchUtil final {
    */
   static nsresult GetValidRequestMethod(const nsACString& aMethod,
                                         nsCString& outMethod);
-
   /**
    * Extracts an HTTP header from a substring range.
    */
diff --git a/dom/fetch/InternalHeaders.cpp b/dom/fetch/InternalHeaders.cpp
index 37a5e0fadcaa..45cb2aa5c4dc 100644
--- a/dom/fetch/InternalHeaders.cpp
+++ b/dom/fetch/InternalHeaders.cpp
@@ -6,6 +6,7 @@
 
 #include "mozilla/dom/InternalHeaders.h"
 
+#include "FetchUtil.h"
 #include "mozilla/dom/FetchTypes.h"
 #include "mozilla/ErrorResult.h"
 
@@ -56,11 +57,11 @@ bool InternalHeaders::IsValidHeaderValue(const nsCString& aLowerName,
   }
 
   // Step 4
-  if (mGuard == HeadersGuardEnum::Request &&
-      IsForbiddenRequestHeader(aLowerName)) {
-    return false;
+  if (mGuard == HeadersGuardEnum::Request) {
+    if (IsForbiddenRequestHeader(aLowerName, aNormalizedValue)) {
+      return false;
+    }
   }
-
   // Step 5
   if (mGuard == HeadersGuardEnum::Request_no_cors) {
     nsAutoCString tempValue;
@@ -161,7 +162,9 @@ void InternalHeaders::Delete(const nsACString& aName, ErrorResult& aRv) {
   }
 
   // Step 3
-  if (IsForbiddenRequestHeader(lowerName)) {
+  nsAutoCString value;
+  GetInternal(lowerName, value, aRv);
+  if (IsForbiddenRequestHeader(lowerName, value)) {
     return;
   }
 
@@ -381,9 +384,10 @@ bool InternalHeaders::IsImmutable(ErrorResult& aRv) const {
   return false;
 }
 
-bool InternalHeaders::IsForbiddenRequestHeader(const nsCString& aName) const {
+bool InternalHeaders::IsForbiddenRequestHeader(const nsCString& aName,
+                                               const nsACString& aValue) const {
   return mGuard == HeadersGuardEnum::Request &&
-         nsContentUtils::IsForbiddenRequestHeader(aName);
+         nsContentUtils::IsForbiddenRequestHeader(aName, aValue);
 }
 
 bool InternalHeaders::IsForbiddenRequestNoCorsHeader(
diff --git a/dom/fetch/InternalHeaders.h b/dom/fetch/InternalHeaders.h
index 2fac237733d7..2841844ef6da 100644
--- a/dom/fetch/InternalHeaders.h
+++ b/dom/fetch/InternalHeaders.h
@@ -131,7 +131,8 @@ class InternalHeaders final {
   bool IsValidHeaderValue(const nsCString& aLowerName,
                           const nsCString& aNormalizedValue, ErrorResult& aRv);
   bool IsImmutable(ErrorResult& aRv) const;
-  bool IsForbiddenRequestHeader(const nsCString& aName) const;
+  bool IsForbiddenRequestHeader(const nsCString& aName,
+                                const nsACString& aValue) const;
   bool IsForbiddenRequestNoCorsHeader(const nsCString& aName) const;
   bool IsForbiddenRequestNoCorsHeader(const nsCString& aName,
                                       const nsACString& aValue) const;
@@ -144,7 +145,7 @@ class InternalHeaders final {
   bool IsInvalidMutableHeader(const nsCString& aName, const nsACString& aValue,
                               ErrorResult& aRv) const {
     return IsInvalidName(aName, aRv) || IsInvalidValue(aValue, aRv) ||
-           IsImmutable(aRv) || IsForbiddenRequestHeader(aName) ||
+           IsImmutable(aRv) || IsForbiddenRequestHeader(aName, aValue) ||
            IsForbiddenRequestNoCorsHeader(aName, aValue) ||
            IsForbiddenResponseHeader(aName);
   }
diff --git a/dom/xhr/XMLHttpRequestMainThread.cpp b/dom/xhr/XMLHttpRequestMainThread.cpp
index c969ee9a88b4..c58a65be2a16 100644
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -3130,7 +3130,8 @@ void XMLHttpRequestMainThread::SetRequestHeader(const nsACString& aName,
 
   // Step 5
   bool isPrivilegedCaller = IsSystemXHR();
-  bool isForbiddenHeader = nsContentUtils::IsForbiddenRequestHeader(aName);
+  bool isForbiddenHeader =
+      nsContentUtils::IsForbiddenRequestHeader(aName, aValue);
   if (!isPrivilegedCaller && isForbiddenHeader) {
     AutoTArray<nsString, 1> params;
     CopyUTF8toUTF16(aName, *params.AppendElement());

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the tor-commits mailing list