Skip to content

Commit a2fa03e

Browse files
Java: Improved the query for disabled certificate revocation checking
- Added a taint propagation step for List.of() methods - Added a testcase with one of the List.of() method - Simplified conditions - Fixed typos
1 parent 06e3f10 commit a2fa03e

File tree

4 files changed

+36
-9
lines changed

4 files changed

+36
-9
lines changed

java/ql/src/experimental/Security/CWE/CWE-299/DisabledRevocationChecking.qhelp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ revocation checker that uses OCSP to obtain revocation status of certificates.</
5656
</li>
5757
<li>
5858
Java SE API Specification:
59-
<a href="https://docs.oracle.com/javase/8/docs/api/index.html?java/security/cert/CertPathValidator.html">CertPathValidator</a>
59+
<a href="https://docs.oracle.com/javase/8/docs/api/java/security/cert/CertPathValidator.html">CertPathValidator</a>
6060
</li>
6161

6262
</references>

java/ql/src/experimental/Security/CWE/CWE-299/DisabledRevocationChecking.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* @name Disabled ceritificate revocation checking
33
* @description Using revoked certificates is dangerous.
4-
* Therefore, revocation status of ceritifcates in a chain should be checked.
4+
* Therefore, revocation status of certificates in a chain should be checked.
55
* @kind path-problem
66
* @problem.severity error
77
* @precision high

java/ql/src/experimental/Security/CWE/CWE-299/RevocationCheckingLib.qll

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class SettingRevocationCheckerConfig extends DataFlow2::Configuration {
5353

5454
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
5555
createSingletonListStep(node1, node2) or
56+
createListOfElementsStep(node1, node2) or
5657
convertArrayToListStep(node1, node2) or
5758
addToListStep(node1, node2)
5859
}
@@ -99,20 +100,20 @@ predicate createSingletonListStep(DataFlow::Node node1, DataFlow::Node node2) {
99100
m.getDeclaringType() instanceof Collections and
100101
m.hasName("singletonList") and
101102
ma.getArgument(0) = node1.asExpr() and
102-
(ma = node2.asExpr() or ma.getQualifier() = node2.asExpr())
103+
ma = node2.asExpr()
103104
)
104105
}
105106

106107
/**
107-
* Holds if `node1` to `node2` is a dataflow step that converts an array to a list,class
108+
* Holds if `node1` to `node2` is a dataflow step that converts an array to a list
108109
* i.e. `Arrays.asList(element)`.
109110
*/
110111
predicate convertArrayToListStep(DataFlow::Node node1, DataFlow::Node node2) {
111112
exists(StaticMethodAccess ma, Method m | m = ma.getMethod() |
112113
m.getDeclaringType() instanceof Arrays and
113114
m.hasName("asList") and
114115
ma.getArgument(0) = node1.asExpr() and
115-
(ma = node2.asExpr() or ma.getQualifier() = node2.asExpr())
116+
ma = node2.asExpr()
116117
)
117118
}
118119

@@ -128,7 +129,20 @@ predicate addToListStep(DataFlow::Node node1, DataFlow::Node node2) {
128129
m.hasName("addAll")
129130
) and
130131
ma.getArgument(0) = node1.asExpr() and
131-
(ma = node2.asExpr() or ma.getQualifier() = node2.asExpr())
132+
ma.getQualifier() = node2.asExpr()
133+
)
134+
}
135+
136+
/**
137+
* Holds if `node1` to `node2` is a dataflow step that creates a list,
138+
* i.e. `List.of(element)`.
139+
*/
140+
predicate createListOfElementsStep(DataFlow::Node node1, DataFlow::Node node2) {
141+
exists(StaticMethodAccess ma, Method m | m = ma.getMethod() |
142+
m.getDeclaringType() instanceof List and
143+
m.hasName("of") and
144+
ma.getAnArgument() = node1.asExpr() and
145+
ma = node2.asExpr()
132146
)
133147
}
134148

@@ -176,6 +190,9 @@ class Arrays extends RefType {
176190
Arrays() { hasQualifiedName("java.util", "Arrays") }
177191
}
178192

179-
class List extends ParameterizedInterface {
180-
List() { getGenericType().hasQualifiedName("java.util", "List") }
193+
class List extends RefType {
194+
List() {
195+
this.hasQualifiedName("java.util", "List<>") or
196+
this.(ParameterizedInterface).getGenericType().hasQualifiedName("java.util", "List")
197+
}
181198
}

java/ql/test/experimental/Security/CWE/CWE-299/DisabledRevocationChecking.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public void testSettingRevocationCheckerWithArraysAsList(KeyStore cacerts, CertP
4747
validator.validate(certPath, params);
4848
}
4949

50-
public void testSettingRevocationCheckerWithList(KeyStore cacerts, CertPath certPath) throws Exception {
50+
public void testSettingRevocationCheckerWithAddingToArrayList(KeyStore cacerts, CertPath certPath) throws Exception {
5151
CertPathValidator validator = CertPathValidator.getInstance("PKIX");
5252
PKIXParameters params = new PKIXParameters(cacerts);
5353
params.setRevocationEnabled(false);
@@ -58,6 +58,16 @@ public void testSettingRevocationCheckerWithList(KeyStore cacerts, CertPath cert
5858
validator.validate(certPath, params);
5959
}
6060

61+
public void testSettingRevocationCheckerWithListOf(KeyStore cacerts, CertPath certPath) throws Exception {
62+
CertPathValidator validator = CertPathValidator.getInstance("PKIX");
63+
PKIXParameters params = new PKIXParameters(cacerts);
64+
params.setRevocationEnabled(false);
65+
PKIXRevocationChecker checker = (PKIXRevocationChecker) validator.getRevocationChecker();
66+
List<PKIXCertPathChecker> checkers = List.of(checker);
67+
params.setCertPathCheckers(checkers);
68+
validator.validate(certPath, params);
69+
}
70+
6171
public void testAddingRevocationChecker(KeyStore cacerts, CertPath certPath) throws Exception {
6272
CertPathValidator validator = CertPathValidator.getInstance("PKIX");
6373
PKIXParameters params = new PKIXParameters(cacerts);

0 commit comments

Comments
 (0)