Skip to content

Commit 61bd868

Browse files
committed
Python: Improve API and representation of taint tracking nodes. Update queries and tests accordingly.
1 parent c01db23 commit 61bd868

File tree

20 files changed

+190
-152
lines changed

20 files changed

+190
-152
lines changed

python/ql/src/Security/CWE-022/PathInjection.ql

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ import semmle.python.web.HttpRequest
2626
import semmle.python.security.injection.Path
2727

2828

29-
30-
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
31-
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
32-
33-
select sink, srcnode, sinknode, "This path depends on $@.", src, "a user-provided value"
29+
from TaintedPathSource src, TaintedPathSink sink
30+
where src.flowsTo(sink)
31+
select sink.getSink(), src, sink, "This path depends on $@.", src.getSource(), "a user-provided value"

python/ql/src/Security/CWE-078/CommandInjection.ql

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import semmle.python.web.HttpRequest
2323
/* Sinks */
2424
import semmle.python.security.injection.Command
2525

26-
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
27-
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
28-
29-
select sink, srcnode, sinknode, "This command depends on $@.", src, "a user-provided value"
26+
from TaintedPathSource src, TaintedPathSink sink
27+
where src.flowsTo(sink)
28+
select sink.getSink(), src, sink, "This command depends on $@.", src.getSource(), "a user-provided value"

python/ql/src/Security/CWE-079/ReflectedXss.ql

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ import semmle.python.web.HttpResponse
2525
/* Flow */
2626
import semmle.python.security.strings.Untrusted
2727

28-
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
29-
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
30-
31-
select sink, srcnode, sinknode, "Cross-site scripting vulnerability due to $@.",
32-
src, "user-provided value"
33-
28+
from TaintedPathSource src, TaintedPathSink sink
29+
where src.flowsTo(sink)
30+
select sink.getSink(), src, sink, "Cross-site scripting vulnerability due to $@.", src.getSource(), "user-provided value"

python/ql/src/Security/CWE-089/SqlInjection.ql

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import semmle.python.web.django.Db
2323
import semmle.python.web.django.Model
2424

2525

26-
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
27-
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
28-
29-
select sink, srcnode, sinknode, "This SQL query depends on $@.", src, "a user-provided value"
26+
from TaintedPathSource src, TaintedPathSink sink
27+
where src.flowsTo(sink)
28+
select sink.getSink(), src, sink, "This SQL query depends on $@.", src.getSource(), "a user-provided value"

python/ql/src/Security/CWE-094/CodeInjection.ql

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import semmle.python.web.HttpRequest
2424
import semmle.python.security.injection.Exec
2525

2626

27-
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
28-
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
29-
30-
select sink, srcnode, sinknode, "$@ flows to here and is interpreted as code.", src, "User-provided value"
27+
from TaintedPathSource src, TaintedPathSink sink
28+
where src.flowsTo(sink)
29+
select sink.getSink(), src, sink, "$@ flows to here and is interpreted as code.", src.getSource(), "User-provided value"

python/ql/src/Security/CWE-209/StackTraceExposure.ql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ import semmle.python.security.Paths
1818
import semmle.python.security.Exceptions
1919
import semmle.python.web.HttpResponse
2020

21-
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
22-
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
23-
select sink, srcnode, sinknode, "$@ may be exposed to an external user", src, "Error information"
21+
from TaintedPathSource src, TaintedPathSink sink
22+
where src.flowsTo(sink)
23+
select sink.getSink(), src, sink, "$@ may be exposed to an external user", src.getSource(), "Error information"

python/ql/src/Security/CWE-502/UnsafeDeserialization.ql

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import semmle.python.security.injection.Marshal
2525
import semmle.python.security.injection.Yaml
2626

2727

28-
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
29-
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
30-
31-
select sink, srcnode, sinknode, "Deserializing of $@.", src, "untrusted input"
28+
from TaintedPathSource src, TaintedPathSink sink
29+
where src.flowsTo(sink)
30+
select sink.getSink(), src, sink, "Deserializing of $@.", src.getSource(), "untrusted input"

python/ql/src/Security/CWE-601/UrlRedirect.ql

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ class UntrustedPrefixStringKind extends UntrustedStringKind {
2828

2929
}
3030

31-
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
32-
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
33-
34-
select sink, srcnode, sinknode, "Untrusted URL redirection due to $@.", src, "a user-provided value"
31+
from TaintedPathSource src, TaintedPathSink sink
32+
where src.flowsTo(sink)
33+
select sink.getSink(), src, sink, "Untrusted URL redirection due to $@.", src.getSource(), "a user-provided value"
3534

python/ql/src/semmle/python/security/Exceptions.qll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ class ExceptionInfo extends StringKind {
2424
ExceptionInfo() {
2525
this = "exception.info"
2626
}
27+
28+
override string repr() {
29+
result = "exception info"
30+
}
31+
2732
}
2833

2934

@@ -36,6 +41,10 @@ class ExceptionKind extends TaintKind {
3641
this = "exception.kind"
3742
}
3843

44+
override string repr() {
45+
result = "exception"
46+
}
47+
3948
override TaintKind getTaintOfAttribute(string name) {
4049
name = "args" and result instanceof ExceptionInfoSequence
4150
or

python/ql/src/semmle/python/security/TaintTracking.qll

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ abstract class TaintKind extends string {
148148
none()
149149
}
150150

151+
string repr() { result = this }
152+
151153
}
152154

153155
/** Taint kinds representing collections of other taint kind.
@@ -208,6 +210,10 @@ class SequenceKind extends CollectionKind {
208210
name = "pop" and result = this.getItem()
209211
}
210212

213+
override string repr() {
214+
result = "sequence of " + itemKind
215+
}
216+
211217
}
212218

213219
/* Helper for getTaintForStep() */
@@ -281,6 +287,10 @@ class DictKind extends CollectionKind {
281287
name = "itervalues" and result.(SequenceKind).getItem() = valueKind
282288
}
283289

290+
override string repr() {
291+
result = "dict of " + valueKind
292+
}
293+
284294
}
285295

286296

@@ -603,7 +613,9 @@ private predicate user_tainted_def(TaintedDefinition def, TaintFlowImplementatio
603613
*/
604614
class TaintedNode extends TTaintedNode {
605615

606-
string toString() { result = this.getTrackedValue().toString() + " at " + this.getLocation() }
616+
string toString() { result = this.getTrackedValue().repr() }
617+
618+
string debug() { result = this.getTrackedValue().toString() + " at " + this.getNode().getLocation() }
607619

608620
TaintedNode getASuccessor() {
609621
exists(TaintFlowImplementation::TrackedValue tokind, CallContext tocontext, ControlFlowNode tonode |
@@ -675,25 +687,33 @@ class TaintedNode extends TTaintedNode {
675687

676688
}
677689

678-
class TaintedNodeSource extends TaintedNode {
690+
class TaintedPathSource extends TaintedNode {
679691

680-
TaintedNodeSource() {
692+
TaintedPathSource() {
681693
this.getNode().(TaintSource).isSourceOf(this.getTaintKind(), this.getContext())
682694
}
683695

684696
/** Holds if taint can flow from this source to sink `sink` */
685-
final predicate flowsTo(TaintedNodeSink sink) {
697+
final predicate flowsTo(TaintedPathSink sink) {
686698
this.getASuccessor*() = sink
687699
}
688700

701+
TaintSource getSource() {
702+
result = this.getNode()
703+
}
704+
689705
}
690706

691-
class TaintedNodeSink extends TaintedNode {
707+
class TaintedPathSink extends TaintedNode {
692708

693-
TaintedNodeSink() {
709+
TaintedPathSink() {
694710
this.getNode().(TaintSink).sinks(this.getTaintKind())
695711
}
696712

713+
TaintSink getSink() {
714+
result = this.getNode()
715+
}
716+
697717
}
698718

699719
/** This module contains the implementation of taint-flow.
@@ -739,12 +759,18 @@ library module TaintFlowImplementation {
739759

740760
abstract string toString();
741761

762+
abstract string repr();
763+
742764
abstract TrackedValue toKind(TaintKind kind);
743765

744766
}
745767

746768
class TrackedTaint extends TrackedValue, TTrackedTaint {
747769

770+
override string repr() {
771+
result = this.getKind().repr()
772+
}
773+
748774
override string toString() {
749775
result = "Taint " + this.getKind()
750776
}
@@ -761,6 +787,13 @@ library module TaintFlowImplementation {
761787

762788
class TrackedAttribute extends TrackedValue, TTrackedAttribute {
763789

790+
override string repr() {
791+
exists(string name, TaintKind kind |
792+
this = TTrackedAttribute(name, kind) and
793+
result = "." + name + "=" + kind.repr()
794+
)
795+
}
796+
764797
override string toString() {
765798
exists(string name, TaintKind kind |
766799
this = TTrackedAttribute(name, kind) and

0 commit comments

Comments
 (0)