mirror of
https://github.com/github/codeql.git
synced 2026-04-29 02:35:15 +02:00
Python: Improve API and representation of taint tracking nodes. Update queries and tests accordingly.
This commit is contained in:
@@ -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"
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user