Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit eb91ecf

Browse files
committed
Add generic artifact data-flow
The relation between RNG and other artifacts has been added Nonce has been completed to report its source
1 parent 2b0b927 commit eb91ecf

2 files changed

Lines changed: 79 additions & 12 deletions

File tree

java/ql/lib/experimental/Quantum/Language.qll

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ private import codeql.cryptography.Model
22
private import java as Language
33
private import semmle.code.java.security.InsecureRandomnessQuery
44
private import semmle.code.java.security.RandomQuery
5+
private import semmle.code.java.dataflow.DataFlow
56

67
private class UnknownLocation extends Language::Location {
78
UnknownLocation() { this.getFile().getAbsolutePath() = "" }
@@ -36,6 +37,10 @@ module Crypto = CryptographyBase<Language::Location, CryptoInput>;
3637
*/
3738
abstract class RandomnessInstance extends Crypto::RandomNumberGenerationInstance {
3839
override DataFlow::Node asOutputData() { result.asExpr() = this }
40+
41+
override predicate flowsTo(Crypto::ArtifactLocatableElement other) {
42+
RNGToArtifactFlow::flow(this.asOutputData(), other.getInput())
43+
}
3944
}
4045

4146
class SecureRandomnessInstance extends RandomnessInstance {
@@ -50,5 +55,20 @@ class InsecureRandomnessInstance extends RandomnessInstance {
5055
InsecureRandomnessInstance() { exists(InsecureRandomnessSource node | this = node.asExpr()) }
5156
}
5257

58+
/**
59+
* Random number generation artifact to other artifact flow configuration
60+
*/
61+
module RNGToArtifactFlowConfig implements DataFlow::ConfigSig {
62+
predicate isSource(DataFlow::Node source) {
63+
source = any(Crypto::RandomNumberGenerationInstance rng).asOutputData()
64+
}
65+
66+
predicate isSink(DataFlow::Node sink) {
67+
sink = any(Crypto::ArtifactLocatableElement other).getInput()
68+
}
69+
}
70+
71+
module RNGToArtifactFlow = DataFlow::Global<RNGToArtifactFlowConfig>;
72+
5373
// Import library-specific modeling
5474
import JCA

shared/cryptography/codeql/cryptography/Model.qll

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
4747

4848
predicate nodes_graph_impl(NodeBase node, string key, string value) {
4949
not (
50-
// exclude Artifact nodes with no edges to or from them
51-
node instanceof Artifact and
50+
// exclude certain Artifact nodes with no edges to or from them
51+
node instanceof RandomNumberGeneration and
52+
// TODO: performance?
5253
not (edges_graph_impl(node, _, _, _) or edges_graph_impl(_, node, _, _))
5354
) and
5455
(
@@ -110,17 +111,47 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
110111
abstract class PaddingAlgorithmInstance extends LocatableElement { }
111112

112113
// Artifacts
113-
abstract private class ArtifactLocatableElement extends LocatableElement {
114+
abstract class ArtifactLocatableElement extends LocatableElement {
115+
/**
116+
* Gets the output node for this artifact, which should usually be the same as `this`.
117+
*/
114118
abstract DataFlowNode asOutputData();
115119

120+
/**
121+
* Gets the input node for this artifact.
122+
*
123+
* If `getInput` is implemented as `none()`, the artifact will not have inbound flow analysis.
124+
*/
116125
abstract DataFlowNode getInput();
126+
127+
/**
128+
* Holds if this artifact flows to `other`.
129+
*
130+
* This predicate should be defined generically per-language with library-specific extension support.
131+
* The expected implementation is to perform flow analysis from this artifact's output to another artifact's input.
132+
* The `other` argument should be one or more `ArtifactLocatableElement` that are sinks of the flow.
133+
*
134+
* If `flowsTo` is implemented as `none()`, the artifact will not have outbound flow analysis.
135+
*/
136+
abstract predicate flowsTo(ArtifactLocatableElement other);
117137
}
118138

139+
newtype TGenericDataSourceType =
140+
FilesystemDataSource() or
141+
ExternalLibraryDataSource() or
142+
MemoryAllocationDataSource() or
143+
ConstantDataSource()
144+
145+
abstract class GenericDataSourceInstance extends ArtifactLocatableElement { }
146+
119147
abstract class DigestArtifactInstance extends ArtifactLocatableElement { }
120148

121149
abstract class KeyArtifactInstance extends ArtifactLocatableElement { }
122150

123-
abstract class NonceArtifactInstance extends ArtifactLocatableElement { }
151+
abstract class NonceArtifactInstance extends ArtifactLocatableElement {
152+
// no implicit outbound data-flow (only modelled in cipher operations)
153+
override predicate flowsTo(ArtifactLocatableElement other) { none() }
154+
}
124155

125156
abstract class RandomNumberGenerationInstance extends ArtifactLocatableElement {
126157
final override DataFlowNode getInput() { none() }
@@ -206,10 +237,30 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
206237

207238
class Asset = NodeBase;
208239

240+
/**
241+
* An artifact is an instance of data that is used in a cryptographic operation or produced by one.
242+
*/
209243
abstract class Artifact extends NodeBase {
210-
abstract DataFlowNode asOutputData();
244+
/**
245+
* Gets the artifact locatable element associated with this artifact.
246+
*
247+
* *Implementation note*: to avoid cross-products, the result *must* only bind to the
248+
* `ArtifactLocatableElement` that is already associated with the node instance.
249+
*/
250+
abstract ArtifactLocatableElement asArtifactLocatableElement();
211251

212-
abstract DataFlowNode getInputData();
252+
final Artifact getSourceArtifact() {
253+
not result = this and
254+
result.asArtifactLocatableElement().flowsTo(this.asArtifactLocatableElement())
255+
}
256+
257+
override NodeBase getChild(string edgeName) {
258+
result = super.getChild(edgeName)
259+
or
260+
// [ONLY_KNOWN] - TODO: unknown case handled by reporting a generic source type or unknown as a property
261+
edgeName = "source" and
262+
result = this.getSourceArtifact()
263+
}
213264
}
214265

215266
/**
@@ -224,9 +275,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
224275

225276
override Location getLocation() { result = instance.getLocation() }
226277

227-
override DataFlowNode asOutputData() { result = instance.asOutputData() }
228-
229-
override DataFlowNode getInputData() { result = instance.getInput() }
278+
override ArtifactLocatableElement asArtifactLocatableElement() { result = instance }
230279
}
231280

232281
final class Nonce = NonceImpl;
@@ -243,9 +292,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
243292

244293
override Location getLocation() { result = instance.getLocation() }
245294

246-
override DataFlowNode asOutputData() { result = instance.asOutputData() }
247-
248-
override DataFlowNode getInputData() { result = instance.getInput() }
295+
override ArtifactLocatableElement asArtifactLocatableElement() { result = instance }
249296
}
250297

251298
final class RandomNumberGeneration = RandomNumberGenerationImpl;

0 commit comments

Comments
 (0)