Skip to content

Commit 5ec8e5d

Browse files
committed
Python: Setup support for threat-models
Naming in other languages: - `SourceNode` (for QL only modeling) - `ThreatModelFlowSource` (for active sources from QL or data-extensions) However, since we use `LocalSourceNode` in Python, and `SourceNode` in JS (for local source nodes), it seems a bit confusing to follow the same naming convention as other languages, and instead I came up with new names.
1 parent 25fc5f3 commit 5ec8e5d

File tree

4 files changed

+61
-11
lines changed

4 files changed

+61
-11
lines changed

python/ql/lib/qlpack.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ dependencies:
99
codeql/dataflow: ${workspace}
1010
codeql/mad: ${workspace}
1111
codeql/regex: ${workspace}
12+
codeql/threat-models: ${workspace}
1213
codeql/tutorial: ${workspace}
1314
codeql/util: ${workspace}
1415
codeql/xml: ${workspace}

python/ql/lib/semmle/python/Concepts.qll

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,54 @@ private import semmle.python.dataflow.new.RemoteFlowSources
1010
private import semmle.python.dataflow.new.TaintTracking
1111
private import semmle.python.Frameworks
1212
private import semmle.python.security.internal.EncryptionKeySizes
13+
private import codeql.threatmodels.ThreatModels
14+
15+
/**
16+
* A data flow source, for a specific threat-model.
17+
*
18+
* Extend this class to refine existing API models. If you want to model new APIs,
19+
* extend `ThreatModelSource::Range` instead.
20+
*/
21+
class ThreatModelSource extends DataFlow::Node instanceof ThreatModelSource::Range {
22+
/**
23+
* Gets a string that represents the source kind with respect to threat modeling.
24+
*/
25+
string getThreatModel() { result = super.getThreatModel() }
26+
27+
/** Gets a string that describes the type of this threat-model source. */
28+
string getSourceType() { result = super.getSourceType() }
29+
}
30+
31+
/** Provides a class for modeling new sources for specific threat-models. */
32+
module ThreatModelSource {
33+
/**
34+
* A data flow source, for a specific threat-model.
35+
*
36+
* Extend this class to model new APIs. If you want to refine existing API models,
37+
* extend `ThreatModelSource` instead.
38+
*/
39+
abstract class Range extends DataFlow::Node {
40+
/**
41+
* Gets a string that represents the source kind with respect to threat modeling.
42+
*/
43+
abstract string getThreatModel();
44+
45+
/** Gets a string that describes the type of this threat-model source. */
46+
abstract string getSourceType();
47+
}
48+
}
49+
50+
/**
51+
* A data flow source that is enabled in the current threat model configuration.
52+
*/
53+
class ActiveThreatModelSource extends DataFlow::Node {
54+
ActiveThreatModelSource() {
55+
exists(string kind |
56+
currentThreatModel(kind) and
57+
this.(ThreatModelSource).getThreatModel() = kind
58+
)
59+
}
60+
}
1361

1462
/**
1563
* A data-flow node that executes an operating system command,

python/ql/lib/semmle/python/dataflow/new/RemoteFlowSources.qll

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,7 @@ private import semmle.python.Concepts
1515
* Extend this class to refine existing API models. If you want to model new APIs,
1616
* extend `RemoteFlowSource::Range` instead.
1717
*/
18-
class RemoteFlowSource extends DataFlow::Node instanceof RemoteFlowSource::Range {
19-
/** Gets a string that describes the type of this remote flow source. */
20-
string getSourceType() { result = super.getSourceType() }
21-
}
18+
class RemoteFlowSource extends ThreatModelSource instanceof RemoteFlowSource::Range { }
2219

2320
/** Provides a class for modeling new sources of remote user input. */
2421
module RemoteFlowSource {
@@ -28,8 +25,7 @@ module RemoteFlowSource {
2825
* Extend this class to model new APIs. If you want to refine existing API models,
2926
* extend `RemoteFlowSource` instead.
3027
*/
31-
abstract class Range extends DataFlow::Node {
32-
/** Gets a string that describes the type of this remote flow source. */
33-
abstract string getSourceType();
28+
abstract class Range extends ThreatModelSource::Range {
29+
override string getThreatModel() { result = "remote" }
3430
}
3531
}

python/ql/lib/semmle/python/frameworks/data/ModelsAsData.qll

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,19 @@ private import semmle.python.dataflow.new.RemoteFlowSources
1818
private import semmle.python.dataflow.new.DataFlow
1919
private import semmle.python.ApiGraphs
2020
private import semmle.python.dataflow.new.FlowSummary
21+
private import semmle.python.Concepts
2122

2223
/**
23-
* A remote flow source originating from a CSV source row.
24+
* A threat-model flow source originating from a data extension.
2425
*/
25-
private class RemoteFlowSourceFromCsv extends RemoteFlowSource::Range {
26-
RemoteFlowSourceFromCsv() { this = ModelOutput::getASourceNode("remote").asSource() }
26+
private class ThreatModelSourceFromDataExtension extends ThreatModelSource::Range {
27+
ThreatModelSourceFromDataExtension() { this = ModelOutput::getASourceNode(_).asSource() }
2728

28-
override string getSourceType() { result = "Remote flow (from model)" }
29+
override string getThreatModel() { this = ModelOutput::getASourceNode(result).asSource() }
30+
31+
override string getSourceType() {
32+
result = "Source node (" + this.getThreatModel() + ") [from data-extension]"
33+
}
2934
}
3035

3136
private class SummarizedCallableFromModel extends SummarizedCallable {

0 commit comments

Comments
 (0)