initial MaD implementation for Python

This commit is contained in:
Erik Krogh Kristensen
2022-04-26 12:43:34 +02:00
parent 1d44694280
commit 1c2c9159a9
12 changed files with 1068 additions and 2 deletions

View File

@@ -0,0 +1,18 @@
taintFlow
| test.py:3:5:3:15 | ControlFlowNode for getSource() | test.py:4:8:4:8 | ControlFlowNode for x |
isSink
| test.py:4:8:4:8 | ControlFlowNode for x | test-sink |
isSource
| test.py:3:5:3:15 | ControlFlowNode for getSource() | test-source |
syntaxErrors
| Member[foo |
| Member[foo] .Member[bar] |
| Member[foo] Member[bar] |
| Member[foo], Member[bar] |
| Member[foo],Member[bar] |
| Member[foo]. Member[bar] |
| Member[foo]..Member[bar] |
| Member[foo]Member[bar] |
| Member[foo]] |
| Member[foo]].Member[bar] |
warning

View File

@@ -0,0 +1,4 @@
from testlib import getSource, mySink
x = getSource()
mySink(x)

View File

@@ -0,0 +1,85 @@
import python
import semmle.python.frameworks.data.internal.AccessPathSyntax as AccessPathSyntax
import semmle.python.frameworks.data.ModelsAsData
import semmle.python.dataflow.new.TaintTracking
import semmle.python.dataflow.new.DataFlow
// TODO:
/*
* class Steps extends ModelInput::SummaryModelCsv {
* override predicate row(string row) {
* // package;type;path;input;output;kind
* row =
* [
* "testlib;;Member[preserveTaint];Argument[0];ReturnValue;taint",
* "testlib;;Member[taintIntoCallback];Argument[0];Argument[1..2].Parameter[0];taint",
* "testlib;;Member[taintIntoCallbackThis];Argument[0];Argument[1..2].Parameter[this];taint",
* "testlib;;Member[preserveArgZeroAndTwo];Argument[0,2];ReturnValue;taint",
* "testlib;;Member[preserveAllButFirstArgument];Argument[1..];ReturnValue;taint",
* "testlib;;Member[preserveAllIfCall].Call;Argument[0..];ReturnValue;taint",
* "testlib;;Member[getSource].ReturnValue.Member[continue];Argument[this];ReturnValue;taint",
* ]
* }
* }
*/
class Sinks extends ModelInput::SinkModelCsv {
override predicate row(string row) {
// package;type;path;kind
row = ["testlib;;Member[mySink].Argument[0];test-sink"]
}
}
// TODO: Test taint steps (include that the base path may end with ".Call")
// TODO: Ctrl + f: TODO
// TODO: // There are no API-graph edges for: ArrayElement, Element, MapKey, MapValue (remove from valid tokens list)
// TODO: Verify that the list of valid tokens matches the implementation.
class Sources extends ModelInput::SourceModelCsv {
// package;type;path;kind
override predicate row(string row) {
row = ["testlib;;Member[getSource].ReturnValue;test-source"]
}
}
class BasicTaintTracking extends TaintTracking::Configuration {
BasicTaintTracking() { this = "BasicTaintTracking" }
override predicate isSource(DataFlow::Node source) {
source = ModelOutput::getASourceNode("test-source").getAnImmediateUse()
}
override predicate isSink(DataFlow::Node sink) {
sink = ModelOutput::getASinkNode("test-sink").getARhs()
}
}
query predicate taintFlow(DataFlow::Node source, DataFlow::Node sink) {
any(BasicTaintTracking tr).hasFlow(source, sink)
}
query predicate isSink(DataFlow::Node node, string kind) {
node = ModelOutput::getASinkNode(kind).getARhs()
}
query predicate isSource(DataFlow::Node node, string kind) {
node = ModelOutput::getASourceNode(kind).getAnImmediateUse()
}
class SyntaxErrorTest extends ModelInput::SinkModelCsv {
override predicate row(string row) {
row =
[
"testlib;;Member[foo],Member[bar];test-sink", "testlib;;Member[foo] Member[bar];test-sink",
"testlib;;Member[foo]. Member[bar];test-sink",
"testlib;;Member[foo], Member[bar];test-sink",
"testlib;;Member[foo]..Member[bar];test-sink",
"testlib;;Member[foo] .Member[bar];test-sink", "testlib;;Member[foo]Member[bar];test-sink",
"testlib;;Member[foo;test-sink", "testlib;;Member[foo]];test-sink",
"testlib;;Member[foo]].Member[bar];test-sink"
]
}
}
query predicate syntaxErrors(AccessPathSyntax::AccessPath path) { path.hasSyntaxError() }
query predicate warning = ModelOutput::getAWarning/0;

View File

@@ -0,0 +1,12 @@
| CSV type row should have 5 columns but has 2: test;TooFewColumns |
| CSV type row should have 5 columns but has 8: test;TooManyColumns;;;Member[Foo].Instance;too;many;columns |
| Invalid argument '0-1' in token 'Argument[0-1]' in access path: Method[foo].Argument[0-1] |
| Invalid argument '*' in token 'Argument[*]' in access path: Method[foo].Argument[*] |
| Invalid argument 'foo' in token 'Method[foo]' in access path: Method[foo].Arg[0] |
| Invalid argument 'foo' in token 'Method[foo]' in access path: Method[foo].Argument |
| Invalid argument 'foo' in token 'Method[foo]' in access path: Method[foo].Argument[0-1] |
| Invalid argument 'foo' in token 'Method[foo]' in access path: Method[foo].Argument[*] |
| Invalid argument 'foo' in token 'Method[foo]' in access path: Method[foo].Member |
| Invalid token 'Argument' is missing its arguments, in access path: Method[foo].Argument |
| Invalid token 'Member' is missing its arguments, in access path: Method[foo].Member |
| Invalid token name 'Arg' in access path: Method[foo].Arg[0] |

View File

@@ -0,0 +1,25 @@
import python
import semmle.python.frameworks.data.internal.AccessPathSyntax as AccessPathSyntax
import semmle.python.frameworks.data.internal.ApiGraphModels as ApiGraphModels
import semmle.python.frameworks.data.ModelsAsData
private class InvalidTypeModel extends ModelInput::TypeModelCsv {
override predicate row(string row) {
row =
[
"test;TooManyColumns;;;Member[Foo].Instance;too;many;columns", //
"test;TooFewColumns", //
"test;X;test;Y;Method[foo].Arg[0]", //
"test;X;test;Y;Method[foo].Argument[0-1]", //
"test;X;test;Y;Method[foo].Argument[*]", //
"test;X;test;Y;Method[foo].Argument", //
"test;X;test;Y;Method[foo].Member", //
]
}
}
class IsTesting extends ApiGraphModels::TestAllModels {
IsTesting() { this = this }
}
query predicate warning = ModelOutput::getAWarning/0;