[prev in list] [next in list] [prev in thread] [next in thread] 

List:       oss-security
Subject:    [oss-security] [CVE-2021-44528] Possible Open Redirect in Host Authorization Middleware
From:       Aaron Patterson <aaron.patterson () gmail ! com>
Date:       2021-12-14 20:29:20
Message-ID: CALBaBG_3ddr3XE9JQsi60L3xXwMvnPiBjyA1S8NRUWyKsCn2Eg () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


There is a possible open redirect vulnerability in the Host Authorization
middleware in Action Pack. This vulnerability has been assigned the CVE
identifier CVE-2021-44528.

Versions Affected:  >= 6.0.0.
Not affected:       < 6.0.0
Fixed Versions:     6.1.4.2, 6.0.4.2, 7.0.0.rc2

Impact
------
Specially crafted "X-Forwarded-Host" headers in combination with certain
"allowed host" formats can cause the Host Authorization middleware in Action
Pack to redirect users to a malicious website.

Impacted applications will have allowed hosts with a leading dot. For
example,
configuration files that look like this:

```
config.hosts <<  '.EXAMPLE.com'
```

When an allowed host contains a leading dot, a specially crafted Host header
can be used to redirect to a malicious website.

This vulnerability is similar to CVE-2021-22881 and CVE-2021-22942.

Releases
--------
The fixed releases are available at the normal locations.

Patches
-------
To aid users who aren't able to upgrade immediately we have provided
patches for
the two supported release series. They are in git-am format and consist of a
single changeset.

* 6-0-host-authorzation-open-redirect.patch - Patch for 6.0 series
* 6-1-host-authorzation-open-redirect.patch - Patch for 6.1 series
* 7-0-host-authorzation-open-redirect.patch - Patch for 7.0 series

Please note that only the 6.1.Z, 6.0.Z, and 5.2.Z series are supported at
present. Users of earlier unsupported releases are advised to upgrade as
soon
as possible as we cannot guarantee the continued availability of security
fixes for unsupported releases.

Credits
-------
Thanks to [@krynos](https://hackerone.com/krynos?type=user) for originally
reporting this!

Huge thanks to
[@stefschenkelaars](https://hackerone.com/stefschenkelaars?type=user) for
writing a patch along with tests to fix this issue!


-- 
Aaron Patterson
http://tenderlovemaking.com/

[Attachment #5 (text/html)]

<div dir="ltr">There is a possible open redirect vulnerability in the Host \
Authorization<br>middleware in Action Pack. This vulnerability has been assigned the \
CVE<br>identifier CVE-2021-44528.<br><br>Versions Affected:   &gt;= 6.0.0.<br>Not affected:     \
&lt; 6.0.0<br>Fixed Versions:       6.1.4.2, 6.0.4.2, \
7.0.0.rc2<br><br>Impact<br>------<br>Specially crafted &quot;X-Forwarded-Host&quot; headers in \
combination with certain<br>&quot;allowed host&quot; formats can cause the Host Authorization \
middleware in Action<br>Pack to redirect users to a malicious website.<br><br>Impacted \
applications will have allowed hosts with a leading dot. For example,<br>configuration files \
that look like this:<br><br>```<br>config.hosts &lt;&lt;   \
&#39;.EXAMPLE.com&#39;<br>```<br><br>When an allowed host contains a leading dot, a specially \
crafted Host header<br>can be used to redirect to a malicious website.<br><br>This \
vulnerability is similar to CVE-2021-22881 and \
CVE-2021-22942.<br><br>Releases<br>--------<br>The fixed releases are available at the normal \
locations.<br><br>Patches<br>-------<br>To aid users who aren&#39;t able to upgrade immediately \
we have provided patches for<br>the two supported release series. They are in git-am format and \
consist of a<br>single changeset.<br><br>* 6-0-host-authorzation-open-redirect.patch - Patch \
for 6.0 series<br>* 6-1-host-authorzation-open-redirect.patch - Patch for 6.1 series<br>* \
7-0-host-authorzation-open-redirect.patch - Patch for 7.0 series<br><br>Please note that only \
the 6.1.Z, 6.0.Z, and 5.2.Z series are supported at<br>present. Users of earlier unsupported \
releases are advised to upgrade as soon<br>as possible as we cannot guarantee the continued \
availability of security<br>fixes for unsupported releases.<br><br>Credits<br>-------<br>Thanks \
to [@krynos](<a href="https://hackerone.com/krynos?type=user">https://hackerone.com/krynos?type=user</a>) \
for originally<br>reporting this!<br><br>Huge thanks to<br>[@stefschenkelaars](<a \
href="https://hackerone.com/stefschenkelaars?type=user">https://hackerone.com/stefschenkelaars?type=user</a>) \
for<br>writing a patch along with tests to fix this issue!<br><br><div><br></div>-- <br><div \
dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">Aaron Patterson<br><a \
href="http://tenderlovemaking.com/" \
target="_blank">http://tenderlovemaking.com/</a></div></div>

--000000000000f6a8c705d3210bb5--


["6-0-host-authorzation-open-redirect.patch" (application/octet-stream)]

From fd6a64fef1d0f7f40a8d4b046da882e83163299c Mon Sep 17 00:00:00 2001
From: Stef Schenkelaars <stef.schenkelaars@gmail.com>
Date: Wed, 7 Jul 2021 12:06:32 +0200
Subject: [PATCH] Fix invalid forwarded host vulnerability

Prior to this commit, it was possible to pass an unvalidated host
through the `X-Forwarded-Host` header. If the value of the header
was prefixed with a invalid domain character (for example a `/`),
it was always accepted as the actual host of that request.

Since this host is used for all url helpers, an attacker could change
generated links and redirects. If the header is set to
`X-Forwarded-Host: //evil.hacker`, a redirect will be send to
`https:////evil.hacker/`. Browsers will ignore these four slashes
and redirect the user.

[CVE-2021-44528]
---
 .../middleware/host_authorization.rb          | 10 +--
 .../test/dispatch/host_authorization_test.rb  | 89 ++++++++++++++++++-
 2 files changed, 91 insertions(+), 8 deletions(-)

diff --git a/actionpack/lib/action_dispatch/middleware/host_authorization.rb \
b/actionpack/lib/action_dispatch/middleware/host_authorization.rb index 8e39aee87d..ca2b17cb8b \
                100644
--- a/actionpack/lib/action_dispatch/middleware/host_authorization.rb
+++ b/actionpack/lib/action_dispatch/middleware/host_authorization.rb
@@ -46,7 +46,7 @@ def sanitize_regexp(host)
 
         def sanitize_string(host)
           if host.start_with?(".")
-            /\A(.+\.)?#{Regexp.escape(host[1..-1])}\z/i
+            /\A([a-z0-9-]+\.)?#{Regexp.escape(host[1..-1])}\z/i
           else
             /\A#{Regexp.escape host}\z/i
           end
@@ -86,13 +86,9 @@ def call(env)
     end
 
     private
-      HOSTNAME = /[a-z0-9.-]+|\[[a-f0-9]*:[a-f0-9.:]+\]/i
-      VALID_ORIGIN_HOST = /\A(#{HOSTNAME})(?::\d+)?\z/
-      VALID_FORWARDED_HOST = /(?:\A|,[ ]?)(#{HOSTNAME})(?::\d+)?\z/
-
       def authorized?(request)
-        origin_host = request.get_header("HTTP_HOST")&.slice(VALID_ORIGIN_HOST, 1) || ""
-        forwarded_host = request.x_forwarded_host&.slice(VALID_FORWARDED_HOST, 1) || ""
+        origin_host = request.get_header("HTTP_HOST")
+        forwarded_host = request.x_forwarded_host&.split(/,\s?/)&.last
 
         @permissions.allows?(origin_host) && (forwarded_host.blank? || \
@permissions.allows?(forwarded_host))  end
diff --git a/actionpack/test/dispatch/host_authorization_test.rb \
b/actionpack/test/dispatch/host_authorization_test.rb index 63562c9046..8b29dabf0c 100644
--- a/actionpack/test/dispatch/host_authorization_test.rb
+++ b/actionpack/test/dispatch/host_authorization_test.rb
@@ -155,6 +155,44 @@ class HostAuthorizationTest < ActionDispatch::IntegrationTest
     assert_match "Blocked host: 127.0.0.1", response.body
   end
 
+  test "blocks requests with spoofed relative X-FORWARDED-HOST" do
+    @app = ActionDispatch::HostAuthorization.new(App, ["www.example.com"])
+
+    get "/", env: {
+      "HTTP_X_FORWARDED_HOST" => "//randomhost.com",
+      "HOST" => "www.example.com",
+      "action_dispatch.show_detailed_exceptions" => true
+    }
+
+    assert_response :forbidden
+    assert_match "Blocked host: //randomhost.com", response.body
+  end
+
+  test "forwarded secondary hosts are allowed when permitted" do
+    @app = ActionDispatch::HostAuthorization.new(App, ".domain.com")
+
+    get "/", env: {
+      "HTTP_X_FORWARDED_HOST" => "example.com, my-sub.domain.com",
+      "HOST" => "domain.com",
+    }
+
+    assert_response :ok
+    assert_equal "Success", body
+  end
+
+  test "forwarded secondary hosts are blocked when mismatch" do
+    @app = ActionDispatch::HostAuthorization.new(App, "domain.com")
+
+    get "/", env: {
+      "HTTP_X_FORWARDED_HOST" => "domain.com, evil.com",
+      "HOST" => "domain.com",
+      "action_dispatch.show_detailed_exceptions" => true
+    }
+
+    assert_response :forbidden
+    assert_match "Blocked host: evil.com", response.body
+  end
+
   test "does not consider IP addresses in X-FORWARDED-HOST spoofed when disabled" do
     @app = ActionDispatch::HostAuthorization.new(App, nil)
 
@@ -191,11 +229,23 @@ class HostAuthorizationTest < ActionDispatch::IntegrationTest
     assert_match "Blocked host: sub.domain.com", response.body
   end
 
+  test "sub-sub domains should not be permitted" do
+    @app = ActionDispatch::HostAuthorization.new(App, ".domain.com")
+
+    get "/", env: {
+      "HOST" => "secondary.sub.domain.com",
+      "action_dispatch.show_detailed_exceptions" => true
+    }
+
+    assert_response :forbidden
+    assert_match "Blocked host: secondary.sub.domain.com", response.body
+  end
+
   test "forwarded hosts are allowed when permitted" do
     @app = ActionDispatch::HostAuthorization.new(App, ".domain.com")
 
     get "/", env: {
-      "HTTP_X_FORWARDED_HOST" => "sub.domain.com",
+      "HTTP_X_FORWARDED_HOST" => "my-sub.domain.com",
       "HOST" => "domain.com",
     }
 
@@ -224,4 +274,41 @@ class HostAuthorizationTest < ActionDispatch::IntegrationTest
     assert_response :forbidden
     assert_match "Blocked host: sub-example.com", response.body
   end
+
+  test "lots of NG hosts" do
+    ng_hosts = [
+      "hacker%E3%80%82com",
+      "hacker%00.com",
+      "www.theirsite.com@yoursite.com",
+      "hacker.com/test/",
+      "hacker%252ecom",
+      ".hacker.com",
+      "/\/\/hacker.com/",
+      "/hacker.com",
+      "../hacker.com",
+      ".hacker.com",
+      "@hacker.com",
+      "hacker.com",
+      "hacker.com%23@example.com",
+      "hacker.com/.jpg",
+      "hacker.com\texample.com/",
+      "hacker.com/example.com",
+      "hacker.com\@example.com",
+      "hacker.com/example.com",
+      "hacker.com/"
+    ]
+
+    @app = ActionDispatch::HostAuthorization.new(App, "example.com")
+
+    ng_hosts.each do |host|
+      get "/", env: {
+        "HTTP_X_FORWARDED_HOST" => host,
+        "HOST" => "example.com",
+        "action_dispatch.show_detailed_exceptions" => true
+      }
+
+      assert_response :forbidden
+      assert_match "Blocked host: #{host}", response.body
+    end
+  end
 end
-- 
2.33.0


["6-1-host-authorzation-open-redirect.patch" (application/octet-stream)]

From aecba3c301b80e9d5a63c30ea1b287bceaf2c107 Mon Sep 17 00:00:00 2001
From: Stef Schenkelaars <stef.schenkelaars@gmail.com>
Date: Wed, 7 Jul 2021 12:06:32 +0200
Subject: [PATCH] Fix invalid forwarded host vulnerability

Prior to this commit, it was possible to pass an unvalidated host
through the `X-Forwarded-Host` header. If the value of the header
was prefixed with a invalid domain character (for example a `/`),
it was always accepted as the actual host of that request.

Since this host is used for all url helpers, an attacker could change
generated links and redirects. If the header is set to
`X-Forwarded-Host: //evil.hacker`, a redirect will be send to
`https:////evil.hacker/`. Browsers will ignore these four slashes
and redirect the user.

[CVE-2021-44528]
---
 .../middleware/host_authorization.rb          | 10 +--
 .../test/dispatch/host_authorization_test.rb  | 89 ++++++++++++++++++-
 2 files changed, 91 insertions(+), 8 deletions(-)

diff --git a/actionpack/lib/action_dispatch/middleware/host_authorization.rb \
b/actionpack/lib/action_dispatch/middleware/host_authorization.rb index 62f0866f3e..93610e5097 \
                100644
--- a/actionpack/lib/action_dispatch/middleware/host_authorization.rb
+++ b/actionpack/lib/action_dispatch/middleware/host_authorization.rb
@@ -51,7 +51,7 @@ def sanitize_regexp(host)
 
         def sanitize_string(host)
           if host.start_with?(".")
-            /\A(.+\.)?#{Regexp.escape(host[1..-1])}\z/i
+            /\A([a-z0-9-]+\.)?#{Regexp.escape(host[1..-1])}\z/i
           else
             /\A#{Regexp.escape host}\z/i
           end
@@ -102,13 +102,9 @@ def call(env)
     end
 
     private
-      HOSTNAME = /[a-z0-9.-]+|\[[a-f0-9]*:[a-f0-9.:]+\]/i
-      VALID_ORIGIN_HOST = /\A(#{HOSTNAME})(?::\d+)?\z/
-      VALID_FORWARDED_HOST = /(?:\A|,[ ]?)(#{HOSTNAME})(?::\d+)?\z/
-
       def authorized?(request)
-        origin_host = request.get_header("HTTP_HOST")&.slice(VALID_ORIGIN_HOST, 1) || ""
-        forwarded_host = request.x_forwarded_host&.slice(VALID_FORWARDED_HOST, 1) || ""
+        origin_host = request.get_header("HTTP_HOST")
+        forwarded_host = request.x_forwarded_host&.split(/,\s?/)&.last
 
         @permissions.allows?(origin_host) && (forwarded_host.blank? || \
@permissions.allows?(forwarded_host))  end
diff --git a/actionpack/test/dispatch/host_authorization_test.rb \
b/actionpack/test/dispatch/host_authorization_test.rb index d6e366bb1a..ff0a6df503 100644
--- a/actionpack/test/dispatch/host_authorization_test.rb
+++ b/actionpack/test/dispatch/host_authorization_test.rb
@@ -155,6 +155,44 @@ class HostAuthorizationTest < ActionDispatch::IntegrationTest
     assert_match "Blocked host: 127.0.0.1", response.body
   end
 
+  test "blocks requests with spoofed relative X-FORWARDED-HOST" do
+    @app = ActionDispatch::HostAuthorization.new(App, ["www.example.com"])
+
+    get "/", env: {
+      "HTTP_X_FORWARDED_HOST" => "//randomhost.com",
+      "HOST" => "www.example.com",
+      "action_dispatch.show_detailed_exceptions" => true
+    }
+
+    assert_response :forbidden
+    assert_match "Blocked host: //randomhost.com", response.body
+  end
+
+  test "forwarded secondary hosts are allowed when permitted" do
+    @app = ActionDispatch::HostAuthorization.new(App, ".domain.com")
+
+    get "/", env: {
+      "HTTP_X_FORWARDED_HOST" => "example.com, my-sub.domain.com",
+      "HOST" => "domain.com",
+    }
+
+    assert_response :ok
+    assert_equal "Success", body
+  end
+
+  test "forwarded secondary hosts are blocked when mismatch" do
+    @app = ActionDispatch::HostAuthorization.new(App, "domain.com")
+
+    get "/", env: {
+      "HTTP_X_FORWARDED_HOST" => "domain.com, evil.com",
+      "HOST" => "domain.com",
+      "action_dispatch.show_detailed_exceptions" => true
+    }
+
+    assert_response :forbidden
+    assert_match "Blocked host: evil.com", response.body
+  end
+
   test "does not consider IP addresses in X-FORWARDED-HOST spoofed when disabled" do
     @app = ActionDispatch::HostAuthorization.new(App, nil)
 
@@ -191,11 +229,23 @@ class HostAuthorizationTest < ActionDispatch::IntegrationTest
     assert_match "Blocked host: sub.domain.com", response.body
   end
 
+  test "sub-sub domains should not be permitted" do
+    @app = ActionDispatch::HostAuthorization.new(App, ".domain.com")
+
+    get "/", env: {
+      "HOST" => "secondary.sub.domain.com",
+      "action_dispatch.show_detailed_exceptions" => true
+    }
+
+    assert_response :forbidden
+    assert_match "Blocked host: secondary.sub.domain.com", response.body
+  end
+
   test "forwarded hosts are allowed when permitted" do
     @app = ActionDispatch::HostAuthorization.new(App, ".domain.com")
 
     get "/", env: {
-      "HTTP_X_FORWARDED_HOST" => "sub.domain.com",
+      "HTTP_X_FORWARDED_HOST" => "my-sub.domain.com",
       "HOST" => "domain.com",
     }
 
@@ -203,6 +253,43 @@ class HostAuthorizationTest < ActionDispatch::IntegrationTest
     assert_equal "Success", body
   end
 
+  test "lots of NG hosts" do
+    ng_hosts = [
+      "hacker%E3%80%82com",
+      "hacker%00.com",
+      "www.theirsite.com@yoursite.com",
+      "hacker.com/test/",
+      "hacker%252ecom",
+      ".hacker.com",
+      "/\/\/hacker.com/",
+      "/hacker.com",
+      "../hacker.com",
+      ".hacker.com",
+      "@hacker.com",
+      "hacker.com",
+      "hacker.com%23@example.com",
+      "hacker.com/.jpg",
+      "hacker.com\texample.com/",
+      "hacker.com/example.com",
+      "hacker.com\@example.com",
+      "hacker.com/example.com",
+      "hacker.com/"
+    ]
+
+    @app = ActionDispatch::HostAuthorization.new(App, "example.com")
+
+    ng_hosts.each do |host|
+      get "/", env: {
+        "HTTP_X_FORWARDED_HOST" => host,
+        "HOST" => "example.com",
+        "action_dispatch.show_detailed_exceptions" => true
+      }
+
+      assert_response :forbidden
+      assert_match "Blocked host: #{host}", response.body
+    end
+  end
+
   test "exclude matches allow any host" do
     @app = ActionDispatch::HostAuthorization.new(App, "only.com", exclude: ->(req) { req.path \
== "/foo" })  
-- 
2.33.0


["7-0-host-authorzation-open-redirect.patch" (application/octet-stream)]

From 970d3b2e7387c34663988b0db222d045c34c59c1 Mon Sep 17 00:00:00 2001
From: Stef Schenkelaars <stef.schenkelaars@gmail.com>
Date: Wed, 7 Jul 2021 12:06:32 +0200
Subject: [PATCH] Fix invalid forwarded host vulnerability

Prior to this commit, it was possible to pass an unvalidated host
through the `X-Forwarded-Host` header. If the value of the header
was prefixed with a invalid domain character (for example a `/`),
it was always accepted as the actual host of that request.

Since this host is used for all url helpers, an attacker could change
generated links and redirects. If the header is set to
`X-Forwarded-Host: //evil.hacker`, a redirect will be send to
`https:////evil.hacker/`. Browsers will ignore these four slashes
and redirect the user.

[CVE-2021-44528]
---
 .../middleware/host_authorization.rb          | 10 +--
 .../test/dispatch/host_authorization_test.rb  | 89 ++++++++++++++++++-
 2 files changed, 91 insertions(+), 8 deletions(-)

diff --git a/actionpack/lib/action_dispatch/middleware/host_authorization.rb \
b/actionpack/lib/action_dispatch/middleware/host_authorization.rb index 968e862800..d21bca72c6 \
                100644
--- a/actionpack/lib/action_dispatch/middleware/host_authorization.rb
+++ b/actionpack/lib/action_dispatch/middleware/host_authorization.rb
@@ -52,7 +52,7 @@ def sanitize_regexp(host)
 
         def sanitize_string(host)
           if host.start_with?(".")
-            /\A(.+\.)?#{Regexp.escape(host[1..-1])}\z/i
+            /\A([a-z0-9-]+\.)?#{Regexp.escape(host[1..-1])}\z/i
           else
             /\A#{Regexp.escape host}\z/i
           end
@@ -120,13 +120,9 @@ def call(env)
     end
 
     private
-      HOSTNAME = /[a-z0-9.-]+|\[[a-f0-9]*:[a-f0-9.:]+\]/i
-      VALID_ORIGIN_HOST = /\A(#{HOSTNAME})(?::\d+)?\z/
-      VALID_FORWARDED_HOST = /(?:\A|,[ ]?)(#{HOSTNAME})(?::\d+)?\z/
-
       def authorized?(request)
-        origin_host = request.get_header("HTTP_HOST")&.slice(VALID_ORIGIN_HOST, 1) || ""
-        forwarded_host = request.x_forwarded_host&.slice(VALID_FORWARDED_HOST, 1) || ""
+        origin_host = request.get_header("HTTP_HOST")
+        forwarded_host = request.x_forwarded_host&.split(/,\s?/)&.last
 
         @permissions.allows?(origin_host) && (forwarded_host.blank? || \
@permissions.allows?(forwarded_host))  end
diff --git a/actionpack/test/dispatch/host_authorization_test.rb \
b/actionpack/test/dispatch/host_authorization_test.rb index b98b6492a0..85cb6c7318 100644
--- a/actionpack/test/dispatch/host_authorization_test.rb
+++ b/actionpack/test/dispatch/host_authorization_test.rb
@@ -167,6 +167,44 @@ class HostAuthorizationTest < ActionDispatch::IntegrationTest
     assert_match "Blocked host: 127.0.0.1", response.body
   end
 
+  test "blocks requests with spoofed relative X-FORWARDED-HOST" do
+    @app = ActionDispatch::HostAuthorization.new(App, ["www.example.com"])
+
+    get "/", env: {
+      "HTTP_X_FORWARDED_HOST" => "//randomhost.com",
+      "HOST" => "www.example.com",
+      "action_dispatch.show_detailed_exceptions" => true
+    }
+
+    assert_response :forbidden
+    assert_match "Blocked host: //randomhost.com", response.body
+  end
+
+  test "forwarded secondary hosts are allowed when permitted" do
+    @app = ActionDispatch::HostAuthorization.new(App, ".domain.com")
+
+    get "/", env: {
+      "HTTP_X_FORWARDED_HOST" => "example.com, my-sub.domain.com",
+      "HOST" => "domain.com",
+    }
+
+    assert_response :ok
+    assert_equal "Success", body
+  end
+
+  test "forwarded secondary hosts are blocked when mismatch" do
+    @app = ActionDispatch::HostAuthorization.new(App, "domain.com")
+
+    get "/", env: {
+      "HTTP_X_FORWARDED_HOST" => "domain.com, evil.com",
+      "HOST" => "domain.com",
+      "action_dispatch.show_detailed_exceptions" => true
+    }
+
+    assert_response :forbidden
+    assert_match "Blocked host: evil.com", response.body
+  end
+
   test "does not consider IP addresses in X-FORWARDED-HOST spoofed when disabled" do
     @app = ActionDispatch::HostAuthorization.new(App, nil)
 
@@ -205,11 +243,23 @@ class HostAuthorizationTest < ActionDispatch::IntegrationTest
     assert_match "Blocked host: sub.domain.com", response.body
   end
 
+  test "sub-sub domains should not be permitted" do
+    @app = ActionDispatch::HostAuthorization.new(App, ".domain.com")
+
+    get "/", env: {
+      "HOST" => "secondary.sub.domain.com",
+      "action_dispatch.show_detailed_exceptions" => true
+    }
+
+    assert_response :forbidden
+    assert_match "Blocked host: secondary.sub.domain.com", response.body
+  end
+
   test "forwarded hosts are allowed when permitted" do
     @app = ActionDispatch::HostAuthorization.new(App, ".domain.com")
 
     get "/", env: {
-      "HTTP_X_FORWARDED_HOST" => "sub.domain.com",
+      "HTTP_X_FORWARDED_HOST" => "my-sub.domain.com",
       "HOST" => "domain.com",
     }
 
@@ -217,6 +267,43 @@ class HostAuthorizationTest < ActionDispatch::IntegrationTest
     assert_equal "Success", body
   end
 
+  test "lots of NG hosts" do
+    ng_hosts = [
+      "hacker%E3%80%82com",
+      "hacker%00.com",
+      "www.theirsite.com@yoursite.com",
+      "hacker.com/test/",
+      "hacker%252ecom",
+      ".hacker.com",
+      "/\/\/hacker.com/",
+      "/hacker.com",
+      "../hacker.com",
+      ".hacker.com",
+      "@hacker.com",
+      "hacker.com",
+      "hacker.com%23@example.com",
+      "hacker.com/.jpg",
+      "hacker.com\texample.com/",
+      "hacker.com/example.com",
+      "hacker.com\@example.com",
+      "hacker.com/example.com",
+      "hacker.com/"
+    ]
+
+    @app = ActionDispatch::HostAuthorization.new(App, "example.com")
+
+    ng_hosts.each do |host|
+      get "/", env: {
+        "HTTP_X_FORWARDED_HOST" => host,
+        "HOST" => "example.com",
+        "action_dispatch.show_detailed_exceptions" => true
+      }
+
+      assert_response :forbidden
+      assert_match "Blocked host: #{host}", response.body
+    end
+  end
+
   test "exclude matches allow any host" do
     @app = ActionDispatch::HostAuthorization.new(App, "only.com", exclude: ->(req) { req.path \
== "/foo" })  
-- 
2.33.0



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic