Skip to content

Commit f53b2fc

Browse files
Updated IgnoredHostnameVerification.ql to cover more uses of HostnameVerifier.verify()
1 parent 825fe17 commit f53b2fc

File tree

3 files changed

+13
-54
lines changed

3 files changed

+13
-54
lines changed

java/ql/src/experimental/Security/CWE/CWE-297/IgnoredHostnameVerification.ql

Lines changed: 5 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,13 @@
44
* A caller has to check the result and drop the connection if the verification failed.
55
* @kind problem
66
* @problem.severity error
7-
* @precision medium
7+
* @precision high
88
* @id java/ignored-hostname-verification
99
* @tags security
1010
* external/cwe/cwe-297
1111
*/
1212

1313
import java
14-
import semmle.code.java.controlflow.Guards
15-
import semmle.code.java.dataflow.DataFlow
1614

1715
/** The `HostnameVerifier.verify()` method. */
1816
private class HostnameVerifierVerifyMethod extends Method {
@@ -22,45 +20,17 @@ private class HostnameVerifierVerifyMethod extends Method {
2220
}
2321
}
2422

25-
/** Defines `HostnameVerifier.verity()` calls that are not wrapped by another `HostnameVerifier`. */
23+
/** Defines `HostnameVerifier.verity()` calls that is not wrapped in another `HostnameVerifier`. */
2624
private class HostnameVerificationCall extends MethodAccess {
2725
HostnameVerificationCall() {
2826
this.getMethod() instanceof HostnameVerifierVerifyMethod and
2927
not this.getCaller() instanceof HostnameVerifierVerifyMethod
3028
}
3129

32-
/** Holds if the result if the call is not useds. */
30+
/** Holds if the result of the call is not used. */
3331
predicate isIgnored() {
34-
not exists(
35-
DataFlow::Node source, DataFlow::Node sink, CheckFailedHostnameVerificationConfig config
36-
|
37-
this = source.asExpr() and config.hasFlow(source, sink)
38-
)
39-
}
40-
}
41-
42-
/**
43-
* A configuration that tracks data flows from the result of a `HostnameVerifier.vefiry()` call
44-
* to a condition that controls a throw statement.
45-
*/
46-
private class CheckFailedHostnameVerificationConfig extends DataFlow::Configuration {
47-
CheckFailedHostnameVerificationConfig() { this = "CheckFailedHostnameVerificationConfig" }
48-
49-
override predicate isSource(DataFlow::Node source) {
50-
source.asExpr() instanceof HostnameVerificationCall
51-
}
52-
53-
override predicate isSink(DataFlow::Node sink) {
54-
exists(Guard guard, ThrowStmt throwStmt, ReturnStmt returnStmt |
55-
(
56-
guard.controls(throwStmt.getBasicBlock(), false) or
57-
guard.controls(returnStmt.getBasicBlock(), true)
58-
) and
59-
(
60-
guard = sink.asExpr() or
61-
guard.(EqualityTest).getAnOperand() = sink.asExpr() or
62-
guard.(HostnameVerificationCall) = sink.asExpr()
63-
)
32+
not exists(Expr expr, IfStmt ifStmt, MethodAccess ma |
33+
this = [expr.getAChildExpr(), ifStmt.getCondition(), ma.getAnArgument()]
6434
)
6535
}
6636
}
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
| IgnoredHostnameVerification.java:16:5:16:46 | verify(...) | Ignored result of hostname verification. |
2-
| IgnoredHostnameVerification.java:26:22:26:63 | verify(...) | Ignored result of hostname verification. |
3-
| IgnoredHostnameVerification.java:37:22:37:63 | verify(...) | Ignored result of hostname verification. |
1+
| IgnoredHostnameVerification.java:16:5:16:46 | verify(...) | Ignored result of hostname verification. |

java/ql/test/experimental/query-tests/security/CWE-297/IgnoredHostnameVerification.java

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,19 @@ public static SSLSocket connectWithIgnoredHostnameVerification(
1717
return socket;
1818
}
1919

20-
// BAD: ignored result of HostnameVerifier.verify()
21-
public static SSLSocket connectAndOnlyPrintResultOfHostnameVerification(
22-
String host, int port, HostnameVerifier verifier) throws IOException {
23-
24-
SSLSocket socket = (SSLSocket) SSLSocketFactory.getDefault().createSocket(host, port);
25-
socket.startHandshake();
26-
boolean result = verifier.verify(host, socket.getSession());
27-
System.out.println("Result of hostname verification: " + result);
28-
return socket;
20+
public static void check(boolean result) throws SSLException {
21+
if (!result) {
22+
throw new SSLException("Oops! Hostname verification failed!");
23+
}
2924
}
3025

31-
// BAD: ignored result of HostnameVerifier.verify()
32-
public static SSLSocket connectAndOnlyPrintFailureOfHostnameVerification(
26+
// GOOD: connect and check result of HostnameVerifier.verify()
27+
public static SSLSocket connectWithHostnameVerification00(
3328
String host, int port, HostnameVerifier verifier) throws IOException {
3429

3530
SSLSocket socket = (SSLSocket) SSLSocketFactory.getDefault().createSocket(host, port);
3631
socket.startHandshake();
37-
boolean failed = verifier.verify(host, socket.getSession());
38-
if (failed) {
39-
System.out.println("Hostname verification failed");
40-
}
41-
32+
check(verifier.verify(host, socket.getSession()));
4233
return socket;
4334
}
4435

0 commit comments

Comments
 (0)