Skip to content

Commit 8b5a423

Browse files
committed
Crypto: Convert ReusedNonce.ql into a path problem.
1 parent 7847e92 commit 8b5a423

File tree

2 files changed

+136
-11
lines changed

2 files changed

+136
-11
lines changed

java/ql/src/experimental/quantum/Examples/ReusedNonce.ql

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @name Reuse of cryptographic nonce
33
* @description Reuse of nonce in cryptographic operations can lead to vulnerabilities.
44
* @id java/quantum/reused-nonce
5-
* @kind problem
5+
* @kind path-problem
66
* @problem.severity error
77
* @precision high
88
* @tags quantum
@@ -12,16 +12,51 @@
1212
import java
1313
import ArtifactReuse
1414

15-
from Crypto::NonceArtifactNode nonce1, Crypto::NonceArtifactNode nonce2, Crypto::NodeBase sourceNode
15+
module NonceSrcFlowConfig implements DataFlow::ConfigSig {
16+
predicate isSource(DataFlow::Node source) {
17+
source = any(Crypto::GenericSourceInstance i).getOutputNode() or
18+
source = any(Crypto::ArtifactInstance artifact).getOutputNode()
19+
}
20+
21+
predicate isSink(DataFlow::Node sink) {
22+
exists(Crypto::NonceArtifactNode nonce | sink.asExpr() = nonce.asElement())
23+
}
24+
25+
predicate isBarrierOut(DataFlow::Node node) {
26+
node = any(Crypto::FlowAwareElement element).getInputNode()
27+
}
28+
29+
predicate isBarrierIn(DataFlow::Node node) {
30+
node = any(Crypto::FlowAwareElement element).getOutputNode()
31+
}
32+
33+
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
34+
node1.(AdditionalFlowInputStep).getOutput() = node2
35+
or
36+
exists(MethodCall m |
37+
m.getMethod().hasQualifiedName("java.lang", "String", "getBytes") and
38+
node1.asExpr() = m.getQualifier() and
39+
node2.asExpr() = m
40+
)
41+
}
42+
}
43+
44+
module NonceSrcFlow = TaintTracking::Global<NonceSrcFlowConfig>;
45+
46+
import NonceSrcFlow::PathGraph
47+
48+
from
49+
Crypto::NonceArtifactNode nonce1, Crypto::NonceArtifactNode nonce2, Crypto::NodeBase src,
50+
NonceSrcFlow::PathNode srcNode, NonceSrcFlow::PathNode sinkNode
1651
where
1752
isArtifactReuse(nonce1, nonce2) and
1853
// NOTE: in general we may not know a source, but see possible reuse,
1954
// we are not detecting these cases here (only where the source is the same).
20-
sourceNode = nonce1.getSourceNode() and
21-
sourceNode = nonce2.getSourceNode() and
55+
src = nonce1.getSourceNode() and
56+
src = nonce2.getSourceNode() and
2257
// Null literals are typically used for initialization, and if two 'nulls'
2358
// are reused, it is likely an uninitialization path that would result in a NullPointerException.
24-
not sourceNode.asElement() instanceof NullLiteral and
59+
not src.asElement() instanceof NullLiteral and
2560
// if the nonce is used in an encryption and decryption, ignore that reuse
2661
not exists(Crypto::CipherOperationNode op1, Crypto::CipherOperationNode op2 |
2762
op1 != op2 and
@@ -46,6 +81,9 @@ where
4681
op1.getKeyOperationSubtype() instanceof Crypto::TUnwrapMode
4782
)
4883
)
49-
)
50-
select sourceNode, "Nonce source is reused, see $@ and $@", nonce1, nonce1.toString(), nonce2,
84+
) and
85+
srcNode.getNode().asExpr() = src.asElement() and
86+
sinkNode.getNode().asExpr() = nonce1.asElement() and
87+
NonceSrcFlow::flowPath(srcNode, sinkNode)
88+
select sinkNode, srcNode, sinkNode, "Nonce source is reused, see alternate sink $@", nonce2,
5189
nonce2.toString()
Lines changed: 91 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,91 @@
1-
| Test.java:19:38:19:40 | RandomNumberGeneration | Nonce source is reused, see $@ and $@ | Test.java:40:47:40:52 | Nonce | Nonce | Test.java:49:47:49:52 | Nonce | Nonce |
2-
| Test.java:19:38:19:40 | RandomNumberGeneration | Nonce source is reused, see $@ and $@ | Test.java:49:47:49:52 | Nonce | Nonce | Test.java:40:47:40:52 | Nonce | Nonce |
3-
| Test.java:19:38:19:40 | RandomNumberGeneration | Nonce source is reused, see $@ and $@ | Test.java:76:48:76:54 | Nonce | Nonce | Test.java:82:49:82:55 | Nonce | Nonce |
4-
| Test.java:19:38:19:40 | RandomNumberGeneration | Nonce source is reused, see $@ and $@ | Test.java:82:49:82:55 | Nonce | Nonce | Test.java:76:48:76:54 | Nonce | Nonce |
1+
edges
2+
| Test.java:19:38:19:40 | val : byte[] | Test.java:20:16:20:18 | val : byte[] | provenance | |
3+
| Test.java:20:16:20:18 | val : byte[] | Test.java:25:15:25:33 | getRandomWrapper1(...) : byte[] | provenance | |
4+
| Test.java:20:16:20:18 | val : byte[] | Test.java:32:15:32:33 | getRandomWrapper1(...) : byte[] | provenance | |
5+
| Test.java:25:15:25:33 | getRandomWrapper1(...) : byte[] | Test.java:26:16:26:18 | val : byte[] | provenance | |
6+
| Test.java:25:15:25:33 | getRandomWrapper1(...) : byte[] | Test.java:27:16:27:18 | val : byte[] | provenance | |
7+
| Test.java:26:16:26:18 | val : byte[] | Test.java:36:32:36:40 | iv : byte[] | provenance | |
8+
| Test.java:27:16:27:18 | val : byte[] | Test.java:45:21:45:40 | getRandomWrapper2A(...) : byte[] | provenance | |
9+
| Test.java:32:15:32:33 | getRandomWrapper1(...) : byte[] | Test.java:33:16:33:18 | val : byte[] | provenance | |
10+
| Test.java:33:16:33:18 | val : byte[] | Test.java:54:21:54:40 | getRandomWrapper2b(...) : byte[] | provenance | |
11+
| Test.java:33:16:33:18 | val : byte[] | Test.java:63:21:63:40 | getRandomWrapper2b(...) : byte[] | provenance | |
12+
| Test.java:33:16:33:18 | val : byte[] | Test.java:72:21:72:40 | getRandomWrapper2b(...) : byte[] | provenance | |
13+
| Test.java:36:32:36:40 | iv : byte[] | Test.java:37:54:37:55 | iv : byte[] | provenance | |
14+
| Test.java:37:34:37:56 | new IvParameterSpec(...) : IvParameterSpec | Test.java:40:47:40:52 | ivSpec | provenance | Sink:MaD:45890 |
15+
| Test.java:37:54:37:55 | iv : byte[] | Test.java:37:34:37:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | Config |
16+
| Test.java:37:54:37:55 | iv : byte[] | Test.java:37:34:37:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | MaD:45920 |
17+
| Test.java:45:21:45:40 | getRandomWrapper2A(...) : byte[] | Test.java:46:54:46:55 | iv : byte[] | provenance | |
18+
| Test.java:46:34:46:56 | new IvParameterSpec(...) : IvParameterSpec | Test.java:49:47:49:52 | ivSpec | provenance | Sink:MaD:45890 |
19+
| Test.java:46:54:46:55 | iv : byte[] | Test.java:46:34:46:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | Config |
20+
| Test.java:46:54:46:55 | iv : byte[] | Test.java:46:34:46:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | MaD:45920 |
21+
| Test.java:54:21:54:40 | getRandomWrapper2b(...) : byte[] | Test.java:55:54:55:55 | iv : byte[] | provenance | |
22+
| Test.java:55:34:55:56 | new IvParameterSpec(...) : IvParameterSpec | Test.java:58:47:58:52 | ivSpec | provenance | Sink:MaD:45890 |
23+
| Test.java:55:54:55:55 | iv : byte[] | Test.java:55:34:55:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | Config |
24+
| Test.java:55:54:55:55 | iv : byte[] | Test.java:55:34:55:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | MaD:45920 |
25+
| Test.java:63:21:63:40 | getRandomWrapper2b(...) : byte[] | Test.java:64:54:64:55 | iv : byte[] | provenance | |
26+
| Test.java:64:34:64:56 | new IvParameterSpec(...) : IvParameterSpec | Test.java:67:47:67:52 | ivSpec | provenance | Sink:MaD:45890 |
27+
| Test.java:64:54:64:55 | iv : byte[] | Test.java:64:34:64:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | Config |
28+
| Test.java:64:54:64:55 | iv : byte[] | Test.java:64:34:64:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | MaD:45920 |
29+
| Test.java:72:21:72:40 | getRandomWrapper2b(...) : byte[] | Test.java:73:55:73:56 | iv : byte[] | provenance | |
30+
| Test.java:73:35:73:57 | new IvParameterSpec(...) : IvParameterSpec | Test.java:76:48:76:54 | ivSpec1 | provenance | Sink:MaD:45890 |
31+
| Test.java:73:55:73:56 | iv : byte[] | Test.java:73:35:73:57 | new IvParameterSpec(...) : IvParameterSpec | provenance | Config |
32+
| Test.java:73:55:73:56 | iv : byte[] | Test.java:73:35:73:57 | new IvParameterSpec(...) : IvParameterSpec | provenance | MaD:45920 |
33+
| Test.java:73:55:73:56 | iv : byte[] | Test.java:79:55:79:56 | iv : byte[] | provenance | |
34+
| Test.java:79:35:79:57 | new IvParameterSpec(...) : IvParameterSpec | Test.java:82:49:82:55 | ivSpec2 | provenance | Sink:MaD:45890 |
35+
| Test.java:79:55:79:56 | iv : byte[] | Test.java:79:35:79:57 | new IvParameterSpec(...) : IvParameterSpec | provenance | Config |
36+
| Test.java:79:55:79:56 | iv : byte[] | Test.java:79:35:79:57 | new IvParameterSpec(...) : IvParameterSpec | provenance | MaD:45920 |
37+
| Test.java:88:38:88:39 | iv : byte[] | Test.java:89:54:89:55 | iv : byte[] | provenance | |
38+
| Test.java:89:34:89:56 | new IvParameterSpec(...) : IvParameterSpec | Test.java:93:51:93:56 | ivSpec | provenance | Sink:MaD:45890 |
39+
| Test.java:89:34:89:56 | new IvParameterSpec(...) : IvParameterSpec | Test.java:96:51:96:56 | ivSpec | provenance | Sink:MaD:45890 |
40+
| Test.java:89:54:89:55 | iv : byte[] | Test.java:89:34:89:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | Config |
41+
| Test.java:89:54:89:55 | iv : byte[] | Test.java:89:34:89:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | MaD:45920 |
42+
| Test.java:103:38:103:39 | iv : byte[] | Test.java:104:54:104:55 | iv : byte[] | provenance | |
43+
| Test.java:104:34:104:56 | new IvParameterSpec(...) : IvParameterSpec | Test.java:107:47:107:52 | ivSpec | provenance | Sink:MaD:45890 |
44+
| Test.java:104:54:104:55 | iv : byte[] | Test.java:104:34:104:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | Config |
45+
| Test.java:104:54:104:55 | iv : byte[] | Test.java:104:34:104:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | MaD:45920 |
46+
nodes
47+
| Test.java:19:38:19:40 | val : byte[] | semmle.label | val : byte[] |
48+
| Test.java:20:16:20:18 | val : byte[] | semmle.label | val : byte[] |
49+
| Test.java:25:15:25:33 | getRandomWrapper1(...) : byte[] | semmle.label | getRandomWrapper1(...) : byte[] |
50+
| Test.java:26:16:26:18 | val : byte[] | semmle.label | val : byte[] |
51+
| Test.java:27:16:27:18 | val : byte[] | semmle.label | val : byte[] |
52+
| Test.java:32:15:32:33 | getRandomWrapper1(...) : byte[] | semmle.label | getRandomWrapper1(...) : byte[] |
53+
| Test.java:33:16:33:18 | val : byte[] | semmle.label | val : byte[] |
54+
| Test.java:36:32:36:40 | iv : byte[] | semmle.label | iv : byte[] |
55+
| Test.java:37:34:37:56 | new IvParameterSpec(...) : IvParameterSpec | semmle.label | new IvParameterSpec(...) : IvParameterSpec |
56+
| Test.java:37:54:37:55 | iv : byte[] | semmle.label | iv : byte[] |
57+
| Test.java:40:47:40:52 | ivSpec | semmle.label | ivSpec |
58+
| Test.java:45:21:45:40 | getRandomWrapper2A(...) : byte[] | semmle.label | getRandomWrapper2A(...) : byte[] |
59+
| Test.java:46:34:46:56 | new IvParameterSpec(...) : IvParameterSpec | semmle.label | new IvParameterSpec(...) : IvParameterSpec |
60+
| Test.java:46:54:46:55 | iv : byte[] | semmle.label | iv : byte[] |
61+
| Test.java:49:47:49:52 | ivSpec | semmle.label | ivSpec |
62+
| Test.java:54:21:54:40 | getRandomWrapper2b(...) : byte[] | semmle.label | getRandomWrapper2b(...) : byte[] |
63+
| Test.java:55:34:55:56 | new IvParameterSpec(...) : IvParameterSpec | semmle.label | new IvParameterSpec(...) : IvParameterSpec |
64+
| Test.java:55:54:55:55 | iv : byte[] | semmle.label | iv : byte[] |
65+
| Test.java:58:47:58:52 | ivSpec | semmle.label | ivSpec |
66+
| Test.java:63:21:63:40 | getRandomWrapper2b(...) : byte[] | semmle.label | getRandomWrapper2b(...) : byte[] |
67+
| Test.java:64:34:64:56 | new IvParameterSpec(...) : IvParameterSpec | semmle.label | new IvParameterSpec(...) : IvParameterSpec |
68+
| Test.java:64:54:64:55 | iv : byte[] | semmle.label | iv : byte[] |
69+
| Test.java:67:47:67:52 | ivSpec | semmle.label | ivSpec |
70+
| Test.java:72:21:72:40 | getRandomWrapper2b(...) : byte[] | semmle.label | getRandomWrapper2b(...) : byte[] |
71+
| Test.java:73:35:73:57 | new IvParameterSpec(...) : IvParameterSpec | semmle.label | new IvParameterSpec(...) : IvParameterSpec |
72+
| Test.java:73:55:73:56 | iv : byte[] | semmle.label | iv : byte[] |
73+
| Test.java:76:48:76:54 | ivSpec1 | semmle.label | ivSpec1 |
74+
| Test.java:79:35:79:57 | new IvParameterSpec(...) : IvParameterSpec | semmle.label | new IvParameterSpec(...) : IvParameterSpec |
75+
| Test.java:79:55:79:56 | iv : byte[] | semmle.label | iv : byte[] |
76+
| Test.java:82:49:82:55 | ivSpec2 | semmle.label | ivSpec2 |
77+
| Test.java:88:38:88:39 | iv : byte[] | semmle.label | iv : byte[] |
78+
| Test.java:89:34:89:56 | new IvParameterSpec(...) : IvParameterSpec | semmle.label | new IvParameterSpec(...) : IvParameterSpec |
79+
| Test.java:89:54:89:55 | iv : byte[] | semmle.label | iv : byte[] |
80+
| Test.java:93:51:93:56 | ivSpec | semmle.label | ivSpec |
81+
| Test.java:96:51:96:56 | ivSpec | semmle.label | ivSpec |
82+
| Test.java:103:38:103:39 | iv : byte[] | semmle.label | iv : byte[] |
83+
| Test.java:104:34:104:56 | new IvParameterSpec(...) : IvParameterSpec | semmle.label | new IvParameterSpec(...) : IvParameterSpec |
84+
| Test.java:104:54:104:55 | iv : byte[] | semmle.label | iv : byte[] |
85+
| Test.java:107:47:107:52 | ivSpec | semmle.label | ivSpec |
86+
subpaths
87+
#select
88+
| Test.java:40:47:40:52 | ivSpec | Test.java:19:38:19:40 | val : byte[] | Test.java:40:47:40:52 | ivSpec | Nonce source is reused, see alternate sink $@ | Test.java:49:47:49:52 | Nonce | Nonce |
89+
| Test.java:49:47:49:52 | ivSpec | Test.java:19:38:19:40 | val : byte[] | Test.java:49:47:49:52 | ivSpec | Nonce source is reused, see alternate sink $@ | Test.java:40:47:40:52 | Nonce | Nonce |
90+
| Test.java:76:48:76:54 | ivSpec1 | Test.java:19:38:19:40 | val : byte[] | Test.java:76:48:76:54 | ivSpec1 | Nonce source is reused, see alternate sink $@ | Test.java:82:49:82:55 | Nonce | Nonce |
91+
| Test.java:82:49:82:55 | ivSpec2 | Test.java:19:38:19:40 | val : byte[] | Test.java:82:49:82:55 | ivSpec2 | Nonce source is reused, see alternate sink $@ | Test.java:76:48:76:54 | Nonce | Nonce |

0 commit comments

Comments
 (0)