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

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


The following commit(s) were added to refs/heads/master by this push:
     new 06078adc60 [fix] stop silent SSL-to-plaintext downgrade in R2DBC MySQL 
route (#4260)
06078adc60 is described below

commit 06078adc605ec92f0c8b3fe7de92518768e829a0
Author: aias00 <[email protected]>
AuthorDate: Sun Aug 9 18:47:38 2026 +0800

    [fix] stop silent SSL-to-plaintext downgrade in R2DBC MySQL route (#4260)
    
    Co-authored-by: Claude <[email protected]>
    Co-authored-by: Duansg <[email protected]>
---
 .../mysql/r2dbc/MysqlR2dbcQueryExecutor.java       | 33 ++++++++--------------
 1 file changed, 12 insertions(+), 21 deletions(-)

diff --git 
a/hertzbeat-collector/hertzbeat-collector-mysql-r2dbc/src/main/java/org/apache/hertzbeat/collector/mysql/r2dbc/MysqlR2dbcQueryExecutor.java
 
b/hertzbeat-collector/hertzbeat-collector-mysql-r2dbc/src/main/java/org/apache/hertzbeat/collector/mysql/r2dbc/MysqlR2dbcQueryExecutor.java
index d8a5e9698e..41f5ed36a7 100644
--- 
a/hertzbeat-collector/hertzbeat-collector-mysql-r2dbc/src/main/java/org/apache/hertzbeat/collector/mysql/r2dbc/MysqlR2dbcQueryExecutor.java
+++ 
b/hertzbeat-collector/hertzbeat-collector-mysql-r2dbc/src/main/java/org/apache/hertzbeat/collector/mysql/r2dbc/MysqlR2dbcQueryExecutor.java
@@ -46,21 +46,23 @@ public class MysqlR2dbcQueryExecutor implements 
MysqlQueryExecutor {
     @Override
     public QueryResult execute(String sql, QueryOptions options) {
         String normalizedSql = sqlGuard.normalizeAndValidate(sql);
-        QueryResult firstAttempt = executeOnce(normalizedSql, options, 
SslMode.PREFERRED);
-        if (!firstAttempt.hasError() || 
!shouldRetryWithoutSsl(firstAttempt.getError())) {
-            return firstAttempt;
-        }
-        QueryResult fallbackAttempt = executeOnce(normalizedSql, options, 
SslMode.DISABLED);
-        if (!fallbackAttempt.hasError()) {
-            return fallbackAttempt;
+        // A single PREFERRED attempt negotiates TLS when the server supports 
it and
+        // falls back to plaintext only through the protocol-level handshake 
when the
+        // server advertises no SSL capability. It must NOT be followed by a 
second
+        // SslMode.DISABLED attempt on handshake *failures*: a handshake 
failure is
+        // ambiguous (a MitM can induce it to force a downgrade), and retrying 
with
+        // SSL disabled would then ship the monitoring credentials in the 
clear.
+        QueryResult result = executeOnce(normalizedSql, options, 
SslMode.PREFERRED);
+        if (!result.hasError()) {
+            return result;
         }
-        if (requiresSslCompatibleAuth(fallbackAttempt.getError())) {
+        if (requiresSslCompatibleAuth(result.getError())) {
             return QueryResult.builder()
-                    .error(fallbackAttempt.getError()
+                    .error(result.getError()
                             + ". This route currently needs a TLS-compatible 
runtime or a mysql_native_password monitoring user.")
                     .build();
         }
-        return fallbackAttempt;
+        return result;
     }
 
     private QueryResult executeOnce(String sql, QueryOptions options, SslMode 
sslMode) {
@@ -128,17 +130,6 @@ public class MysqlR2dbcQueryExecutor implements 
MysqlQueryExecutor {
         return false;
     }
 
-    private boolean shouldRetryWithoutSsl(String error) {
-        if (error == null) {
-            return false;
-        }
-        String normalized = error.toLowerCase(Locale.ROOT);
-        return normalized.contains("handshake_failure")
-                || normalized.contains("ssl/tls handshake")
-                || normalized.contains("closedchannelexception")
-                || normalized.contains("connection unexpectedly closed");
-    }
-
     private boolean requiresSslCompatibleAuth(String error) {
         if (error == null) {
             return false;


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to