Skip to content

Commit 25ad7cb

Browse files
authored
Addressed CVE-2025-59250 and version updates for 10.2.4 (#2802)
1 parent 4e7a872 commit 25ad7cb

File tree

17 files changed

+137
-51
lines changed

17 files changed

+137
-51
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file.
33

44
The format is based on [Keep a Changelog](http://keepachangelog.com/)
55

6+
## [10.2.4] Hotfix & Stable Release
7+
### Fixed issues
8+
- **Address a hostname validation vulnerability by securely parsing certificate common names.**
9+
**What was fixed**: Secure hostname validation is enforced by replacing the vulnerable CN parsing logic in SQLServerCertificateUtils.java, preventing spoofing attacks.
10+
**Who benefits**: All users of the SQL Server JDBC driver, especially those relying on TLS for secure connections, benefit from improved certificate validation.
11+
612
## [10.2.3] HotFix & Stable Release
713
### Fixed issues
814
- Fixed incorrect update counts when timeout occurs in batch queries [2024](https://github.com/microsoft/mssql-jdbc/pull/2024)

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ We're now on the Maven Central Repository. Add the following to your POM file to
8080
<dependency>
8181
<groupId>com.microsoft.sqlserver</groupId>
8282
<artifactId>mssql-jdbc</artifactId>
83-
<version>10.2.2.jre17</version>
83+
<version>10.2.4.jre17</version>
8484
</dependency>
8585
```
8686
The driver can be downloaded from the [Microsoft Download Center](https://go.microsoft.com/fwlink/?linkid=2168495).
@@ -91,7 +91,7 @@ To get the latest preview version of the driver, add the following to your POM f
9191
<dependency>
9292
<groupId>com.microsoft.sqlserver</groupId>
9393
<artifactId>mssql-jdbc</artifactId>
94-
<version>10.2.2.jre17</version>
94+
<version>10.2.4.jre17</version>
9595
</dependency>
9696
```
9797

@@ -126,7 +126,7 @@ Projects that require either of the two features need to explicitly declare the
126126
<dependency>
127127
<groupId>com.microsoft.sqlserver</groupId>
128128
<artifactId>mssql-jdbc</artifactId>
129-
<version>10.2.2.jre17</version>
129+
<version>10.2.4.jre17</version>
130130
<scope>compile</scope>
131131
</dependency>
132132

@@ -144,7 +144,7 @@ Projects that require either of the two features need to explicitly declare the
144144
<dependency>
145145
<groupId>com.microsoft.sqlserver</groupId>
146146
<artifactId>mssql-jdbc</artifactId>
147-
<version>10.2.2.jre17</version>
147+
<version>10.2.4.jre17</version>
148148
<scope>compile</scope>
149149
</dependency>
150150

@@ -171,7 +171,7 @@ When setting 'useFmtOnly' property to 'true' for establishing a connection or cr
171171
<dependency>
172172
<groupId>com.microsoft.sqlserver</groupId>
173173
<artifactId>mssql-jdbc</artifactId>
174-
<version>10.2.2.jre17</version>
174+
<version>10.2.4.jre17</version>
175175
</dependency>
176176

177177
<dependency>

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
apply plugin: 'java'
1313

14-
version = '10.2.3'
14+
version = '10.2.4'
1515
def jreVersion = ""
1616
def testOutputDir = file("build/classes/java/test")
1717
def archivesBaseName = 'mssql-jdbc'

mssql-jdbc_auth_LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
MICROSOFT SOFTWARE LICENSE TERMS
2-
MICROSOFT JDBC DRIVER 10.2.3 FOR SQL SERVER
2+
MICROSOFT JDBC DRIVER 10.2.4 FOR SQL SERVER
33

44
These license terms are an agreement between you and Microsoft Corporation (or one of its affiliates). They apply to the software named above and any Microsoft services or software updates (except to the extent such services or updates are accompanied by new or additional terms, in which case those different terms apply prospectively and do not alter your or Microsoft’s rights relating to pre-updated software or services). IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW. BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS.
55

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.microsoft.sqlserver</groupId>
88
<artifactId>mssql-jdbc</artifactId>
9-
<version>10.2.3</version>
9+
<version>10.2.4</version>
1010
<packaging>jar</packaging>
1111

1212
<name>Microsoft JDBC Driver for SQL Server</name>

src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@
6464
import java.util.logging.Level;
6565
import java.util.logging.Logger;
6666

67+
import javax.naming.InvalidNameException;
68+
import javax.naming.ldap.LdapName;
69+
import javax.naming.ldap.Rdn;
6770
import javax.net.SocketFactory;
6871
import javax.net.ssl.KeyManager;
6972
import javax.net.ssl.SSLContext;
@@ -1524,38 +1527,34 @@ private final class HostNameOverrideX509TrustManager implements X509TrustManager
15241527
this.hostName = hostName.toLowerCase(Locale.ENGLISH);
15251528
}
15261529

1527-
// Parse name in RFC 2253 format
1528-
// Returns the common name if successful, null if failed to find the common name.
1529-
// The parser tuned to be safe than sorry so if it sees something it cant parse correctly it returns null
1530-
private String parseCommonName(String distinguishedName) {
1531-
int index;
1532-
// canonical name converts entire name to lowercase
1533-
index = distinguishedName.indexOf("cn=");
1534-
if (index == -1) {
1535-
return null;
1536-
}
1537-
distinguishedName = distinguishedName.substring(index + 3);
1538-
// Parse until a comma or end is reached
1539-
// Note the parser will handle gracefully (essentially will return empty string) , inside the quotes (e.g
1540-
// cn="Foo, bar") however
1541-
// RFC 952 says that the hostName cant have commas however the parser should not (and will not) crash if it
1542-
// sees a , within quotes.
1543-
for (index = 0; index < distinguishedName.length(); index++) {
1544-
if (distinguishedName.charAt(index) == ',') {
1545-
break;
1530+
/**
1531+
* Securely parse the Common Name from an X.509 certificate using RFC2253 format.
1532+
* This method prevents DN injection attacks by using LdapName/Rdn parsing.
1533+
*
1534+
* @param cert X.509 certificate
1535+
* @return Common Name from the certificate subject, or null if not found
1536+
*/
1537+
private String parseCommonNameSecure(X509Certificate cert) {
1538+
try {
1539+
String subjectDN = cert.getSubjectX500Principal().getName(); // RFC2253 format
1540+
LdapName ldapName = new LdapName(subjectDN);
1541+
1542+
// Iterate through RDNs to find CN
1543+
for (Rdn rdn : ldapName.getRdns()) {
1544+
if ("CN".equalsIgnoreCase(rdn.getType())) {
1545+
return rdn.getValue().toString();
1546+
}
15461547
}
1547-
}
1548-
String commonName = distinguishedName.substring(0, index);
1549-
// strip any quotes
1550-
if (commonName.length() > 1 && ('\"' == commonName.charAt(0))) {
1551-
if ('\"' == commonName.charAt(commonName.length() - 1))
1552-
commonName = commonName.substring(1, commonName.length() - 1);
1553-
else {
1554-
// Be safe the name is not ended in " return null so the common Name wont match
1555-
commonName = null;
1548+
if (logger.isLoggable(Level.FINER)) {
1549+
logger.finer(logContext + " No CN found in certificate subject");
15561550
}
1551+
return null;
1552+
} catch (Exception e) {
1553+
if (logger.isLoggable(Level.WARNING)) {
1554+
logger.warning(logContext + " Error parsing certificate: " + e.getMessage());
1555+
}
1556+
return null;
15571557
}
1558-
return commonName;
15591558
}
15601559

15611560
private boolean validateServerName(String nameInCert) {
@@ -1645,17 +1644,21 @@ public void checkServerTrusted(X509Certificate[] chain, String authType) throws
16451644
}
16461645

16471646
private void validateServerNameInCertificate(X509Certificate cert) throws CertificateException {
1648-
String nameInCertDN = cert.getSubjectX500Principal().getName("canonical");
16491647
if (logger.isLoggable(Level.FINER)) {
16501648
logger.finer(logContext + " Validating the server name:" + hostName);
1651-
logger.finer(logContext + " The DN name in certificate:" + nameInCertDN);
16521649
}
16531650

16541651
boolean isServerNameValidated;
16551652
String dnsNameInSANCert = "";
16561653

1657-
// the name in cert is in RFC2253 format parse it to get the actual subject name
1658-
String subjectCN = parseCommonName(nameInCertDN);
1654+
// Use secure RFC2253 parsing to prevent DN injection attacks
1655+
String subjectCN = parseCommonNameSecure(cert);
1656+
// X.509 certificate standard requires domain names to be in ASCII.
1657+
// Even IDN (Unicode) names will be represented here in Punycode (ASCII).
1658+
// Normalize case for comparison using English to avoid case issues like Turkish i.
1659+
if (subjectCN != null) {
1660+
subjectCN = subjectCN.toLowerCase(Locale.ENGLISH);
1661+
}
16591662

16601663
isServerNameValidated = validateServerName(subjectCN);
16611664

src/main/java/com/microsoft/sqlserver/jdbc/SQLJdbcVersion.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
final class SQLJdbcVersion {
99
static final int major = 10;
1010
static final int minor = 2;
11-
static final int patch = 3;
11+
static final int patch = 4;
1212
static final int build = 0;
1313
/*
1414
* Used to load mssql-jdbc_auth DLL.

src/samples/adaptive/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<dependency>
1616
<groupId>com.microsoft.sqlserver</groupId>
1717
<artifactId>mssql-jdbc</artifactId>
18-
<version>10.2.0.jre17</version>
18+
<version>10.2.4.jre17</version>
1919
</dependency>
2020
</dependencies>
2121
<profiles>

src/samples/alwaysencrypted/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<dependency>
1616
<groupId>com.microsoft.sqlserver</groupId>
1717
<artifactId>mssql-jdbc</artifactId>
18-
<version>10.2.0.jre17</version>
18+
<version>10.2.4.jre17</version>
1919
</dependency>
2020
</dependencies>
2121
<profiles>

src/samples/azureactivedirectoryauthentication/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<dependency>
1515
<groupId>com.microsoft.sqlserver</groupId>
1616
<artifactId>mssql-jdbc</artifactId>
17-
<version>10.2.0.jre17</version>
17+
<version>10.2.4.jre17</version>
1818
</dependency>
1919
</dependencies>
2020
<profiles>

0 commit comments

Comments
 (0)