Crypto: Convert ReusedNonce.ql into a path problem.

This commit is contained in:
REDMOND\brodes
2025-10-13 15:34:41 -04:00
parent 7847e92670
commit 8b5a42328e
2 changed files with 136 additions and 11 deletions

View File

@@ -2,7 +2,7 @@
* @name Reuse of cryptographic nonce
* @description Reuse of nonce in cryptographic operations can lead to vulnerabilities.
* @id java/quantum/reused-nonce
* @kind problem
* @kind path-problem
* @problem.severity error
* @precision high
* @tags quantum
@@ -12,16 +12,51 @@
import java
import ArtifactReuse
from Crypto::NonceArtifactNode nonce1, Crypto::NonceArtifactNode nonce2, Crypto::NodeBase sourceNode
module NonceSrcFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source = any(Crypto::GenericSourceInstance i).getOutputNode() or
source = any(Crypto::ArtifactInstance artifact).getOutputNode()
}
predicate isSink(DataFlow::Node sink) {
exists(Crypto::NonceArtifactNode nonce | sink.asExpr() = nonce.asElement())
}
predicate isBarrierOut(DataFlow::Node node) {
node = any(Crypto::FlowAwareElement element).getInputNode()
}
predicate isBarrierIn(DataFlow::Node node) {
node = any(Crypto::FlowAwareElement element).getOutputNode()
}
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
node1.(AdditionalFlowInputStep).getOutput() = node2
or
exists(MethodCall m |
m.getMethod().hasQualifiedName("java.lang", "String", "getBytes") and
node1.asExpr() = m.getQualifier() and
node2.asExpr() = m
)
}
}
module NonceSrcFlow = TaintTracking::Global<NonceSrcFlowConfig>;
import NonceSrcFlow::PathGraph
from
Crypto::NonceArtifactNode nonce1, Crypto::NonceArtifactNode nonce2, Crypto::NodeBase src,
NonceSrcFlow::PathNode srcNode, NonceSrcFlow::PathNode sinkNode
where
isArtifactReuse(nonce1, nonce2) and
// NOTE: in general we may not know a source, but see possible reuse,
// we are not detecting these cases here (only where the source is the same).
sourceNode = nonce1.getSourceNode() and
sourceNode = nonce2.getSourceNode() and
src = nonce1.getSourceNode() and
src = nonce2.getSourceNode() and
// Null literals are typically used for initialization, and if two 'nulls'
// are reused, it is likely an uninitialization path that would result in a NullPointerException.
not sourceNode.asElement() instanceof NullLiteral and
not src.asElement() instanceof NullLiteral and
// if the nonce is used in an encryption and decryption, ignore that reuse
not exists(Crypto::CipherOperationNode op1, Crypto::CipherOperationNode op2 |
op1 != op2 and
@@ -46,6 +81,9 @@ where
op1.getKeyOperationSubtype() instanceof Crypto::TUnwrapMode
)
)
)
select sourceNode, "Nonce source is reused, see $@ and $@", nonce1, nonce1.toString(), nonce2,
) and
srcNode.getNode().asExpr() = src.asElement() and
sinkNode.getNode().asExpr() = nonce1.asElement() and
NonceSrcFlow::flowPath(srcNode, sinkNode)
select sinkNode, srcNode, sinkNode, "Nonce source is reused, see alternate sink $@", nonce2,
nonce2.toString()

View File

@@ -1,4 +1,91 @@
| 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 |
| 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 |
| 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 |
| 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 |
edges
| Test.java:19:38:19:40 | val : byte[] | Test.java:20:16:20:18 | val : byte[] | provenance | |
| Test.java:20:16:20:18 | val : byte[] | Test.java:25:15:25:33 | getRandomWrapper1(...) : byte[] | provenance | |
| Test.java:20:16:20:18 | val : byte[] | Test.java:32:15:32:33 | getRandomWrapper1(...) : byte[] | provenance | |
| Test.java:25:15:25:33 | getRandomWrapper1(...) : byte[] | Test.java:26:16:26:18 | val : byte[] | provenance | |
| Test.java:25:15:25:33 | getRandomWrapper1(...) : byte[] | Test.java:27:16:27:18 | val : byte[] | provenance | |
| Test.java:26:16:26:18 | val : byte[] | Test.java:36:32:36:40 | iv : byte[] | provenance | |
| Test.java:27:16:27:18 | val : byte[] | Test.java:45:21:45:40 | getRandomWrapper2A(...) : byte[] | provenance | |
| Test.java:32:15:32:33 | getRandomWrapper1(...) : byte[] | Test.java:33:16:33:18 | val : byte[] | provenance | |
| Test.java:33:16:33:18 | val : byte[] | Test.java:54:21:54:40 | getRandomWrapper2b(...) : byte[] | provenance | |
| Test.java:33:16:33:18 | val : byte[] | Test.java:63:21:63:40 | getRandomWrapper2b(...) : byte[] | provenance | |
| Test.java:33:16:33:18 | val : byte[] | Test.java:72:21:72:40 | getRandomWrapper2b(...) : byte[] | provenance | |
| Test.java:36:32:36:40 | iv : byte[] | Test.java:37:54:37:55 | iv : byte[] | provenance | |
| Test.java:37:34:37:56 | new IvParameterSpec(...) : IvParameterSpec | Test.java:40:47:40:52 | ivSpec | provenance | Sink:MaD:45890 |
| Test.java:37:54:37:55 | iv : byte[] | Test.java:37:34:37:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | Config |
| Test.java:37:54:37:55 | iv : byte[] | Test.java:37:34:37:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | MaD:45920 |
| Test.java:45:21:45:40 | getRandomWrapper2A(...) : byte[] | Test.java:46:54:46:55 | iv : byte[] | provenance | |
| Test.java:46:34:46:56 | new IvParameterSpec(...) : IvParameterSpec | Test.java:49:47:49:52 | ivSpec | provenance | Sink:MaD:45890 |
| Test.java:46:54:46:55 | iv : byte[] | Test.java:46:34:46:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | Config |
| Test.java:46:54:46:55 | iv : byte[] | Test.java:46:34:46:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | MaD:45920 |
| Test.java:54:21:54:40 | getRandomWrapper2b(...) : byte[] | Test.java:55:54:55:55 | iv : byte[] | provenance | |
| Test.java:55:34:55:56 | new IvParameterSpec(...) : IvParameterSpec | Test.java:58:47:58:52 | ivSpec | provenance | Sink:MaD:45890 |
| Test.java:55:54:55:55 | iv : byte[] | Test.java:55:34:55:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | Config |
| Test.java:55:54:55:55 | iv : byte[] | Test.java:55:34:55:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | MaD:45920 |
| Test.java:63:21:63:40 | getRandomWrapper2b(...) : byte[] | Test.java:64:54:64:55 | iv : byte[] | provenance | |
| Test.java:64:34:64:56 | new IvParameterSpec(...) : IvParameterSpec | Test.java:67:47:67:52 | ivSpec | provenance | Sink:MaD:45890 |
| Test.java:64:54:64:55 | iv : byte[] | Test.java:64:34:64:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | Config |
| Test.java:64:54:64:55 | iv : byte[] | Test.java:64:34:64:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | MaD:45920 |
| Test.java:72:21:72:40 | getRandomWrapper2b(...) : byte[] | Test.java:73:55:73:56 | iv : byte[] | provenance | |
| Test.java:73:35:73:57 | new IvParameterSpec(...) : IvParameterSpec | Test.java:76:48:76:54 | ivSpec1 | provenance | Sink:MaD:45890 |
| Test.java:73:55:73:56 | iv : byte[] | Test.java:73:35:73:57 | new IvParameterSpec(...) : IvParameterSpec | provenance | Config |
| Test.java:73:55:73:56 | iv : byte[] | Test.java:73:35:73:57 | new IvParameterSpec(...) : IvParameterSpec | provenance | MaD:45920 |
| Test.java:73:55:73:56 | iv : byte[] | Test.java:79:55:79:56 | iv : byte[] | provenance | |
| Test.java:79:35:79:57 | new IvParameterSpec(...) : IvParameterSpec | Test.java:82:49:82:55 | ivSpec2 | provenance | Sink:MaD:45890 |
| Test.java:79:55:79:56 | iv : byte[] | Test.java:79:35:79:57 | new IvParameterSpec(...) : IvParameterSpec | provenance | Config |
| Test.java:79:55:79:56 | iv : byte[] | Test.java:79:35:79:57 | new IvParameterSpec(...) : IvParameterSpec | provenance | MaD:45920 |
| Test.java:88:38:88:39 | iv : byte[] | Test.java:89:54:89:55 | iv : byte[] | provenance | |
| Test.java:89:34:89:56 | new IvParameterSpec(...) : IvParameterSpec | Test.java:93:51:93:56 | ivSpec | provenance | Sink:MaD:45890 |
| Test.java:89:34:89:56 | new IvParameterSpec(...) : IvParameterSpec | Test.java:96:51:96:56 | ivSpec | provenance | Sink:MaD:45890 |
| Test.java:89:54:89:55 | iv : byte[] | Test.java:89:34:89:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | Config |
| Test.java:89:54:89:55 | iv : byte[] | Test.java:89:34:89:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | MaD:45920 |
| Test.java:103:38:103:39 | iv : byte[] | Test.java:104:54:104:55 | iv : byte[] | provenance | |
| Test.java:104:34:104:56 | new IvParameterSpec(...) : IvParameterSpec | Test.java:107:47:107:52 | ivSpec | provenance | Sink:MaD:45890 |
| Test.java:104:54:104:55 | iv : byte[] | Test.java:104:34:104:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | Config |
| Test.java:104:54:104:55 | iv : byte[] | Test.java:104:34:104:56 | new IvParameterSpec(...) : IvParameterSpec | provenance | MaD:45920 |
nodes
| Test.java:19:38:19:40 | val : byte[] | semmle.label | val : byte[] |
| Test.java:20:16:20:18 | val : byte[] | semmle.label | val : byte[] |
| Test.java:25:15:25:33 | getRandomWrapper1(...) : byte[] | semmle.label | getRandomWrapper1(...) : byte[] |
| Test.java:26:16:26:18 | val : byte[] | semmle.label | val : byte[] |
| Test.java:27:16:27:18 | val : byte[] | semmle.label | val : byte[] |
| Test.java:32:15:32:33 | getRandomWrapper1(...) : byte[] | semmle.label | getRandomWrapper1(...) : byte[] |
| Test.java:33:16:33:18 | val : byte[] | semmle.label | val : byte[] |
| Test.java:36:32:36:40 | iv : byte[] | semmle.label | iv : byte[] |
| Test.java:37:34:37:56 | new IvParameterSpec(...) : IvParameterSpec | semmle.label | new IvParameterSpec(...) : IvParameterSpec |
| Test.java:37:54:37:55 | iv : byte[] | semmle.label | iv : byte[] |
| Test.java:40:47:40:52 | ivSpec | semmle.label | ivSpec |
| Test.java:45:21:45:40 | getRandomWrapper2A(...) : byte[] | semmle.label | getRandomWrapper2A(...) : byte[] |
| Test.java:46:34:46:56 | new IvParameterSpec(...) : IvParameterSpec | semmle.label | new IvParameterSpec(...) : IvParameterSpec |
| Test.java:46:54:46:55 | iv : byte[] | semmle.label | iv : byte[] |
| Test.java:49:47:49:52 | ivSpec | semmle.label | ivSpec |
| Test.java:54:21:54:40 | getRandomWrapper2b(...) : byte[] | semmle.label | getRandomWrapper2b(...) : byte[] |
| Test.java:55:34:55:56 | new IvParameterSpec(...) : IvParameterSpec | semmle.label | new IvParameterSpec(...) : IvParameterSpec |
| Test.java:55:54:55:55 | iv : byte[] | semmle.label | iv : byte[] |
| Test.java:58:47:58:52 | ivSpec | semmle.label | ivSpec |
| Test.java:63:21:63:40 | getRandomWrapper2b(...) : byte[] | semmle.label | getRandomWrapper2b(...) : byte[] |
| Test.java:64:34:64:56 | new IvParameterSpec(...) : IvParameterSpec | semmle.label | new IvParameterSpec(...) : IvParameterSpec |
| Test.java:64:54:64:55 | iv : byte[] | semmle.label | iv : byte[] |
| Test.java:67:47:67:52 | ivSpec | semmle.label | ivSpec |
| Test.java:72:21:72:40 | getRandomWrapper2b(...) : byte[] | semmle.label | getRandomWrapper2b(...) : byte[] |
| Test.java:73:35:73:57 | new IvParameterSpec(...) : IvParameterSpec | semmle.label | new IvParameterSpec(...) : IvParameterSpec |
| Test.java:73:55:73:56 | iv : byte[] | semmle.label | iv : byte[] |
| Test.java:76:48:76:54 | ivSpec1 | semmle.label | ivSpec1 |
| Test.java:79:35:79:57 | new IvParameterSpec(...) : IvParameterSpec | semmle.label | new IvParameterSpec(...) : IvParameterSpec |
| Test.java:79:55:79:56 | iv : byte[] | semmle.label | iv : byte[] |
| Test.java:82:49:82:55 | ivSpec2 | semmle.label | ivSpec2 |
| Test.java:88:38:88:39 | iv : byte[] | semmle.label | iv : byte[] |
| Test.java:89:34:89:56 | new IvParameterSpec(...) : IvParameterSpec | semmle.label | new IvParameterSpec(...) : IvParameterSpec |
| Test.java:89:54:89:55 | iv : byte[] | semmle.label | iv : byte[] |
| Test.java:93:51:93:56 | ivSpec | semmle.label | ivSpec |
| Test.java:96:51:96:56 | ivSpec | semmle.label | ivSpec |
| Test.java:103:38:103:39 | iv : byte[] | semmle.label | iv : byte[] |
| Test.java:104:34:104:56 | new IvParameterSpec(...) : IvParameterSpec | semmle.label | new IvParameterSpec(...) : IvParameterSpec |
| Test.java:104:54:104:55 | iv : byte[] | semmle.label | iv : byte[] |
| Test.java:107:47:107:52 | ivSpec | semmle.label | ivSpec |
subpaths
#select
| 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 |
| 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 |
| 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 |
| 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 |