diff --git a/java/ql/src/Security/CWE/CWE-297/UnsafeHostnameVerification.ql b/java/ql/src/Security/CWE/CWE-297/UnsafeHostnameVerification.ql index 1828b924752c..6d68c6642d21 100644 --- a/java/ql/src/Security/CWE/CWE-297/UnsafeHostnameVerification.ql +++ b/java/ql/src/Security/CWE/CWE-297/UnsafeHostnameVerification.ql @@ -15,6 +15,7 @@ import semmle.code.java.controlflow.Guards import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.Encryption +import semmle.code.java.security.SecurityFlag import DataFlow::PathGraph private import semmle.code.java.dataflow.ExternalFlow @@ -86,71 +87,30 @@ private class HostnameVerifierSink extends DataFlow::Node { HostnameVerifierSink() { sinkNode(this, "set-hostname-verifier") } } -bindingset[result] -private string getAFlagName() { - result - .regexpMatch("(?i).*(secure|disable|selfCert|selfSign|validat|verif|trust|ignore|nocertificatecheck).*") -} - /** - * A flag has to either be of type `String`, `boolean` or `Boolean`. + * Flags suggesting a deliberately unsafe `HostnameVerifier` usage. */ -private class FlagType extends Type { - FlagType() { - this instanceof TypeString - or - this instanceof BooleanType +private class UnsafeHostnameVerificationFlag extends FlagKind { + UnsafeHostnameVerificationFlag() { this = "UnsafeHostnameVerificationFlag" } + + bindingset[result] + override string getAFlagName() { + result + .regexpMatch("(?i).*(secure|disable|selfCert|selfSign|validat|verif|trust|ignore|nocertificatecheck).*") and + result != "equalsIgnoreCase" } } -private predicate isEqualsIgnoreCaseMethodAccess(MethodAccess ma) { - ma.getMethod().hasName("equalsIgnoreCase") and - ma.getMethod().getDeclaringType() instanceof TypeString -} - -/** Holds if `source` should is considered a flag. */ -private predicate isFlag(DataFlow::Node source) { - exists(VarAccess v | v.getVariable().getName() = getAFlagName() | - source.asExpr() = v and v.getType() instanceof FlagType - ) - or - exists(StringLiteral s | s.getRepresentedString() = getAFlagName() | source.asExpr() = s) - or - exists(MethodAccess ma | ma.getMethod().getName() = getAFlagName() | - source.asExpr() = ma and - ma.getType() instanceof FlagType and - not isEqualsIgnoreCaseMethodAccess(ma) - ) -} - -/** Holds if there is flow from `node1` to `node2` either due to local flow or due to custom flow steps. */ -private predicate flagFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - DataFlow::localFlowStep(node1, node2) - or - exists(MethodAccess ma | ma.getMethod() = any(EnvReadMethod m) | - ma = node2.asExpr() and ma.getAnArgument() = node1.asExpr() - ) - or - exists(MethodAccess ma | - ma.getMethod().hasName("parseBoolean") and - ma.getMethod().getDeclaringType().hasQualifiedName("java.lang", "Boolean") - | - ma = node2.asExpr() and ma.getAnArgument() = node1.asExpr() - ) +/** Gets a guard that represents a (likely) flag controlling an unsafe `HostnameVerifier` use. */ +private Guard getAnUnsafeHostnameVerifierFlagGuard() { + result = any(UnsafeHostnameVerificationFlag flag).getAFlag().asExpr() } -/** Gets a guard that depends on a flag. */ -private Guard getAGuard() { - exists(DataFlow::Node source, DataFlow::Node sink | - isFlag(source) and - flagFlowStep*(source, sink) and - sink.asExpr() = result - ) -} - -/** Holds if `node` is guarded by a flag that suggests an intentionally insecure feature. */ +/** Holds if `node` is guarded by a flag that suggests an intentionally insecure use. */ private predicate isNodeGuardedByFlag(DataFlow::Node node) { - exists(Guard g | g.controls(node.asExpr().getBasicBlock(), _) | g = getAGuard()) + exists(Guard g | g.controls(node.asExpr().getBasicBlock(), _) | + g = getASecurityFeatureFlagGuard() or g = getAnUnsafeHostnameVerifierFlagGuard() + ) } from diff --git a/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.java b/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.java index b3536fa7d1de..e94491eb22f0 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.java +++ b/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.java @@ -1,45 +1,5 @@ public static void main(String[] args) { - { - X509TrustManager trustAllCertManager = new X509TrustManager() { - @Override - public void checkClientTrusted(final X509Certificate[] chain, final String authType) - throws CertificateException { - } - - @Override - public void checkServerTrusted(final X509Certificate[] chain, final String authType) - throws CertificateException { - // BAD: trust any server cert - } - - @Override - public X509Certificate[] getAcceptedIssuers() { - return null; //BAD: doesn't check cert issuer - } - }; - } - - { - X509TrustManager trustCertManager = new X509TrustManager() { - @Override - public void checkClientTrusted(final X509Certificate[] chain, final String authType) - throws CertificateException { - } - - @Override - public void checkServerTrusted(final X509Certificate[] chain, final String authType) - throws CertificateException { - pkixTrustManager.checkServerTrusted(chain, authType); //GOOD: validate the server cert - } - - @Override - public X509Certificate[] getAcceptedIssuers() { - return new X509Certificate[0]; //GOOD: Validate the cert issuer - } - }; - } - { SSLContext sslContext = SSLContext.getInstance("TLS"); SSLEngine sslEngine = sslContext.createSSLEngine(); diff --git a/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.qhelp b/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.qhelp index 9a6bdb82cbac..ae8d76b1bb1f 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.qhelp +++ b/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.qhelp @@ -4,10 +4,9 @@ -

Java offers two mechanisms for SSL authentication - trust manager and hostname verifier (checked by the java/insecure-hostname-verifier query). Trust manager validates the peer's certificate chain while hostname verification establishes that the hostname in the URL matches the hostname in the server's identification.

-

And when SSLSocket or SSLEngine is created without a valid parameter of setEndpointIdentificationAlgorithm, hostname verification is disabled by default.

+

When SSLSocket or SSLEngine is created without a valid parameter of setEndpointIdentificationAlgorithm, hostname verification is disabled by default.

Unsafe implementation of the interface X509TrustManager and SSLSocket/SSLEngine ignores all SSL certificate validation errors when establishing an HTTPS connection, thereby making the app vulnerable to man-in-the-middle attacks.

-

This query checks whether trust manager is set to trust all certificates or setEndpointIdentificationAlgorithm is missing. The query also covers a special implementation com.rabbitmq.client.ConnectionFactory.

+

This query checks whether setEndpointIdentificationAlgorithm is missing. The query also covers a special implementation com.rabbitmq.client.ConnectionFactory.

@@ -15,8 +14,8 @@ -

The following two examples show two ways of configuring X509 trust cert manager. In the 'BAD' case, -no validation is performed thus any certificate is trusted. In the 'GOOD' case, the proper validation is performed.

+

The following two examples show two ways of configuring SSLSocket/SSLEngine. In the 'BAD' case, +setEndpointIdentificationAlgorithm is not called, thus no hostname verification takes place. In the 'GOOD' case, setEndpointIdentificationAlgorithm is called.

@@ -25,9 +24,6 @@ no validation is performed thus any certificate is trusted. In the 'GOOD' case, CWE-273
  • -How to fix apps containing an unsafe implementation of TrustManager -
  • -
  • Testing Endpoint Identify Verification (MSTG-NETWORK-3)
  • diff --git a/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.ql b/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.ql index 9efdcbf4c6e0..a18b35ae38f4 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.ql @@ -1,7 +1,6 @@ /** * @name Unsafe certificate trust - * @description Unsafe implementation of the interface X509TrustManager and - * SSLSocket/SSLEngine ignores all SSL certificate validation + * @description SSLSocket/SSLEngine ignores all SSL certificate validation * errors when establishing an HTTPS connection, thereby making * the app vulnerable to man-in-the-middle attacks. * @kind problem @@ -15,49 +14,6 @@ import java import semmle.code.java.security.Encryption -/** - * X509TrustManager class that blindly trusts all certificates in server SSL authentication - */ -class X509TrustAllManager extends RefType { - X509TrustAllManager() { - this.getASupertype*() instanceof X509TrustManager and - exists(Method m1 | - m1.getDeclaringType() = this and - m1.hasName("checkServerTrusted") and - m1.getBody().getNumStmt() = 0 - ) and - exists(Method m2, ReturnStmt rt2 | - m2.getDeclaringType() = this and - m2.hasName("getAcceptedIssuers") and - rt2.getEnclosingCallable() = m2 and - rt2.getResult() instanceof NullLiteral - ) - } -} - -/** - * The init method of SSLContext with the trust all manager, which is sslContext.init(..., serverTMs, ...) - */ -class X509TrustAllManagerInit extends MethodAccess { - X509TrustAllManagerInit() { - this.getMethod().hasName("init") and - this.getMethod().getDeclaringType() instanceof SSLContext and //init method of SSLContext - ( - exists(ArrayInit ai | - this.getArgument(1).(ArrayCreationExpr).getInit() = ai and - ai.getInit(0).(VarAccess).getVariable().getInitializer().getType().(Class).getASupertype*() - instanceof X509TrustAllManager //Scenario of context.init(null, new TrustManager[] { TRUST_ALL_CERTIFICATES }, null); - ) - or - exists(Variable v, ArrayInit ai | - this.getArgument(1).(VarAccess).getVariable() = v and - ai.getParent() = v.getAnAssignedValue() and - ai.getInit(0).getType().(Class).getASupertype*() instanceof X509TrustAllManager //Scenario of context.init(null, serverTMs, null); - ) - ) - } -} - class SSLEngine extends RefType { SSLEngine() { this.hasQualifiedName("javax.net.ssl", "SSLEngine") } } @@ -208,7 +164,6 @@ class RabbitMQEnableHostnameVerificationNotSet extends MethodAccess { from MethodAccess aa where - aa instanceof X509TrustAllManagerInit or aa instanceof SSLEndpointIdentificationNotSet or aa instanceof RabbitMQEnableHostnameVerificationNotSet select aa, "Unsafe configuration of trusted certificates" diff --git a/java/ql/src/experimental/Security/CWE/CWE-295/InsecureTrustManager.java b/java/ql/src/experimental/Security/CWE/CWE-295/InsecureTrustManager.java new file mode 100644 index 000000000000..4e9c3ce6bbc9 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-295/InsecureTrustManager.java @@ -0,0 +1,52 @@ +public static void main(String[] args) throws Exception { + { + class InsecureTrustManager implements X509TrustManager { + @Override + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + // BAD: Does not verify the certificate chain, allowing any certificate. + } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + + } + } + SSLContext context = SSLContext.getInstance("TLS"); + TrustManager[] trustManager = new TrustManager[] { new InsecureTrustManager() }; + context.init(null, trustManager, null); + } + { + SSLContext context = SSLContext.getInstance("TLS"); + File certificateFile = new File("path/to/self-signed-certificate"); + // Create a `KeyStore` with default type + KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); + // `keyStore` is initially empty + keyStore.load(null, null); + X509Certificate generatedCertificate; + try (InputStream cert = new FileInputStream(certificateFile)) { + generatedCertificate = (X509Certificate) CertificateFactory.getInstance("X509") + .generateCertificate(cert); + } + // Add the self-signed certificate to the key store + keyStore.setCertificateEntry(certificateFile.getName(), generatedCertificate); + // Get default `TrustManagerFactory` + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + // Use it with our key store that trusts our self-signed certificate + tmf.init(keyStore); + TrustManager[] trustManagers = tmf.getTrustManagers(); + context.init(null, trustManagers, null); + // GOOD, we are not using a custom `TrustManager` but instead have + // added the self-signed certificate we want to trust to the key + // store. Note, the `trustManagers` will **only** trust this one + // certificate. + + URL url = new URL("https://self-signed.badssl.com/"); + HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); + conn.setSSLSocketFactory(context.getSocketFactory()); + } +} diff --git a/java/ql/src/experimental/Security/CWE/CWE-295/InsecureTrustManager.qhelp b/java/ql/src/experimental/Security/CWE/CWE-295/InsecureTrustManager.qhelp new file mode 100644 index 000000000000..99746477a343 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-295/InsecureTrustManager.qhelp @@ -0,0 +1,47 @@ + + + +

    +If the checkServerTrusted method of a TrustManager never throws a CertificateException it trusts every certificate. +This allows an attacker to perform a machine-in-the-middle attack against the application therefore breaking any security Transport Layer Security (TLS) gives. +

    + +

    +An attack might look like this: +

    + +
      +
    1. The vulnerable program connects to https://example.com.
    2. +
    3. The attacker intercepts this connection and presents a valid, self-signed certificate for https://example.com.
    4. +
    5. The vulnerable program calls the checkServerTrusted method to check whether it should trust the certificate.
    6. +
    7. The checkServerTrusted method of your TrustManager does not throw a CertificateException.
    8. +
    9. The vulnerable program accepts the certificate and proceeds with the connection since your TrustManager implicitly trusted it by not throwing an exception.
    10. +
    11. The attacker can now read the data your program sends to https://example.com and/or alter its replies while the program thinks the connection is secure.
    12. +
    +
    + + +

    +Do not use a custom TrustManager that trusts any certificate. +If you have to use a self-signed certificate, don't trust every certificate, but instead only trust this specific certificate. +See below for an example of how to do this. +

    + +
    + + +

    +In the first (bad) example, the TrustManager never throws a CertificateException and therefore implicitly trusts any certificate. +This allows an attacker to perform a machine-in-the-middle attack. +In the second (good) example, the self-signed certificate that should be trusted +is loaded into a KeyStore. This explicitly defines the certificate as trusted and there is no need to create a custom TrustManager. +

    + +
    + + +
  • Android Develoers:Security with HTTPS and SSL.
  • + +
    diff --git a/java/ql/src/experimental/Security/CWE/CWE-295/InsecureTrustManager.ql b/java/ql/src/experimental/Security/CWE/CWE-295/InsecureTrustManager.ql new file mode 100644 index 000000000000..598113ed5cda --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-295/InsecureTrustManager.ql @@ -0,0 +1,117 @@ +/** + * @name `TrustManager` that accepts all certificates + * @description Trusting all certificates allows an attacker to perform a machine-in-the-middle attack. + * @kind path-problem + * @problem.severity error + * @precision high + * @id java/insecure-trustmanager + * @tags security + * external/cwe/cwe-295 + */ + +import java +import semmle.code.java.controlflow.Guards +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.dataflow.FlowSources +import semmle.code.java.security.Encryption +import semmle.code.java.security.SecurityFlag +import DataFlow::PathGraph + +/** + * An insecure `X509TrustManager`. + * An `X509TrustManager` is considered insecure if it never throws a `CertificateException` + * and therefore implicitly trusts any certificate as valid. + */ +class InsecureX509TrustManager extends RefType { + InsecureX509TrustManager() { + this.getASupertype*() instanceof X509TrustManager and + exists(Method m | + m.getDeclaringType() = this and + m.hasName("checkServerTrusted") and + not mayThrowCertificateException(m) + ) + } +} + +/** The `java.security.cert.CertificateException` class. */ +private class CertificateException extends RefType { + CertificateException() { this.hasQualifiedName("java.security.cert", "CertificateException") } +} + +/** + * Holds if: + * - `m` may `throw` a `CertificateException`, or + * - `m` calls another method that may throw, or + * - `m` calls a method declared to throw a `CertificateException`, but for which no source is available + */ +private predicate mayThrowCertificateException(Method m) { + exists(ThrowStmt throwStmt | + throwStmt.getThrownExceptionType().getASupertype*() instanceof CertificateException + | + throwStmt.getEnclosingCallable() = m + ) + or + exists(Method otherMethod | m.polyCalls(otherMethod) | + mayThrowCertificateException(otherMethod) + or + not otherMethod.fromSource() and + otherMethod.getAnException().getType().getASupertype*() instanceof CertificateException + ) +} + +/** + * A configuration to model the flow of an `InsecureX509TrustManager` to an `SSLContext.init` call. + */ +class InsecureTrustManagerConfiguration extends TaintTracking::Configuration { + InsecureTrustManagerConfiguration() { this = "InsecureTrustManagerConfiguration" } + + override predicate isSource(DataFlow::Node source) { + source.asExpr().(ClassInstanceExpr).getConstructedType() instanceof InsecureX509TrustManager + } + + override predicate isSink(DataFlow::Node sink) { + exists(MethodAccess ma, Method m | + m.hasName("init") and + m.getDeclaringType() instanceof SSLContext and + ma.getMethod() = m + | + ma.getArgument(1) = sink.asExpr() + ) + } +} + +/** + * Flags suggesting a deliberately insecure `TrustManager` usage. + */ +private class InsecureTrustManagerFlag extends FlagKind { + InsecureTrustManagerFlag() { this = "InsecureTrustManagerFlag" } + + bindingset[result] + override string getAFlagName() { + result + .regexpMatch("(?i).*(secure|disable|selfCert|selfSign|validat|verif|trust|ignore|nocertificatecheck).*") and + result != "equalsIgnoreCase" + } +} + +/** Gets a guard that represents a (likely) flag controlling an insecure `TrustManager` use. */ +private Guard getAnInsecureTrustManagerFlagGuard() { + result = any(InsecureTrustManagerFlag flag).getAFlag().asExpr() +} + +/** Holds if `node` is guarded by a flag that suggests an intentionally insecure use. */ +private predicate isNodeGuardedByFlag(DataFlow::Node node) { + exists(Guard g | g.controls(node.asExpr().getBasicBlock(), _) | + g = getASecurityFeatureFlagGuard() or g = getAnInsecureTrustManagerFlagGuard() + ) +} + +from + DataFlow::PathNode source, DataFlow::PathNode sink, InsecureTrustManagerConfiguration cfg, + RefType trustManager +where + cfg.hasFlowPath(source, sink) and + not isNodeGuardedByFlag(sink.getNode()) and + trustManager = source.getNode().asExpr().(ClassInstanceExpr).getConstructedType() +select sink, source, sink, "$@ that is defined $@ and trusts any certificate, is used here.", + source, "This trustmanager", trustManager, "here" diff --git a/java/ql/src/semmle/code/java/security/SecurityFlag.qll b/java/ql/src/semmle/code/java/security/SecurityFlag.qll new file mode 100644 index 000000000000..e4f47d95ec45 --- /dev/null +++ b/java/ql/src/semmle/code/java/security/SecurityFlag.qll @@ -0,0 +1,86 @@ +/** + * Provides utility predicates to spot variable names, parameter names, and string literals that suggest deliberately insecure settings. + */ + +import java +import semmle.code.java.controlflow.Guards +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.dataflow.FlowSources + +/** + * A kind of flag that may indicate security expectations regarding the code it guards. + */ +abstract class FlagKind extends string { + bindingset[this] + FlagKind() { any() } + + /** + * Gets a flag name of this type. + */ + bindingset[result] + abstract string getAFlagName(); + + /** Gets a node representing a (likely) security flag. */ + DataFlow::Node getAFlag() { + exists(DataFlow::Node flag | + exists(VarAccess v | v.getVariable().getName() = getAFlagName() | + flag.asExpr() = v and v.getType() instanceof FlagType + ) + or + exists(StringLiteral s | s.getRepresentedString() = getAFlagName() | flag.asExpr() = s) + or + exists(MethodAccess ma | ma.getMethod().getName() = getAFlagName() | + flag.asExpr() = ma and + ma.getType() instanceof FlagType + ) + | + flagFlowStep*(flag, result) + ) + } +} + +/** + * Flags suggesting an optional feature, perhaps deliberately insecure. + */ +private class SecurityFeatureFlag extends FlagKind { + SecurityFeatureFlag() { this = "SecurityFeatureFlag" } + + bindingset[result] + override string getAFlagName() { result.regexpMatch("(?i).*(secure|(en|dis)able).*") } +} + +/** + * A flag has to either be of type `String`, `boolean` or `Boolean`. + */ +private class FlagType extends Type { + FlagType() { + this instanceof TypeString + or + this instanceof BooleanType + } +} + +/** + * Holds if there is local flow from `node1` to `node2` either due to standard data-flow steps or the + * following custom flow steps: + * 1. `Boolean.parseBoolean(taintedValue)` taints the return value of `parseBoolean`. + * 2. A call to an `EnvReadMethod` such as `System.getProperty` where a tainted value is used as an argument. + * The return value of such a method is then tainted. + */ +private predicate flagFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + DataFlow::localFlowStep(node1, node2) + or + exists(MethodAccess ma | ma.getMethod() = any(EnvReadMethod m) | + ma = node2.asExpr() and ma.getAnArgument() = node1.asExpr() + ) + or + exists(MethodAccess ma | + ma.getMethod().hasName("parseBoolean") and + ma.getMethod().getDeclaringType().hasQualifiedName("java.lang", "Boolean") + | + ma = node2.asExpr() and ma.getAnArgument() = node1.asExpr() + ) +} + +/** Gets a guard that represents a (likely) security feature-flag check. */ +Guard getASecurityFeatureFlagGuard() { result = any(SecurityFeatureFlag flag).getAFlag().asExpr() } diff --git a/java/ql/test/experimental/query-tests/security/CWE-273/UnsafeCertTrust.expected b/java/ql/test/experimental/query-tests/security/CWE-273/UnsafeCertTrust.expected index 5d2da21289e5..f26706a56d2c 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-273/UnsafeCertTrust.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-273/UnsafeCertTrust.expected @@ -1,5 +1,3 @@ -| UnsafeCertTrustTest.java:27:4:27:74 | init(...) | Unsafe configuration of trusted certificates | -| UnsafeCertTrustTest.java:42:4:42:38 | init(...) | Unsafe configuration of trusted certificates | -| UnsafeCertTrustTest.java:92:25:92:52 | createSSLEngine(...) | Unsafe configuration of trusted certificates | -| UnsafeCertTrustTest.java:103:25:103:52 | createSSLEngine(...) | Unsafe configuration of trusted certificates | -| UnsafeCertTrustTest.java:112:34:112:83 | createSocket(...) | Unsafe configuration of trusted certificates | +| UnsafeCertTrustTest.java:26:25:26:52 | createSSLEngine(...) | Unsafe configuration of trusted certificates | +| UnsafeCertTrustTest.java:37:25:37:52 | createSSLEngine(...) | Unsafe configuration of trusted certificates | +| UnsafeCertTrustTest.java:46:34:46:83 | createSocket(...) | Unsafe configuration of trusted certificates | diff --git a/java/ql/test/experimental/query-tests/security/CWE-273/UnsafeCertTrustTest.java b/java/ql/test/experimental/query-tests/security/CWE-273/UnsafeCertTrustTest.java index 1e8ecbbc20d1..cb8b472eb8fd 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-273/UnsafeCertTrustTest.java +++ b/java/ql/test/experimental/query-tests/security/CWE-273/UnsafeCertTrustTest.java @@ -18,72 +18,6 @@ public class UnsafeCertTrustTest { - /** - * Test the implementation of trusting all server certs as a variable - */ - public SSLSocketFactory testTrustAllCertManager() { - try { - final SSLContext context = SSLContext.getInstance("TLS"); - context.init(null, new TrustManager[] { TRUST_ALL_CERTIFICATES }, null); - final SSLSocketFactory socketFactory = context.getSocketFactory(); - return socketFactory; - } catch (final Exception x) { - throw new RuntimeException(x); - } - } - - /** - * Test the implementation of trusting all server certs as an anonymous class - */ - public SSLSocketFactory testTrustAllCertManagerOfVariable() { - try { - SSLContext context = SSLContext.getInstance("TLS"); - TrustManager[] serverTMs = new TrustManager[] { new X509TrustAllManager() }; - context.init(null, serverTMs, null); - - final SSLSocketFactory socketFactory = context.getSocketFactory(); - return socketFactory; - } catch (final Exception x) { - throw new RuntimeException(x); - } - } - - private static final X509TrustManager TRUST_ALL_CERTIFICATES = new X509TrustManager() { - @Override - public void checkClientTrusted(final X509Certificate[] chain, final String authType) - throws CertificateException { - } - - @Override - public void checkServerTrusted(final X509Certificate[] chain, final String authType) - throws CertificateException { - // Noncompliant - } - - @Override - public X509Certificate[] getAcceptedIssuers() { - return null; // Noncompliant - } - }; - - private class X509TrustAllManager implements X509TrustManager { - @Override - public void checkClientTrusted(final X509Certificate[] chain, final String authType) - throws CertificateException { - } - - @Override - public void checkServerTrusted(final X509Certificate[] chain, final String authType) - throws CertificateException { - // Noncompliant - } - - @Override - public X509Certificate[] getAcceptedIssuers() { - return null; // Noncompliant - } - }; - /** * Test the endpoint identification of SSL engine is set to null */ diff --git a/java/ql/test/experimental/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManager.expected b/java/ql/test/experimental/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManager.expected new file mode 100644 index 000000000000..08c8962cd983 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManager.expected @@ -0,0 +1,108 @@ +edges +| InsecureTrustManagerTest.java:121:33:121:81 | {...} [[]] : InsecureTrustManager | InsecureTrustManagerTest.java:122:22:122:33 | trustManager | +| InsecureTrustManagerTest.java:121:54:121:79 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:121:33:121:81 | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:130:34:130:82 | {...} [[]] : InsecureTrustManager | InsecureTrustManagerTest.java:131:23:131:34 | trustManager | +| InsecureTrustManagerTest.java:130:55:130:80 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:130:34:130:82 | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:151:34:151:82 | {...} [[]] : InsecureTrustManager | InsecureTrustManagerTest.java:152:23:152:34 | trustManager | +| InsecureTrustManagerTest.java:151:55:151:80 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:151:34:151:82 | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:172:34:172:82 | {...} [[]] : InsecureTrustManager | InsecureTrustManagerTest.java:173:23:173:34 | trustManager | +| InsecureTrustManagerTest.java:172:55:172:80 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:172:34:172:82 | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:193:34:193:82 | {...} [[]] : InsecureTrustManager | InsecureTrustManagerTest.java:194:23:194:34 | trustManager | +| InsecureTrustManagerTest.java:193:55:193:80 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:193:34:193:82 | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:214:34:214:82 | {...} [[]] : InsecureTrustManager | InsecureTrustManagerTest.java:215:23:215:34 | trustManager | +| InsecureTrustManagerTest.java:214:55:214:80 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:214:34:214:82 | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:235:34:235:82 | {...} [[]] : InsecureTrustManager | InsecureTrustManagerTest.java:236:23:236:34 | trustManager | +| InsecureTrustManagerTest.java:235:55:235:80 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:235:34:235:82 | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:257:34:257:82 | {...} [[]] : InsecureTrustManager | InsecureTrustManagerTest.java:258:23:258:34 | trustManager | +| InsecureTrustManagerTest.java:257:55:257:80 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:257:34:257:82 | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:280:34:280:82 | {...} [[]] : InsecureTrustManager | InsecureTrustManagerTest.java:281:23:281:34 | trustManager | +| InsecureTrustManagerTest.java:280:55:280:80 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:280:34:280:82 | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:305:33:305:81 | {...} [[]] : InsecureTrustManager | InsecureTrustManagerTest.java:306:22:306:33 | trustManager | +| InsecureTrustManagerTest.java:305:54:305:79 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:305:33:305:81 | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:319:33:319:81 | {...} [[]] : InsecureTrustManager | InsecureTrustManagerTest.java:320:22:320:33 | trustManager | +| InsecureTrustManagerTest.java:319:54:319:79 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:319:33:319:81 | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:333:33:333:81 | {...} [[]] : InsecureTrustManager | InsecureTrustManagerTest.java:334:22:334:33 | trustManager | +| InsecureTrustManagerTest.java:333:54:333:79 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:333:33:333:81 | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:347:33:347:81 | {...} [[]] : InsecureTrustManager | InsecureTrustManagerTest.java:348:22:348:33 | trustManager | +| InsecureTrustManagerTest.java:347:54:347:79 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:347:33:347:81 | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:361:33:361:81 | {...} [[]] : InsecureTrustManager | InsecureTrustManagerTest.java:362:22:362:33 | trustManager | +| InsecureTrustManagerTest.java:361:54:361:79 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:361:33:361:81 | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:375:33:375:81 | {...} [[]] : InsecureTrustManager | InsecureTrustManagerTest.java:376:22:376:33 | trustManager | +| InsecureTrustManagerTest.java:375:54:375:79 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:375:33:375:81 | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:390:33:390:81 | {...} [[]] : InsecureTrustManager | InsecureTrustManagerTest.java:391:22:391:33 | trustManager | +| InsecureTrustManagerTest.java:390:54:390:79 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:390:33:390:81 | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:405:33:405:81 | {...} [[]] : InsecureTrustManager | InsecureTrustManagerTest.java:406:22:406:33 | trustManager | +| InsecureTrustManagerTest.java:405:54:405:79 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:405:33:405:81 | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:414:33:414:81 | {...} [[]] : InsecureTrustManager | InsecureTrustManagerTest.java:415:22:415:33 | trustManager | +| InsecureTrustManagerTest.java:414:54:414:79 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:414:33:414:81 | {...} [[]] : InsecureTrustManager | +nodes +| InsecureTrustManagerTest.java:121:33:121:81 | {...} [[]] : InsecureTrustManager | semmle.label | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:121:54:121:79 | new InsecureTrustManager(...) : InsecureTrustManager | semmle.label | new InsecureTrustManager(...) : InsecureTrustManager | +| InsecureTrustManagerTest.java:122:22:122:33 | trustManager | semmle.label | trustManager | +| InsecureTrustManagerTest.java:130:34:130:82 | {...} [[]] : InsecureTrustManager | semmle.label | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:130:55:130:80 | new InsecureTrustManager(...) : InsecureTrustManager | semmle.label | new InsecureTrustManager(...) : InsecureTrustManager | +| InsecureTrustManagerTest.java:131:23:131:34 | trustManager | semmle.label | trustManager | +| InsecureTrustManagerTest.java:151:34:151:82 | {...} [[]] : InsecureTrustManager | semmle.label | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:151:55:151:80 | new InsecureTrustManager(...) : InsecureTrustManager | semmle.label | new InsecureTrustManager(...) : InsecureTrustManager | +| InsecureTrustManagerTest.java:152:23:152:34 | trustManager | semmle.label | trustManager | +| InsecureTrustManagerTest.java:172:34:172:82 | {...} [[]] : InsecureTrustManager | semmle.label | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:172:55:172:80 | new InsecureTrustManager(...) : InsecureTrustManager | semmle.label | new InsecureTrustManager(...) : InsecureTrustManager | +| InsecureTrustManagerTest.java:173:23:173:34 | trustManager | semmle.label | trustManager | +| InsecureTrustManagerTest.java:193:34:193:82 | {...} [[]] : InsecureTrustManager | semmle.label | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:193:55:193:80 | new InsecureTrustManager(...) : InsecureTrustManager | semmle.label | new InsecureTrustManager(...) : InsecureTrustManager | +| InsecureTrustManagerTest.java:194:23:194:34 | trustManager | semmle.label | trustManager | +| InsecureTrustManagerTest.java:214:34:214:82 | {...} [[]] : InsecureTrustManager | semmle.label | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:214:55:214:80 | new InsecureTrustManager(...) : InsecureTrustManager | semmle.label | new InsecureTrustManager(...) : InsecureTrustManager | +| InsecureTrustManagerTest.java:215:23:215:34 | trustManager | semmle.label | trustManager | +| InsecureTrustManagerTest.java:235:34:235:82 | {...} [[]] : InsecureTrustManager | semmle.label | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:235:55:235:80 | new InsecureTrustManager(...) : InsecureTrustManager | semmle.label | new InsecureTrustManager(...) : InsecureTrustManager | +| InsecureTrustManagerTest.java:236:23:236:34 | trustManager | semmle.label | trustManager | +| InsecureTrustManagerTest.java:257:34:257:82 | {...} [[]] : InsecureTrustManager | semmle.label | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:257:55:257:80 | new InsecureTrustManager(...) : InsecureTrustManager | semmle.label | new InsecureTrustManager(...) : InsecureTrustManager | +| InsecureTrustManagerTest.java:258:23:258:34 | trustManager | semmle.label | trustManager | +| InsecureTrustManagerTest.java:280:34:280:82 | {...} [[]] : InsecureTrustManager | semmle.label | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:280:55:280:80 | new InsecureTrustManager(...) : InsecureTrustManager | semmle.label | new InsecureTrustManager(...) : InsecureTrustManager | +| InsecureTrustManagerTest.java:281:23:281:34 | trustManager | semmle.label | trustManager | +| InsecureTrustManagerTest.java:305:33:305:81 | {...} [[]] : InsecureTrustManager | semmle.label | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:305:54:305:79 | new InsecureTrustManager(...) : InsecureTrustManager | semmle.label | new InsecureTrustManager(...) : InsecureTrustManager | +| InsecureTrustManagerTest.java:306:22:306:33 | trustManager | semmle.label | trustManager | +| InsecureTrustManagerTest.java:319:33:319:81 | {...} [[]] : InsecureTrustManager | semmle.label | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:319:54:319:79 | new InsecureTrustManager(...) : InsecureTrustManager | semmle.label | new InsecureTrustManager(...) : InsecureTrustManager | +| InsecureTrustManagerTest.java:320:22:320:33 | trustManager | semmle.label | trustManager | +| InsecureTrustManagerTest.java:333:33:333:81 | {...} [[]] : InsecureTrustManager | semmle.label | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:333:54:333:79 | new InsecureTrustManager(...) : InsecureTrustManager | semmle.label | new InsecureTrustManager(...) : InsecureTrustManager | +| InsecureTrustManagerTest.java:334:22:334:33 | trustManager | semmle.label | trustManager | +| InsecureTrustManagerTest.java:347:33:347:81 | {...} [[]] : InsecureTrustManager | semmle.label | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:347:54:347:79 | new InsecureTrustManager(...) : InsecureTrustManager | semmle.label | new InsecureTrustManager(...) : InsecureTrustManager | +| InsecureTrustManagerTest.java:348:22:348:33 | trustManager | semmle.label | trustManager | +| InsecureTrustManagerTest.java:361:33:361:81 | {...} [[]] : InsecureTrustManager | semmle.label | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:361:54:361:79 | new InsecureTrustManager(...) : InsecureTrustManager | semmle.label | new InsecureTrustManager(...) : InsecureTrustManager | +| InsecureTrustManagerTest.java:362:22:362:33 | trustManager | semmle.label | trustManager | +| InsecureTrustManagerTest.java:375:33:375:81 | {...} [[]] : InsecureTrustManager | semmle.label | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:375:54:375:79 | new InsecureTrustManager(...) : InsecureTrustManager | semmle.label | new InsecureTrustManager(...) : InsecureTrustManager | +| InsecureTrustManagerTest.java:376:22:376:33 | trustManager | semmle.label | trustManager | +| InsecureTrustManagerTest.java:390:33:390:81 | {...} [[]] : InsecureTrustManager | semmle.label | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:390:54:390:79 | new InsecureTrustManager(...) : InsecureTrustManager | semmle.label | new InsecureTrustManager(...) : InsecureTrustManager | +| InsecureTrustManagerTest.java:391:22:391:33 | trustManager | semmle.label | trustManager | +| InsecureTrustManagerTest.java:405:33:405:81 | {...} [[]] : InsecureTrustManager | semmle.label | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:405:54:405:79 | new InsecureTrustManager(...) : InsecureTrustManager | semmle.label | new InsecureTrustManager(...) : InsecureTrustManager | +| InsecureTrustManagerTest.java:406:22:406:33 | trustManager | semmle.label | trustManager | +| InsecureTrustManagerTest.java:414:33:414:81 | {...} [[]] : InsecureTrustManager | semmle.label | {...} [[]] : InsecureTrustManager | +| InsecureTrustManagerTest.java:414:54:414:79 | new InsecureTrustManager(...) : InsecureTrustManager | semmle.label | new InsecureTrustManager(...) : InsecureTrustManager | +| InsecureTrustManagerTest.java:415:22:415:33 | trustManager | semmle.label | trustManager | +#select +| InsecureTrustManagerTest.java:122:22:122:33 | trustManager | InsecureTrustManagerTest.java:121:54:121:79 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:122:22:122:33 | trustManager | $@ that is defined $@ and trusts any certificate, is used here. | InsecureTrustManagerTest.java:121:54:121:79 | new InsecureTrustManager(...) : InsecureTrustManager | This trustmanager | InsecureTrustManagerTest.java:35:23:35:42 | InsecureTrustManager | here | +| InsecureTrustManagerTest.java:152:23:152:34 | trustManager | InsecureTrustManagerTest.java:151:55:151:80 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:152:23:152:34 | trustManager | $@ that is defined $@ and trusts any certificate, is used here. | InsecureTrustManagerTest.java:151:55:151:80 | new InsecureTrustManager(...) : InsecureTrustManager | This trustmanager | InsecureTrustManagerTest.java:35:23:35:42 | InsecureTrustManager | here | +| InsecureTrustManagerTest.java:194:23:194:34 | trustManager | InsecureTrustManagerTest.java:193:55:193:80 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:194:23:194:34 | trustManager | $@ that is defined $@ and trusts any certificate, is used here. | InsecureTrustManagerTest.java:193:55:193:80 | new InsecureTrustManager(...) : InsecureTrustManager | This trustmanager | InsecureTrustManagerTest.java:35:23:35:42 | InsecureTrustManager | here | +| InsecureTrustManagerTest.java:236:23:236:34 | trustManager | InsecureTrustManagerTest.java:235:55:235:80 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:236:23:236:34 | trustManager | $@ that is defined $@ and trusts any certificate, is used here. | InsecureTrustManagerTest.java:235:55:235:80 | new InsecureTrustManager(...) : InsecureTrustManager | This trustmanager | InsecureTrustManagerTest.java:35:23:35:42 | InsecureTrustManager | here | +| InsecureTrustManagerTest.java:258:23:258:34 | trustManager | InsecureTrustManagerTest.java:257:55:257:80 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:258:23:258:34 | trustManager | $@ that is defined $@ and trusts any certificate, is used here. | InsecureTrustManagerTest.java:257:55:257:80 | new InsecureTrustManager(...) : InsecureTrustManager | This trustmanager | InsecureTrustManagerTest.java:35:23:35:42 | InsecureTrustManager | here | +| InsecureTrustManagerTest.java:281:23:281:34 | trustManager | InsecureTrustManagerTest.java:280:55:280:80 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:281:23:281:34 | trustManager | $@ that is defined $@ and trusts any certificate, is used here. | InsecureTrustManagerTest.java:280:55:280:80 | new InsecureTrustManager(...) : InsecureTrustManager | This trustmanager | InsecureTrustManagerTest.java:35:23:35:42 | InsecureTrustManager | here | +| InsecureTrustManagerTest.java:306:22:306:33 | trustManager | InsecureTrustManagerTest.java:305:54:305:79 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:306:22:306:33 | trustManager | $@ that is defined $@ and trusts any certificate, is used here. | InsecureTrustManagerTest.java:305:54:305:79 | new InsecureTrustManager(...) : InsecureTrustManager | This trustmanager | InsecureTrustManagerTest.java:35:23:35:42 | InsecureTrustManager | here | +| InsecureTrustManagerTest.java:320:22:320:33 | trustManager | InsecureTrustManagerTest.java:319:54:319:79 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:320:22:320:33 | trustManager | $@ that is defined $@ and trusts any certificate, is used here. | InsecureTrustManagerTest.java:319:54:319:79 | new InsecureTrustManager(...) : InsecureTrustManager | This trustmanager | InsecureTrustManagerTest.java:35:23:35:42 | InsecureTrustManager | here | +| InsecureTrustManagerTest.java:334:22:334:33 | trustManager | InsecureTrustManagerTest.java:333:54:333:79 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:334:22:334:33 | trustManager | $@ that is defined $@ and trusts any certificate, is used here. | InsecureTrustManagerTest.java:333:54:333:79 | new InsecureTrustManager(...) : InsecureTrustManager | This trustmanager | InsecureTrustManagerTest.java:35:23:35:42 | InsecureTrustManager | here | +| InsecureTrustManagerTest.java:348:22:348:33 | trustManager | InsecureTrustManagerTest.java:347:54:347:79 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:348:22:348:33 | trustManager | $@ that is defined $@ and trusts any certificate, is used here. | InsecureTrustManagerTest.java:347:54:347:79 | new InsecureTrustManager(...) : InsecureTrustManager | This trustmanager | InsecureTrustManagerTest.java:35:23:35:42 | InsecureTrustManager | here | +| InsecureTrustManagerTest.java:362:22:362:33 | trustManager | InsecureTrustManagerTest.java:361:54:361:79 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:362:22:362:33 | trustManager | $@ that is defined $@ and trusts any certificate, is used here. | InsecureTrustManagerTest.java:361:54:361:79 | new InsecureTrustManager(...) : InsecureTrustManager | This trustmanager | InsecureTrustManagerTest.java:35:23:35:42 | InsecureTrustManager | here | +| InsecureTrustManagerTest.java:376:22:376:33 | trustManager | InsecureTrustManagerTest.java:375:54:375:79 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:376:22:376:33 | trustManager | $@ that is defined $@ and trusts any certificate, is used here. | InsecureTrustManagerTest.java:375:54:375:79 | new InsecureTrustManager(...) : InsecureTrustManager | This trustmanager | InsecureTrustManagerTest.java:35:23:35:42 | InsecureTrustManager | here | +| InsecureTrustManagerTest.java:391:22:391:33 | trustManager | InsecureTrustManagerTest.java:390:54:390:79 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:391:22:391:33 | trustManager | $@ that is defined $@ and trusts any certificate, is used here. | InsecureTrustManagerTest.java:390:54:390:79 | new InsecureTrustManager(...) : InsecureTrustManager | This trustmanager | InsecureTrustManagerTest.java:35:23:35:42 | InsecureTrustManager | here | +| InsecureTrustManagerTest.java:406:22:406:33 | trustManager | InsecureTrustManagerTest.java:405:54:405:79 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:406:22:406:33 | trustManager | $@ that is defined $@ and trusts any certificate, is used here. | InsecureTrustManagerTest.java:405:54:405:79 | new InsecureTrustManager(...) : InsecureTrustManager | This trustmanager | InsecureTrustManagerTest.java:35:23:35:42 | InsecureTrustManager | here | +| InsecureTrustManagerTest.java:415:22:415:33 | trustManager | InsecureTrustManagerTest.java:414:54:414:79 | new InsecureTrustManager(...) : InsecureTrustManager | InsecureTrustManagerTest.java:415:22:415:33 | trustManager | $@ that is defined $@ and trusts any certificate, is used here. | InsecureTrustManagerTest.java:414:54:414:79 | new InsecureTrustManager(...) : InsecureTrustManager | This trustmanager | InsecureTrustManagerTest.java:35:23:35:42 | InsecureTrustManager | here | diff --git a/java/ql/test/experimental/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManager.qlref b/java/ql/test/experimental/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManager.qlref new file mode 100644 index 000000000000..9950f6276595 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManager.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-295/InsecureTrustManager.ql diff --git a/java/ql/test/experimental/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManagerTest.java b/java/ql/test/experimental/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManagerTest.java new file mode 100644 index 000000000000..5b314d464d48 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManagerTest.java @@ -0,0 +1,420 @@ +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; + +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +public class InsecureTrustManagerTest { + + private static final boolean TRUST_ALL = true; + private static final boolean SOME_NAME_THAT_IS_NOT_A_FLAG_NAME = true; + + private static boolean isDisableTrust() { + return true; + } + + private static boolean is42TheAnswerForEverything() { + return true; + } + + private static class InsecureTrustManager implements X509TrustManager { + @Override + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + // BAD: Does not verify the certificate chain, allowing any certificate. + } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + + } + } + + public static void main(String[] args) throws Exception { + directInsecureTrustManagerCall(); + + namedVariableFlagDirectInsecureTrustManagerCall(); + noNamedVariableFlagDirectInsecureTrustManagerCall(); + namedVariableFlagIndirectInsecureTrustManagerCall(); + noNamedVariableFlagIndirectInsecureTrustManagerCall(); + + stringLiteralFlagDirectInsecureTrustManagerCall(); + noStringLiteralFlagDirectInsecureTrustManagerCall(); + stringLiteralFlagIndirectInsecureTrustManagerCall(); + noStringLiteralFlagIndirectInsecureTrustManagerCall(); + + methodAccessFlagDirectInsecureTrustManagerCall(); + noMethodAccessFlagDirectInsecureTrustManagerCall(); + methodAccessFlagIndirectInsecureTrustManagerCall(); + noMethodAccessFlagIndirectInsecureTrustManagerCall(); + + isEqualsIgnoreCaseDirectInsecureTrustManagerCall(); + noIsEqualsIgnoreCaseDirectInsecureTrustManagerCall(); + isEqualsIgnoreCaseIndirectInsecureTrustManagerCall(); + noIsEqualsIgnoreCaseIndirectInsecureTrustManagerCall(); + + namedVariableFlagNOTGuardingDirectInsecureTrustManagerCall(); + noNamedVariableFlagNOTGuardingDirectInsecureTrustManagerCall(); + + stringLiteralFlagNOTGuardingDirectInsecureTrustManagerCall(); + noStringLiteralFlagNOTGuardingDirectInsecureTrustManagerCall(); + + methodAccessFlagNOTGuardingDirectInsecureTrustManagerCall(); + noMethodAccessFlagNOTGuardingDirectInsecureTrustManagerCall(); + + isEqualsIgnoreCaseNOTGuardingDirectInsecureTrustManagerCall(); + noIsEqualsIgnoreCaseNOTGuardingDirectInsecureTrustManagerCall(); + + directSecureTrustManagerCall(); + + } + + private static void directSecureTrustManagerCall() throws NoSuchAlgorithmException, KeyStoreException, IOException, + CertificateException, FileNotFoundException, KeyManagementException, MalformedURLException { + SSLContext context = SSLContext.getInstance("TLS"); + File certificateFile = new File("path/to/self-signed-certificate"); + // Create a `KeyStore` with default type + KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); + // This causes `keyStore` to be empty + keyStore.load(null, null); + X509Certificate generatedCertificate; + try (InputStream cert = new FileInputStream(certificateFile)) { + generatedCertificate = (X509Certificate) CertificateFactory.getInstance("X509").generateCertificate(cert); + } + // Add the self-signed certificate to the key store + keyStore.setCertificateEntry(certificateFile.getName(), generatedCertificate); + // Get default `TrustManagerFactory` + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + // Use it with our modified key store that trusts our self-signed certificate + tmf.init(keyStore); + TrustManager[] trustManagers = tmf.getTrustManagers(); + context.init(null, trustManagers, null); // GOOD, we are not using a custom `TrustManager` but instead have + // added the self-signed certificate we want to trust to the key + // store. Note, the `trustManagers` will **only** trust this one + // certificate. + URL url = new URL("https://self-signed.badssl.com/"); + HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); + conn.setSSLSocketFactory(context.getSocketFactory()); + } + + private static void directInsecureTrustManagerCall() throws NoSuchAlgorithmException, KeyManagementException { + SSLContext context = SSLContext.getInstance("TLS"); + TrustManager[] trustManager = new TrustManager[] { new InsecureTrustManager() }; + context.init(null, trustManager, null); // BAD: Uses a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. + } + + private static void namedVariableFlagDirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + if (TRUST_ALL) { + SSLContext context = SSLContext.getInstance("TLS"); + TrustManager[] trustManager = new TrustManager[] { new InsecureTrustManager() }; + context.init(null, trustManager, null); // GOOD: Uses a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. BUT it is guarded + // by a feature flag. + } + } + + private static void namedVariableFlagIndirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + if (TRUST_ALL) { + disableTrustManager(); // GOOD [But the disableTrustManager method itself is still detected]: Calls a + // method that install a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. BUT it is guarded + // by a feature flag. + } + } + + private static void noNamedVariableFlagDirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + if (SOME_NAME_THAT_IS_NOT_A_FLAG_NAME) { + SSLContext context = SSLContext.getInstance("TLS"); + TrustManager[] trustManager = new TrustManager[] { new InsecureTrustManager() }; + context.init(null, trustManager, null); // BAD: Uses a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. It is NOT guarded + // by a feature flag. + } + } + + private static void noNamedVariableFlagIndirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + if (SOME_NAME_THAT_IS_NOT_A_FLAG_NAME) { + disableTrustManager(); // BAD [This is detected in the disableTrustManager method]: Calls a method that + // install a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. It is NOT guarded + // by a feature flag. + } + } + + private static void stringLiteralFlagDirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + if (Boolean.parseBoolean(System.getProperty("TRUST_ALL"))) { + SSLContext context = SSLContext.getInstance("TLS"); + TrustManager[] trustManager = new TrustManager[] { new InsecureTrustManager() }; + context.init(null, trustManager, null); // GOOD: Uses a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. BUT it is guarded + // by a feature flag. + } + } + + private static void stringLiteralFlagIndirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + if (Boolean.parseBoolean(System.getProperty("TRUST_ALL"))) { + disableTrustManager(); // GOOD [But the disableTrustManager method itself is still detected]: Calls a + // method that install a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. BUT it is guarded + // by a feature flag. + } + } + + private static void noStringLiteralFlagDirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + if (Boolean.parseBoolean(System.getProperty("SOME_NAME_THAT_IS_NOT_A_FLAG_NAME"))) { + SSLContext context = SSLContext.getInstance("TLS"); + TrustManager[] trustManager = new TrustManager[] { new InsecureTrustManager() }; + context.init(null, trustManager, null); // BAD: Uses a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. It is NOT guarded + // by a feature flag. + } + } + + private static void noStringLiteralFlagIndirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + if (Boolean.parseBoolean(System.getProperty("SOME_NAME_THAT_IS_NOT_A_FLAG_NAME"))) { + disableTrustManager(); // BAD [This is detected in the disableTrustManager method]: Calls a method that + // install a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. It is NOT guarded + // by a feature flag. + } + } + + private static void methodAccessFlagDirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + if (isDisableTrust()) { + SSLContext context = SSLContext.getInstance("TLS"); + TrustManager[] trustManager = new TrustManager[] { new InsecureTrustManager() }; + context.init(null, trustManager, null); // GOOD: Uses a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. BUT it is guarded + // by a feature flag. + } + } + + private static void methodAccessFlagIndirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + if (isDisableTrust()) { + disableTrustManager(); // GOOD [But the disableTrustManager method itself is still detected]: Calls a + // method that install a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. BUT it is guarded + // by a feature flag. + } + } + + private static void noMethodAccessFlagDirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + if (is42TheAnswerForEverything()) { + SSLContext context = SSLContext.getInstance("TLS"); + TrustManager[] trustManager = new TrustManager[] { new InsecureTrustManager() }; + context.init(null, trustManager, null); // BAD: Uses a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. It is NOT guarded + // by a feature flag. + } + } + + private static void noMethodAccessFlagIndirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + if (is42TheAnswerForEverything()) { + disableTrustManager(); // BAD [This is detected in the disableTrustManager method]: Calls a method that + // install a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. It is NOT guarded + // by a feature flag. + } + } + + private static void isEqualsIgnoreCaseDirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + String schemaFromHttpRequest = "HTTPS"; + if (schemaFromHttpRequest.equalsIgnoreCase("https")) { + SSLContext context = SSLContext.getInstance("TLS"); + TrustManager[] trustManager = new TrustManager[] { new InsecureTrustManager() }; + context.init(null, trustManager, null); // BAD: Uses a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. It is NOT guarded + // by a feature flag. + } + } + + private static void isEqualsIgnoreCaseIndirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + String schemaFromHttpRequest = "HTTPS"; + if (schemaFromHttpRequest.equalsIgnoreCase("https")) { + disableTrustManager(); // BAD [This is detected in the disableTrustManager method]: Calls a method that + // install a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. It is NOT guarded + // by a feature flag. + } + } + + private static void noIsEqualsIgnoreCaseDirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + String schemaFromHttpRequest = "HTTPS"; + if (!schemaFromHttpRequest.equalsIgnoreCase("https")) { + SSLContext context = SSLContext.getInstance("TLS"); + TrustManager[] trustManager = new TrustManager[] { new InsecureTrustManager() }; + context.init(null, trustManager, null); // BAD: Uses a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. It is NOT guarded + // by a feature flag. + } + } + + private static void noIsEqualsIgnoreCaseIndirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + String schemaFromHttpRequest = "HTTPS"; + if (!schemaFromHttpRequest.equalsIgnoreCase("https")) { + disableTrustManager(); // BAD [This is detected in the disableTrustManager method]: Calls a method that + // install a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. It is NOT guarded + // by a feature flag. + } + } + + private static void namedVariableFlagNOTGuardingDirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + if (TRUST_ALL) { + System.out.println("Disabling trust!"); + } + + SSLContext context = SSLContext.getInstance("TLS"); + TrustManager[] trustManager = new TrustManager[] { new InsecureTrustManager() }; + context.init(null, trustManager, null); // BAD: Uses a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. It is NOT guarded + // by a feature flag, because it is outside the if. + + } + + private static void noNamedVariableFlagNOTGuardingDirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + if (SOME_NAME_THAT_IS_NOT_A_FLAG_NAME) { + System.out.println("Disabling trust!"); + } + + SSLContext context = SSLContext.getInstance("TLS"); + TrustManager[] trustManager = new TrustManager[] { new InsecureTrustManager() }; + context.init(null, trustManager, null); // BAD: Uses a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. It is NOT guarded + // by a feature flag, because it is outside the if and it is NOT a valid flag. + + } + + private static void stringLiteralFlagNOTGuardingDirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + if (Boolean.parseBoolean(System.getProperty("TRUST_ALL"))) { + System.out.println("Disabling trust!"); + } + + SSLContext context = SSLContext.getInstance("TLS"); + TrustManager[] trustManager = new TrustManager[] { new InsecureTrustManager() }; + context.init(null, trustManager, null); // BAD: Uses a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. It is NOT guarded + // by a feature flag, because it is outside the if. + + } + + private static void noStringLiteralFlagNOTGuardingDirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + if (Boolean.parseBoolean(System.getProperty("SOME_NAME_THAT_IS_NOT_A_FLAG_NAME"))) { + System.out.println("Disabling trust!"); + } + + SSLContext context = SSLContext.getInstance("TLS"); + TrustManager[] trustManager = new TrustManager[] { new InsecureTrustManager() }; + context.init(null, trustManager, null); // BAD: Uses a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. It is NOT guarded + // by a feature flag, because it is outside the if and it is NOT a valid flag. + + } + + private static void methodAccessFlagNOTGuardingDirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + if (isDisableTrust()) { + System.out.println("Disabling trust!"); + } + + SSLContext context = SSLContext.getInstance("TLS"); + TrustManager[] trustManager = new TrustManager[] { new InsecureTrustManager() }; + context.init(null, trustManager, null); // BAD: Uses a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. It is NOT guarded + // by a feature flag, because it is outside the if. + + } + + private static void noMethodAccessFlagNOTGuardingDirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + if (is42TheAnswerForEverything()) { + System.out.println("Disabling trust!"); + } + + SSLContext context = SSLContext.getInstance("TLS"); + TrustManager[] trustManager = new TrustManager[] { new InsecureTrustManager() }; + context.init(null, trustManager, null); // BAD: Uses a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. It is NOT guarded + // by a feature flag, because it is outside the if and it is NOT a valid flag. + + } + + private static void isEqualsIgnoreCaseNOTGuardingDirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + String schemaFromHttpRequest = "HTTPS"; + if (schemaFromHttpRequest.equalsIgnoreCase("https")) { + System.out.println("Disabling trust!"); + } + + SSLContext context = SSLContext.getInstance("TLS"); + TrustManager[] trustManager = new TrustManager[] { new InsecureTrustManager() }; + context.init(null, trustManager, null); // BAD: Uses a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. It is NOT guarded + // by a feature flag, because it is outside the if and it is NOT a valid flag. + + } + + private static void noIsEqualsIgnoreCaseNOTGuardingDirectInsecureTrustManagerCall() + throws NoSuchAlgorithmException, KeyManagementException { + String schemaFromHttpRequest = "HTTPS"; + if (!schemaFromHttpRequest.equalsIgnoreCase("https")) { + System.out.println("Disabling trust!"); + } + + SSLContext context = SSLContext.getInstance("TLS"); + TrustManager[] trustManager = new TrustManager[] { new InsecureTrustManager() }; + context.init(null, trustManager, null); // BAD: Uses a `TrustManager` that does not verify the certificate + // chain, allowing any certificate. It is NOT guarded + // by a feature flag, because it is outside the if and it is NOT a valid flag. + + } + + private static void disableTrustManager() throws NoSuchAlgorithmException, KeyManagementException { + SSLContext context = SSLContext.getInstance("TLS"); + TrustManager[] trustManager = new TrustManager[] { new InsecureTrustManager() }; + context.init(null, trustManager, null); // BAD: Uses a `TrustManager` that does not verify the + // certificate + // chain, allowing any certificate. The method name suggests that this may be + // intentional, but we flag it anyway. + } +} \ No newline at end of file