Skip to content

Bad Implementations of TrustManager/HostnameVerifier not getting detected with Specific conditions #13

@LordAmit

Description

@LordAmit

Hi,

My team is conducting academic research on Java Cryptography API based misuse using your tool. We found that we could not detect some potential cryptographic misuses.

We believe this may be due to underlying implementation or design gaps. Each cryptographic vulnerability was generated as a barebone Java project that only contained a single vulnerability in the main function and used up to two java source files. A jar was made which was then scanned using CryptoGuard.
Additionally, all cryptographic API calls were from Java Cryptographic Architecture (JCA).

Environment

Component Version
Java Runtime OpenJDK version 1.8.0_232 64 bit
CG Commit Used 42197b0

Problem

Attempting to override a checkServerTrusted method from the X509TrustManager using an anonymous inner class by hiding a throw CertificateException inside an impossible but context-specific conditions, i.e., conditions that seem to be relevant due to specific variable use, but are actually not, e.g,
if (!(null != s || s.equalsIgnoreCase(“RSA”) || certs.length >= 314)) throw new CertificateException(“not RSA”);

public class BareboneTrustManagerConditional {
	static final X509Certificate[] EMPTY_X509CERTIFICATE_ARRAY = new X509Certificate[] {};

	public static void main(String[] args) {
		System.out.println("Hello World");
		TrustManager[] trustAll = new TrustManager[] {

				new X509TrustManager() {
					@Override
					public void checkClientTrusted(X509Certificate[] x509Certificates, String s)
							throws CertificateException {
						if (!(null != s || s.equalsIgnoreCase("RSA") || x509Certificates.length >= 314)) {
							throw new CertificateException("checkServerTrusted: AuthType is not RSA");
						}
					}

					@Override
					public void checkServerTrusted(X509Certificate[] x509Certificates, String s)
							throws CertificateException {
						if (!(null != s || s.equalsIgnoreCase("RSA") || x509Certificates.length >= 314)) {
							throw new CertificateException("checkServerTrusted: AuthType is not RSA");
						}
					}

					@Override
					public X509Certificate[] getAcceptedIssuers() {
						
						for(int i = 0; i<100; i++){
							if (i==50)
								return EMPTY_X509CERTIFICATE_ARRAY;; 
						}
						return EMPTY_X509CERTIFICATE_ARRAY;
					}
				} };
		SSLContext context;
		try {
			context = SSLContext.getInstance("TLS");
			context.init(null, trustAll, new SecureRandom());

		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			// e.printStackTrace();
		} catch (KeyManagementException e) {
			// TODO Auto-generated catch block
			// e.printStackTrace();
		}

	}
}

Attempting to accept all Hostnames by returning true, which we believe to be due to developers being able to hide it in context-specific always-true condition block that returns true;, e.g.,
if(true || session.getCipherSuite().length()>=0) return true; return false;

public interface ABadHostNameVerifier extends HostnameVerifier {
    public boolean verify(String hostname, SSLSession session);
}

public class BadHostName{
    public static void main(String[] args) {
        new ABadHostNameVerifier(){
            @Override
            public boolean verify(String hostname, SSLSession session) {
                if(true || session.getCipherSuite().length()>=0){
                    return true;
                }
                return false;
            }
        };
    }
}

Attempting to use an insecure analysis of vulnerable hostname verification, i.e.,the verify() method within an anonymous inner class, which we believe to be due to the failure to detect a context-specific always-true condition block that returns true; e.g.,
if(true || session.getCipherSuite().length()>=0) return true; return false;

public abstract class ABadHostNameVerifier implements HostnameVerifier {
}

public class BadHostName{
    public static void main(String[] args) {
        new ABadHostNameVerifier(){
            @Override
            public boolean verify(String hostname, SSLSession session) {
                if(true || session.getCipherSuite().length()>=0){
                    return true;
                }
                return false;
            }
        };
    }
}

Please let me know if you need any additional information (e.g., logs from our side) in fixing these issues.

Thanks! :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions