Python: Improve API and representation of taint tracking nodes. Update queries and tests accordingly.

This commit is contained in:
Mark Shannon
2018-11-23 12:18:56 +00:00
parent c01db23f58
commit 61bd8682df
20 changed files with 190 additions and 152 deletions

View File

@@ -26,8 +26,6 @@ import semmle.python.web.HttpRequest
import semmle.python.security.injection.Path
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
select sink, srcnode, sinknode, "This path depends on $@.", src, "a user-provided value"
from TaintedPathSource src, TaintedPathSink sink
where src.flowsTo(sink)
select sink.getSink(), src, sink, "This path depends on $@.", src.getSource(), "a user-provided value"

View File

@@ -23,7 +23,6 @@ import semmle.python.web.HttpRequest
/* Sinks */
import semmle.python.security.injection.Command
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
select sink, srcnode, sinknode, "This command depends on $@.", src, "a user-provided value"
from TaintedPathSource src, TaintedPathSink sink
where src.flowsTo(sink)
select sink.getSink(), src, sink, "This command depends on $@.", src.getSource(), "a user-provided value"

View File

@@ -25,9 +25,6 @@ import semmle.python.web.HttpResponse
/* Flow */
import semmle.python.security.strings.Untrusted
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
select sink, srcnode, sinknode, "Cross-site scripting vulnerability due to $@.",
src, "user-provided value"
from TaintedPathSource src, TaintedPathSink sink
where src.flowsTo(sink)
select sink.getSink(), src, sink, "Cross-site scripting vulnerability due to $@.", src.getSource(), "user-provided value"

View File

@@ -23,7 +23,6 @@ import semmle.python.web.django.Db
import semmle.python.web.django.Model
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
select sink, srcnode, sinknode, "This SQL query depends on $@.", src, "a user-provided value"
from TaintedPathSource src, TaintedPathSink sink
where src.flowsTo(sink)
select sink.getSink(), src, sink, "This SQL query depends on $@.", src.getSource(), "a user-provided value"

View File

@@ -24,7 +24,6 @@ import semmle.python.web.HttpRequest
import semmle.python.security.injection.Exec
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
select sink, srcnode, sinknode, "$@ flows to here and is interpreted as code.", src, "User-provided value"
from TaintedPathSource src, TaintedPathSink sink
where src.flowsTo(sink)
select sink.getSink(), src, sink, "$@ flows to here and is interpreted as code.", src.getSource(), "User-provided value"

View File

@@ -18,6 +18,6 @@ import semmle.python.security.Paths
import semmle.python.security.Exceptions
import semmle.python.web.HttpResponse
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
select sink, srcnode, sinknode, "$@ may be exposed to an external user", src, "Error information"
from TaintedPathSource src, TaintedPathSink sink
where src.flowsTo(sink)
select sink.getSink(), src, sink, "$@ may be exposed to an external user", src.getSource(), "Error information"

View File

@@ -25,7 +25,6 @@ import semmle.python.security.injection.Marshal
import semmle.python.security.injection.Yaml
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
select sink, srcnode, sinknode, "Deserializing of $@.", src, "untrusted input"
from TaintedPathSource src, TaintedPathSink sink
where src.flowsTo(sink)
select sink.getSink(), src, sink, "Deserializing of $@.", src.getSource(), "untrusted input"

View File

@@ -28,8 +28,7 @@ class UntrustedPrefixStringKind extends UntrustedStringKind {
}
from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink
where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink
select sink, srcnode, sinknode, "Untrusted URL redirection due to $@.", src, "a user-provided value"
from TaintedPathSource src, TaintedPathSink sink
where src.flowsTo(sink)
select sink.getSink(), src, sink, "Untrusted URL redirection due to $@.", src.getSource(), "a user-provided value"

View File

@@ -24,6 +24,11 @@ class ExceptionInfo extends StringKind {
ExceptionInfo() {
this = "exception.info"
}
override string repr() {
result = "exception info"
}
}
@@ -36,6 +41,10 @@ class ExceptionKind extends TaintKind {
this = "exception.kind"
}
override string repr() {
result = "exception"
}
override TaintKind getTaintOfAttribute(string name) {
name = "args" and result instanceof ExceptionInfoSequence
or

View File

@@ -148,6 +148,8 @@ abstract class TaintKind extends string {
none()
}
string repr() { result = this }
}
/** Taint kinds representing collections of other taint kind.
@@ -208,6 +210,10 @@ class SequenceKind extends CollectionKind {
name = "pop" and result = this.getItem()
}
override string repr() {
result = "sequence of " + itemKind
}
}
/* Helper for getTaintForStep() */
@@ -281,6 +287,10 @@ class DictKind extends CollectionKind {
name = "itervalues" and result.(SequenceKind).getItem() = valueKind
}
override string repr() {
result = "dict of " + valueKind
}
}
@@ -603,7 +613,9 @@ private predicate user_tainted_def(TaintedDefinition def, TaintFlowImplementatio
*/
class TaintedNode extends TTaintedNode {
string toString() { result = this.getTrackedValue().toString() + " at " + this.getLocation() }
string toString() { result = this.getTrackedValue().repr() }
string debug() { result = this.getTrackedValue().toString() + " at " + this.getNode().getLocation() }
TaintedNode getASuccessor() {
exists(TaintFlowImplementation::TrackedValue tokind, CallContext tocontext, ControlFlowNode tonode |
@@ -675,25 +687,33 @@ class TaintedNode extends TTaintedNode {
}
class TaintedNodeSource extends TaintedNode {
class TaintedPathSource extends TaintedNode {
TaintedNodeSource() {
TaintedPathSource() {
this.getNode().(TaintSource).isSourceOf(this.getTaintKind(), this.getContext())
}
/** Holds if taint can flow from this source to sink `sink` */
final predicate flowsTo(TaintedNodeSink sink) {
final predicate flowsTo(TaintedPathSink sink) {
this.getASuccessor*() = sink
}
TaintSource getSource() {
result = this.getNode()
}
}
class TaintedNodeSink extends TaintedNode {
class TaintedPathSink extends TaintedNode {
TaintedNodeSink() {
TaintedPathSink() {
this.getNode().(TaintSink).sinks(this.getTaintKind())
}
TaintSink getSink() {
result = this.getNode()
}
}
/** This module contains the implementation of taint-flow.
@@ -739,12 +759,18 @@ library module TaintFlowImplementation {
abstract string toString();
abstract string repr();
abstract TrackedValue toKind(TaintKind kind);
}
class TrackedTaint extends TrackedValue, TTrackedTaint {
override string repr() {
result = this.getKind().repr()
}
override string toString() {
result = "Taint " + this.getKind()
}
@@ -761,6 +787,13 @@ library module TaintFlowImplementation {
class TrackedAttribute extends TrackedValue, TTrackedAttribute {
override string repr() {
exists(string name, TaintKind kind |
this = TTrackedAttribute(name, kind) and
result = "." + name + "=" + kind.repr()
)
}
override string toString() {
exists(string name, TaintKind kind |
this = TTrackedAttribute(name, kind) and

View File

@@ -36,6 +36,9 @@ class FirstElementKind extends TaintKind {
this = "sequence[" + any(ExternalStringKind key) + "][0]"
}
override string repr() {
result = "first item in sequence of " + this.getItem().repr()
}
/** Gets the taint kind for item in this sequence. */
ExternalStringKind getItem() {

View File

@@ -36,6 +36,10 @@ class NormalizedPath extends TaintKind {
this = "normalized.path.injection"
}
override string repr() {
result = "normalized path"
}
}
private predicate abspath_call(CallNode call, ControlFlowNode arg) {