Refactor Security.CWE.CWE-297.UnsafeHostnameVerification

This commit is contained in:
Ed Minnix
2023-03-15 14:24:19 -04:00
parent 7bd7ecd9e6
commit 481d1f9b15

View File

@@ -16,7 +16,6 @@ import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.FlowSources import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.Encryption import semmle.code.java.security.Encryption
import semmle.code.java.security.SecurityFlag import semmle.code.java.security.SecurityFlag
import DataFlow::PathGraph
private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.ExternalFlow
/** /**
@@ -29,7 +28,7 @@ private predicate alwaysReturnsTrue(HostnameVerifierVerify m) {
} }
/** /**
* A class that overrides the `javax.net.ssl.HostnameVerifier.verify` method and **always** returns `true` (though it could also exit due to an uncaught exception), thus * A class that s the `javax.net.ssl.HostnameVerifier.verify` method and **always** returns `true` (though it could also exit due to an uncaught exception), thus
* accepting any certificate despite a hostname mismatch. * accepting any certificate despite a hostname mismatch.
*/ */
class TrustAllHostnameVerifier extends RefType { class TrustAllHostnameVerifier extends RefType {
@@ -45,16 +44,14 @@ class TrustAllHostnameVerifier extends RefType {
/** /**
* A configuration to model the flow of a `TrustAllHostnameVerifier` to a `set(Default)HostnameVerifier` call. * A configuration to model the flow of a `TrustAllHostnameVerifier` to a `set(Default)HostnameVerifier` call.
*/ */
class TrustAllHostnameVerifierConfiguration extends DataFlow::Configuration { private module TrustAllHostnameVerifierConfiguration implements DataFlow::ConfigSig {
TrustAllHostnameVerifierConfiguration() { this = "TrustAllHostnameVerifierConfiguration" } predicate isSource(DataFlow::Node source) {
override predicate isSource(DataFlow::Node source) {
source.asExpr().(ClassInstanceExpr).getConstructedType() instanceof TrustAllHostnameVerifier source.asExpr().(ClassInstanceExpr).getConstructedType() instanceof TrustAllHostnameVerifier
} }
override predicate isSink(DataFlow::Node sink) { sink instanceof HostnameVerifierSink } predicate isSink(DataFlow::Node sink) { sink instanceof HostnameVerifierSink }
override predicate isBarrier(DataFlow::Node barrier) { predicate isBarrier(DataFlow::Node barrier) {
// ignore nodes that are in functions that intentionally disable hostname verification // ignore nodes that are in functions that intentionally disable hostname verification
barrier barrier
.getEnclosingCallable() .getEnclosingCallable()
@@ -80,6 +77,10 @@ class TrustAllHostnameVerifierConfiguration extends DataFlow::Configuration {
} }
} }
module TrustAllHostnameVerifierFlow = DataFlow::Make<TrustAllHostnameVerifierConfiguration>;
import TrustAllHostnameVerifierFlow::PathGraph
/** /**
* A sink that sets the `HostnameVerifier` on `HttpsURLConnection`. * A sink that sets the `HostnameVerifier` on `HttpsURLConnection`.
*/ */
@@ -114,10 +115,10 @@ private predicate isNodeGuardedByFlag(DataFlow::Node node) {
} }
from from
DataFlow::PathNode source, DataFlow::PathNode sink, TrustAllHostnameVerifierConfiguration cfg, TrustAllHostnameVerifierFlow::PathNode source, TrustAllHostnameVerifierFlow::PathNode sink,
RefType verifier RefType verifier
where where
cfg.hasFlowPath(source, sink) and TrustAllHostnameVerifierFlow::hasFlowPath(source, sink) and
not isNodeGuardedByFlag(sink.getNode()) and not isNodeGuardedByFlag(sink.getNode()) and
verifier = source.getNode().asExpr().(ClassInstanceExpr).getConstructedType() verifier = source.getNode().asExpr().(ClassInstanceExpr).getConstructedType()
select sink, source, sink, select sink, source, sink,