Skip to content

Commit

Permalink
Validate that hostname is ascii in OkHostnameVerifier.java
Browse files Browse the repository at this point in the history
Sec vuln fix
  • Loading branch information
ZachChuba committed Dec 16, 2024
1 parent 486b8ba commit 210d8f3
Showing 1 changed file with 24 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;
import java.nio.charset.StandardCharsets;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
Expand Down Expand Up @@ -63,6 +64,9 @@ private OkHostnameVerifier() {

@Override
public boolean verify(String host, SSLSession session) {
if (!isAscii(host)) {
return false;
}
try {
Certificate[] certificates = session.getPeerCertificates();
return verify(host, (X509Certificate) certificates[0]);
Expand Down Expand Up @@ -98,7 +102,7 @@ private boolean verifyIpAddress(String ipAddress, X509Certificate certificate) {
* Returns true if {@code certificate} matches {@code hostName}.
*/
private boolean verifyHostName(String hostName, X509Certificate certificate) {
hostName = hostName.toLowerCase(Locale.US);
hostName = asciiToLowercase(hostName);
boolean hasDns = false;
List<String> altNames = getSubjectAltNames(certificate, ALT_DNS_NAME);
for (int i = 0, size = altNames.size(); i < size; i++) {
Expand Down Expand Up @@ -198,7 +202,7 @@ private boolean verifyHostName(String hostName, String pattern) {
}
// hostName and pattern are now absolute domain names.

pattern = pattern.toLowerCase(Locale.US);
pattern = asciiToLowercase(pattern);
// hostName and pattern are now in lower case -- domain names are case-insensitive.

if (!pattern.contains("*")) {
Expand Down Expand Up @@ -254,4 +258,22 @@ private boolean verifyHostName(String hostName, String pattern) {
// hostName matches pattern
return true;
}

/**
* Normalize the input to lowercase, if it is an ASCII string.
* Avoid unicode characters like \u1E0E from returning lowercased ascii
* that could match real hostnames.
*/
private static String asciiToLowercase(String input) {
if (isAscii(input)) {
return input.toLowerCase(Locale.US);
} else {
return input;
}
}

private static boolean isAscii(String input) {
// Only ASCII characters are 1 byte in UTF-8.
return input.getBytes(StandardCharsets.UTF_8).length == input.length();
}
}

0 comments on commit 210d8f3

Please sign in to comment.