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]