Details
-
Bug
-
Status: Closed (View Workflow)
-
Critical
-
Resolution: Fixed
-
3.5.10
-
None
-
MariaDB Connector/J: 3.5.10
Last known working version: 3.5.9
Spring Boot: 4.1.0
Hibernate Core: 7.4.1-Final
Database: MariaDB
Connection pool: HikariCP
Description
Since MariaDB Connector/J 3.5.10, DatabaseMetaData#getURL() returns the database password in plain text when the username and password are provided separately from the JDBC URL.
The datasource is configured as follows:
spring.datasource.url=jdbc:mariadb://localhost:3307/myDatabase |
spring.datasource.username=myUser
|
spring.datasource.password=myPassword
|
Starting with Connector/J 3.5.10,{{ DatabaseMetaData#getURL()}} returns:
jdbc:mariadb://localhost:3307/myDatabase?user=myUser&password=myPassword
With Connector/J 3.5.9, the same call returned:
jdbc:mariadb://localhost:3307/myDatabase?user=myUser&password=***
Steps to reproduce
The issue can be reproduced directly using the JDBC API without Spring Boot or Hibernate.
Maven dependency
Use the following dependency and change the version between 3.5.9 and 3.5.10:
<dependency>
|
<groupId>org.mariadb.jdbc</groupId>
|
<artifactId>mariadb-java-client</artifactId>
|
<!--<version>3.5.9</version>--> |
<version>3.5.10</version> |
</dependency>
|
Java code
import java.sql.Connection; |
import java.sql.DriverManager; |
|
|
public class Main { |
|
|
public static void main(String[] args) throws Exception { |
String url = "jdbc:mariadb://localhost:3307/myDatabase"; |
|
|
try (Connection connection = |
DriverManager.getConnection(url, "myUser", "myPassword")) { |
|
|
System.out.println(connection.getMetaData().getURL());
|
}
|
}
|
}
|
Result with Connector/J 3.5.9
jdbc:mariadb://localhost:3307/myDatabase?user=myUser&password=***
Result with Connector/J 3.5.10
jdbc:mariadb://localhost:3307/myDatabase?user=myUser&password=myPassword
Expected behavior
DatabaseMetaData#getURL() should not expose the database password in plain text.
Actual behavior
With Connector/J 3.5.10, DatabaseMetaData#getURL() returns a JDBC URL containing the database password in plain text.
This can cause database credentials to be written to application logs by frameworks that use the standard JDBC metadata API.
For example, Hibernate Core 7.4.1-Final uses DatabaseMetaData#getURL() when building its DatabaseConnectionInfo. During application startup, Hibernate logs this information at INFO level:
Database info:
|
Database JDBC URL [jdbc:mariadb://localhost:3307/myDatabase?user=myUser&password=myPassword] |
As a result, the database password is exposed in the application log even though the password was never part of the configured JDBC URL.
The behavior appears to be related to the following commit:
cb176a0e2cc4681cedb56cbab5b6dabfc5900bcd
The commit is titled:
redact credentials at rendering time, not in the configuration url
In Configuration.Builder.build(), the construction of initialUrl was changed from:
conf.initialUrl = buildUrl(conf);
|
to:
conf.initialUrl = buildUrl(conf, false); |
As a result, initialUrl is now built without hiding sensitive values.
However, DatabaseMetaData#getURL() exposes this unredacted URL, which means that the internal representation can reach external consumers through the standard JDBC API.