v0.14 is out: a mobile auth pack for Swift/iOS and Android, catching insecure token storage, cleartext traffic, and OAuth in embedded WebViews. Read more →
HIGH AI PREVALENCE: HIGH auth.java.tls.trust-all-certs

TLS hostname verification is disabled.

Why AI tools produce this: AI coding tools generate this anti-pattern by default, it appears in a large share of AI-written auth code.

Why this matters

A permissive HostnameVerifier that returns true for every host (or Apache HttpClient's NoopHostnameVerifier) accepts any certificate regardless of the name it was issued for, so a man-in-the-middle can present a certificate for a different domain and the connection succeeds (CWE-295). This is a common AI-generated mistake: the verifier is stubbed out to "fix" a handshake or certificate error during development and shipped to production.

Never accept all hosts. Leave the default hostname verification in place (do not call setHostnameVerifier/setDefaultHostnameVerifier with a permissive verifier), or fix the trust chain by supplying a proper truststore so the certificate validates normally.

VULNERABLE
vulnerable.java
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import org.apache.http.conn.ssl.NoopHostnameVerifier;

class TrustAllCerts {

    void lambdaVerifier(HttpsURLConnection conn) {
        // ruleid: auth.java.tls.trust-all-certs
        conn.setHostnameVerifier((hostname, session) -> true);
    }

    void anonymousVerifier(HttpsURLConnection conn) {
        // ruleid: auth.java.tls.trust-all-certs
        conn.setHostnameVerifier(new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });
    }

    HostnameVerifier noopVerifier() {
        // ruleid: auth.java.tls.trust-all-certs
        return new NoopHostnameVerifier();
    }
}
SAFE
safe.java
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import java.net.URL;
import java.util.function.BiPredicate;

class SafeTls {

    // Negative control: a generic two-arg lambda returning `true` that is NOT a
    // HostnameVerifier. Without context-scoping this matched the verifier rule;
    // it must not fire now.
    BiPredicate<String, String> alwaysTrue() {
        // ok: auth.java.tls.trust-all-certs
        return (a, b) -> true;
    }

    // A verifier that actually checks the hostname against an allowlist.
    void realVerifier(HttpsURLConnection conn) {
        // ok: auth.java.tls.trust-all-certs
        conn.setHostnameVerifier(new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return "api.example.com".equals(hostname)
                        || hostname.endsWith(".trusted.example.com");
            }
        });
    }

    // Default verification: never touch setHostnameVerifier.
    String defaultVerification(URL url) throws Exception {
        // ok: auth.java.tls.trust-all-certs
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
        conn.connect();
        return conn.getCipherSuite();
    }
}

Suppressing this rule

If a finding is a genuine false positive, scope the suppression to the exact line and leave a reason, never disable the rule project-wide. Disable directives are line-scoped by design.

// oauthlint-disable-next-line auth.java.tls.trust-all-certs -- <reason>

References

https://cwe.mitre.org/data/definitions/295.html ↗https://docs.oracle.com/javase/8/docs/api/javax/net/ssl/HostnameVerifier.html ↗