Skip to content

Commit 5cb37f5

Browse files
committed
python: Document MaD format
- add a few tests reflecting the documentation - make the mentioned sink-kinds have an effect on relevant queries
1 parent 6dbdc9e commit 5cb37f5

File tree

9 files changed

+502
-1
lines changed

9 files changed

+502
-1
lines changed

docs/codeql/codeql-language-guides/customizing-library-models-for-python.rst

Lines changed: 449 additions & 0 deletions
Large diffs are not rendered by default.

python/ql/lib/semmle/python/security/dataflow/CodeInjectionCustomizations.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ private import semmle.python.dataflow.new.DataFlow
99
private import semmle.python.Concepts
1010
private import semmle.python.dataflow.new.RemoteFlowSources
1111
private import semmle.python.dataflow.new.BarrierGuards
12+
private import semmle.python.frameworks.data.ModelsAsData
1213

1314
/**
1415
* Provides default sources, sinks and sanitizers for detecting
@@ -43,6 +44,10 @@ module CodeInjection {
4344
CodeExecutionAsSink() { this = any(CodeExecution e).getCode() }
4445
}
4546

47+
private class SinkFromModel extends Sink {
48+
SinkFromModel() { this = ModelOutput::getASinkNode("code-injection").asSink() }
49+
}
50+
4651
/**
4752
* A comparison with a constant string, considered as a sanitizer-guard.
4853
*/

python/ql/lib/semmle/python/security/dataflow/CommandInjectionCustomizations.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ private import semmle.python.dataflow.new.DataFlow
99
private import semmle.python.Concepts
1010
private import semmle.python.dataflow.new.RemoteFlowSources
1111
private import semmle.python.dataflow.new.BarrierGuards
12+
private import semmle.python.frameworks.data.ModelsAsData
1213

1314
/**
1415
* Provides default sources, sinks and sanitizers for detecting
@@ -78,6 +79,10 @@ module CommandInjection {
7879
}
7980
}
8081

82+
private class SinkFromModel extends Sink {
83+
SinkFromModel() { this = ModelOutput::getASinkNode("command-injection").asSink() }
84+
}
85+
8186
/**
8287
* A comparison with a constant string, considered as a sanitizer-guard.
8388
*/

python/ql/lib/semmle/python/security/dataflow/LogInjectionCustomizations.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ private import semmle.python.dataflow.new.DataFlow
99
private import semmle.python.Concepts
1010
private import semmle.python.dataflow.new.RemoteFlowSources
1111
private import semmle.python.dataflow.new.BarrierGuards
12+
private import semmle.python.frameworks.data.ModelsAsData
1213

1314
/**
1415
* Provides default sources, sinks and sanitizers for detecting
@@ -71,6 +72,10 @@ module LogInjection {
7172
}
7273
}
7374

75+
private class SinkFromModel extends Sink {
76+
SinkFromModel() { this = ModelOutput::getASinkNode("log-injection").asSink() }
77+
}
78+
7479
/**
7580
* A comparison with a constant string, considered as a sanitizer-guard.
7681
*/

python/ql/lib/semmle/python/security/dataflow/UnsafeDeserializationCustomizations.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ private import semmle.python.dataflow.new.DataFlow
99
private import semmle.python.Concepts
1010
private import semmle.python.dataflow.new.RemoteFlowSources
1111
private import semmle.python.dataflow.new.BarrierGuards
12+
private import semmle.python.frameworks.data.ModelsAsData
1213

1314
/**
1415
* Provides default sources, sinks and sanitizers for detecting
@@ -48,6 +49,10 @@ module UnsafeDeserialization {
4849
}
4950
}
5051

52+
private class SinkFromModel extends Sink {
53+
SinkFromModel() { this = ModelOutput::getASinkNode("unsafe-deserialization").asSink() }
54+
}
55+
5156
/**
5257
* A comparison with a constant string, considered as a sanitizer-guard.
5358
*/

python/ql/lib/semmle/python/security/dataflow/UrlRedirectCustomizations.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ private import semmle.python.dataflow.new.DataFlow
99
private import semmle.python.Concepts
1010
private import semmle.python.dataflow.new.RemoteFlowSources
1111
private import semmle.python.dataflow.new.BarrierGuards
12+
private import semmle.python.frameworks.data.ModelsAsData
1213

1314
/**
1415
* Provides default sources, sinks and sanitizers for detecting
@@ -89,6 +90,9 @@ module UrlRedirect {
8990
}
9091
}
9192

93+
private class SinkFromModel extends Sink {
94+
SinkFromModel() { this = ModelOutput::getASinkNode("url-redirection").asSink() }
95+
}
9296
/**
9397
* The right side of a string-concat, considered as a sanitizer.
9498
*/

python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ext.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,12 @@ extensions:
2525
- ["foo.MS_Class", "Member[instance_method]", "Argument[0]", "ReturnValue.TupleElement[1]", "value"]
2626
- ["foo.MS_Class", "Member[explicit_self]", "Argument[self:]", "ReturnValue", "value"]
2727
- ["json", "Member[MS_loads]", "Argument[0]", "ReturnValue", "taint"]
28+
29+
- addsTo:
30+
pack: codeql/python-all
31+
extensible: typeModel
32+
data:
33+
- ["foo.MS_Class", "foo", "Member[get_instance].ReturnValue"]
34+
- ["foo.MS_Class!", "foo", "Member[get_class].ReturnValue"]
35+
# Ideally this would be a consequence of the above line
36+
- ["foo.MS_Class", "foo", "Member[get_class].ReturnValue.Instance"]

python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ext.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,12 @@ extensions:
2525
- ["foo.MS_Class", "Member[instance_method]", "Argument[0]", "ReturnValue.TupleElement[1]", "value"]
2626
- ["foo.MS_Class", "Member[explicit_self]", "Argument[self:]", "ReturnValue", "value"]
2727
- ["json", "Member[MS_loads]", "Argument[0]", "ReturnValue", "taint"]
28+
29+
- addsTo:
30+
pack: codeql/python-all
31+
extensible: typeModel
32+
data:
33+
- ["foo.MS_Class", "foo", "Member[get_instance].ReturnValue"]
34+
- ["foo.MS_Class!", "foo", "Member[get_class].ReturnValue"]
35+
# Ideally this would be a consequence of the above line
36+
- ["foo.MS_Class", "foo", "Member[get_class].ReturnValue.Instance"]

python/ql/test/library-tests/dataflow/model-summaries/model_summaries.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ def explicit_identity(x):
122122
SINK(a) # $ flow="SOURCE, l:-1 -> a"
123123
SINK(b) # $ flow="SOURCE, l:-2 -> b"
124124

125-
from foo import MS_Class, MS_Class_transitive
125+
from foo import MS_Class, MS_Class_transitive, get_instance, get_class
126126

127127
# Class summaries
128128
class_via_positional = MS_Class(SOURCE)
@@ -175,6 +175,16 @@ def __init__(y, x):
175175
# Instead, `Argument[self:]` refers to a keyword argument named `self` (which you are allowed to do in Python)
176176
SINK(c.explicit_self(self = SOURCE)) # $ flow="SOURCE -> c.explicit_self(..)"
177177

178+
179+
instance = get_instance()
180+
SINK(instance.instance_method(SOURCE)[1]) # $ flow="SOURCE -> instance.instance_method(..)[1]"
181+
182+
returned_class = get_class()
183+
SINK(returned_class(SOURCE).config) # $ flow="SOURCE -> returned_class(..).config"
184+
185+
SINK(returned_class().instance_method(SOURCE)[1]) # $flow="SOURCE -> returned_class().instance_method(..)[1]"
186+
187+
178188
# Modeled flow-summary is not value preserving
179189
from json import MS_loads as json_loads
180190

0 commit comments

Comments
 (0)