This is an automated email from the ASF dual-hosted git repository.

guoqqqi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git


The following commit(s) were added to refs/heads/master by this push:
     new de0782a91a fix: return 421 for SNI and Host mismatches on mTLS 
requests (#14013)
de0782a91a is described below

commit de0782a91a98febd3733d0f3c547166a7b7464f5
Author: ruanweihong-aaa <[email protected]>
AuthorDate: Tue Oct 20 08:49:56 2026 +0800

    fix: return 421 for SNI and Host mismatches on mTLS requests (#14013)
---
 apisix/init.lua                | 25 ++++++++++++-------------
 t/node/client-mtls-openresty.t |  8 ++++----
 t/node/client-mtls.t           |  8 ++++----
 3 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/apisix/init.lua b/apisix/init.lua
index b25069c744..45120aac03 100644
--- a/apisix/init.lua
+++ b/apisix/init.lua
@@ -482,6 +482,15 @@ local function verify_https_client(ctx)
 
     local matched_ssl = ctx.matched_ssl
     if matched_ssl.value.client and apisix_ssl.support_client_verification() 
then
+        local sni = apisix_ssl.server_name()
+        if sni ~= host then
+            -- A reused connection cannot negotiate the target host's client 
certificate.
+            -- Reject it before checking the certificate so clients can retry 
with its SNI.
+            core.log.error("request SNI ", sni, " does not match host ", host,
+                           " for an mTLS-enabled SSL configuration")
+            return false, 421
+        end
+
         local verified = apisix_base_flags.client_cert_verified_in_handshake
         if not verified then
             -- vanilla OpenResty requires to check the verification result
@@ -497,17 +506,6 @@ local function verify_https_client(ctx)
             end
         end
 
-        local sni = apisix_ssl.server_name()
-        if sni ~= host then
-            -- There is a case that the user configures a SSL object with 
`*.domain`,
-            -- and the client accesses with SNI `a.domain` but uses Host 
`b.domain`.
-            -- This case is complex and we choose to restrict the access until 
there
-            -- is a stronge demand in real world.
-            core.log.error("client certificate verified with SNI ", sni,
-                           ", but the host is ", host)
-            return false
-        end
-
         if not verify_tls_session_resumption() then
             return false
         end
@@ -858,8 +856,9 @@ function _M.http_access_phase()
 
     local span = tracer.start(ngx_ctx, "apisix.phase.access", 
tracer.kind.server)
 
-    if not verify_https_client(api_ctx) then
-        return core.response.exit(400)
+    local verified, status = verify_https_client(api_ctx)
+    if not verified then
+        return core.response.exit(status or 400)
     end
 
     debug.dynamic_debug(api_ctx)
diff --git a/t/node/client-mtls-openresty.t b/t/node/client-mtls-openresty.t
index 050394d1ba..9c69336855 100644
--- a/t/node/client-mtls-openresty.t
+++ b/t/node/client-mtls-openresty.t
@@ -189,9 +189,9 @@ GET /t
 --- exec
 curl -k https://localhost:1994/hello -H "Host: test.com"
 --- response_body eval
-qr/400 Bad Request/
+qr/421 Misdirected Request/
 --- error_log
-client certificate was not present
+request SNI localhost does not match host test.com for an mTLS-enabled SSL 
configuration
 
 
 
@@ -267,6 +267,6 @@ GET /t
 --- exec
 curl --cert t/certs/mtls_client.crt --key t/certs/mtls_client.key -k 
https://localhost:1994/hello -H "Host: test.com"
 --- response_body eval
-qr/400 Bad Request/
+qr/421 Misdirected Request/
 --- error_log
-client certificate verified with SNI localhost, but the host is test.com
+request SNI localhost does not match host test.com for an mTLS-enabled SSL 
configuration
diff --git a/t/node/client-mtls.t b/t/node/client-mtls.t
index e594169605..b71cccb426 100644
--- a/t/node/client-mtls.t
+++ b/t/node/client-mtls.t
@@ -490,9 +490,9 @@ GET /t
 --- exec
 curl -k https://localhost:1994/hello -H "Host: test.com"
 --- response_body eval
-qr/400 Bad Request/
+qr/421 Misdirected Request/
 --- error_log
-client certificate verified with SNI localhost, but the host is test.com
+request SNI localhost does not match host test.com for an mTLS-enabled SSL 
configuration
 
 
 
@@ -568,9 +568,9 @@ GET /t
 --- exec
 curl --cert t/certs/mtls_client.crt --key t/certs/mtls_client.key -k 
https://localhost:1994/hello -H "Host: test.com"
 --- response_body eval
-qr/400 Bad Request/
+qr/421 Misdirected Request/
 --- error_log
-client certificate verified with SNI localhost, but the host is test.com
+request SNI localhost does not match host test.com for an mTLS-enabled SSL 
configuration
 
 
 

Reply via email to