Skip to content

Commit ca43d0a

Browse files
committed
feat(python): add new sinks and utils for enhanced data flow analysis
1 parent 09ad708 commit ca43d0a

File tree

4 files changed

+131
-50
lines changed

4 files changed

+131
-50
lines changed

python/lib/ghsl.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Utils
2+
import ghsl.Utils
3+
import ghsl.Sinks

python/lib/ghsl/Helpers.qll

Lines changed: 0 additions & 45 deletions
This file was deleted.

python/lib/ghsl/Sinks.qll

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
private import python
2+
private import semmle.python.ApiGraphs
3+
private import semmle.python.Concepts
4+
private import semmle.python.dataflow.new.DataFlow
5+
6+
private import semmle.python.security.dataflow.SqlInjectionCustomizations
7+
private import semmle.python.security.dataflow.CodeInjectionCustomizations
8+
private import semmle.python.security.dataflow.CommandInjectionCustomizations
9+
private import semmle.python.security.dataflow.LdapInjectionCustomizations
10+
private import semmle.python.security.dataflow.NoSqlInjectionCustomizations
11+
private import semmle.python.security.dataflow.ReflectedXSSCustomizations
12+
private import semmle.python.security.dataflow.UnsafeDeserializationCustomizations
13+
private import semmle.python.security.dataflow.XpathInjectionCustomizations
14+
private import semmle.python.security.dataflow.XxeCustomizations
15+
// Fields Sinks
16+
private import ghsl.HardcodedSecretSinks
17+
private import ghsl.MassAssignment
18+
19+
20+
/**
21+
* List of all the sinks that we want to check.
22+
*/
23+
class AllSinks extends DataFlow::Node {
24+
private string sink;
25+
26+
AllSinks() {
27+
this instanceof MassAssignment::Sinks and
28+
sink = "mass-assignment"
29+
or
30+
this instanceof CredentialSink and
31+
sink = "credential"
32+
or
33+
this instanceof SqlInjection::Sink and
34+
sink = "sql-injection"
35+
or
36+
this instanceof CodeInjection::Sink and
37+
sink = "code-injection"
38+
or
39+
this instanceof CommandInjection::Sink and
40+
sink = "command-injection"
41+
or
42+
(
43+
this instanceof LdapInjection::DnSink
44+
or
45+
this instanceof LdapInjection::FilterSink
46+
) and
47+
sink = "ldap-injection"
48+
or
49+
(
50+
this instanceof NoSqlInjection::NoSqlExecutionAsDictSink and
51+
this instanceof NoSqlInjection::NoSqlExecutionAsStringSink
52+
) and
53+
sink = "nosql-injection"
54+
or
55+
this instanceof ReflectedXss::Sink and
56+
sink = "reflected-xss"
57+
or
58+
this instanceof UnsafeDeserialization::Sink and
59+
sink = "unsafe-deserialization"
60+
or
61+
this instanceof XpathInjection::Sink and
62+
sink = "xpath-injection"
63+
or
64+
this instanceof Xxe::Sink and
65+
sink = "xxe"
66+
}
67+
68+
/**
69+
* Gets the sink sink type.
70+
*/
71+
string sinkType() { result = sink }
72+
}

python/lib/ghsl/Utils.qll

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,59 @@
1-
import python
1+
private import python
22
private import semmle.python.ApiGraphs
33
private import semmle.python.Concepts
44
private import semmle.python.dataflow.new.DataFlow
5-
private import semmle.python.dataflow.new.internal.TaintTrackingPrivate
5+
private import ghsl.LocalSources
6+
/**
7+
* Find Node at Location
8+
*/
9+
predicate filterByLocation(DataFlow::Node node, string relative_path, int linenumber) {
10+
node.getLocation().getFile().getRelativePath() = relative_path and
11+
node.getLocation().getStartLine() = linenumber
12+
}
13+
14+
/**
15+
* Check if the source node is a method parameter
16+
*/
17+
predicate functionParameters(DataFlow::Node node) {
18+
(
19+
// // Function Call Parameters
20+
node instanceof DataFlow::ParameterNode
21+
or
22+
// Function Call Arguments
23+
node instanceof DataFlow::ArgumentNode
24+
) and
25+
not dangerousSinks(node) and
26+
node.getScope().inSource()
27+
}
28+
29+
30+
/**
31+
* List of all the souces
32+
*/
33+
class AllSources extends DataFlow::Node {
34+
private string threatmodel;
35+
36+
AllSources() {
37+
exists(ThreatModelSource tms |
38+
threatmodel = tms.getThreatModel() and
39+
this = tms
40+
)
41+
or
42+
this instanceof LocalSources::Range and
43+
threatmodel = "local"
44+
}
45+
46+
/**
47+
* Gets the source threat model.
48+
*/
49+
string getThreatModel() { result = threatmodel }
50+
}
51+
52+
/**
53+
* Local sources
54+
*/
55+
class LocalSources = LocalSources::Range;
56+
657

758
// List of all the format strings
859
// - python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll
@@ -23,11 +74,11 @@ class DynamicStrings extends DataFlow::Node {
2374
exists(BinaryExpr expr |
2475
(
2576
// q = "WHERE name = %s" % username
26-
expr.getOp() instanceof Mod or
77+
expr.getOp() instanceof Mod
78+
or
2779
// q = "WHERE name = " + username
2880
expr.getOp() instanceof Add
29-
)
30-
and
81+
) and
3182
expr.getLeft().getParent() = this.asExpr()
3283
)
3384
) and

0 commit comments

Comments
 (0)