Python: Add new API for taint-tracking configuration. As yet, unsupported.

This commit is contained in:
Mark Shannon
2019-07-29 11:34:39 +01:00
parent d2bee79370
commit e8bd9e7341
2 changed files with 117 additions and 41 deletions

View File

@@ -0,0 +1,106 @@
import python
import semmle.python.security.TaintTracking
module TaintTracking {
class Source = TaintSource;
class Sink = TaintSink;
class PathSource = TaintedPathSource;
class PathSink = TaintedPathSink;
class Extension = DataFlowExtension::DataFlowNode;
abstract class Configuration extends string {
/* Required to prevent compiler warning */
bindingset[this]
Configuration() { this = this }
/* Old implementation API */
predicate isSource(Source source) { none() }
predicate isSink(Sink sink) { none() }
predicate isSanitizer(Sanitizer sanitizer) { none() }
predicate isExtension(Extension extension) { none() }
/* New implementation API */
/**
* Holds if `source` is a source of taint of `kind` that is relevant
* for this configuration.
*/
predicate isSource(DataFlow::Node source, TaintKind kind) { none() }
/**
* Holds if `sink` is a sink of taint of `kind` that is relevant
* for this configuration.
*/
predicate isSink(DataFlow::Node sink, TaintKind kind) { none() }
/**
* Holds if `src -> dest` should be considered as a flow edge
* in addition to standard data flow edges.
*/
predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node dest) { none() }
/**
* Holds if `src -> dest` is a flow edge converting taint from `srckind` to `destkind`.
*/
predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node trg, TaintKind srckind, TaintKind destkind) {
none()
}
predicate isBarrier(DataFlow::Node node) { none() }
predicate isBarrier(DataFlow::Node node, TaintKind kind) { none() }
/**
* Holds if flow from `src` to `dest` is prohibited.
*/
predicate isBarrierEdge(DataFlow::Node src, DataFlow::Node trg) { none() }
/**
* Holds if flow from `src` to `dest` is prohibited when the incoming taint is `srckind` and the outgoing taint is `destkind`.
* Note that `srckind` and `destkind` can be the same.
*/
predicate isBarrierEdge(DataFlow::Node src, DataFlow::Node dest, TaintKind srckind, TaintKind destkind) { none() }
/* Common query API */
predicate hasFlowPath(PathSource source, PathSink sink) {
this.isSource(source.getNode()) and
this.isSink(sink.getNode()) and
source.flowsTo(sink)
}
/* Old query API */
deprecated predicate hasFlow(Source source, Sink sink) {
exists(PathSource psource, PathSink psink |
this.hasFlowPath(psource, psink) and
source = psource.getCfgNode() and
sink = psink.getCfgNode()
)
}
/* New query API */
predicate hasSimpleFlow(DataFlow::Node source, DataFlow::Node sink) {
/* TO DO */
exists(PathSource psource, PathSink psink |
this.hasFlowPath(psource, psink) and
source = psource.getNode() and
sink = psink.getNode()
)
}
}
}

View File

@@ -89,6 +89,7 @@
import python
private import semmle.python.pointsto.Filters as Filters
private import semmle.python.objects.ObjectInternal
import semmle.python.dataflow.Configuration
/** A 'kind' of taint. This may be almost anything,
* but it is typically something like a "user-defined string".
@@ -167,6 +168,11 @@ abstract class TaintKind extends string {
}
/**
* Alias of `TaintKind`, so the two types can be used interchangeably.
*/
class FlowLabel = TaintKind;
/** Taint kinds representing collections of other taint kind.
* We use `{kind}` to represent a mapping of string to `kind` and
* `[kind]` to represent a flat collection of `kind`.
@@ -670,6 +676,11 @@ class TaintedNode extends TTaintedNode {
result = this.getNode().getNode()
}
/** Gets the CFG node for this node. */
ControlFlowNode getCfgNode() {
this = TTaintedNode_(_, _, result)
}
/** Gets the data-flow context for this node. */
CallContext getContext() {
this = TTaintedNode_(_, result, _)
@@ -1644,47 +1655,6 @@ private class DataFlowType extends TaintKind {
}
module TaintTracking {
class Source = TaintSource;
class Sink = TaintSink;
class PathSource = TaintedPathSource;
class PathSink = TaintedPathSink;
class Extension = DataFlowExtension::DataFlowNode;
abstract class Configuration extends string {
bindingset[this]
Configuration() { this = this }
abstract predicate isSource(Source source);
abstract predicate isSink(Sink sink);
predicate isSanitizer(Sanitizer sanitizer) { none() }
predicate isExtension(Extension extension) { none() }
predicate hasFlowPath(PathSource source, PathSink sink) {
this.isSource(source.getNode()) and
this.isSink(sink.getNode()) and
source.flowsTo(sink)
}
predicate hasFlow(Source source, Sink sink) {
this.isSource(source) and
this.isSink(sink) and
source.flowsToSink(sink)
}
}
}
pragma [noinline]
private predicate dict_construct(ControlFlowNode itemnode, ControlFlowNode dictnode) {