Merge pull request #115 from esben-semmle/js/composed-function-taint

JS: model composed functions
This commit is contained in:
Max Schaefer
2018-08-31 08:14:18 +01:00
committed by GitHub
6 changed files with 211 additions and 0 deletions

View File

@@ -53,6 +53,7 @@ import semmle.javascript.frameworks.AngularJS
import semmle.javascript.frameworks.AWS
import semmle.javascript.frameworks.Azure
import semmle.javascript.frameworks.Babel
import semmle.javascript.frameworks.ComposedFunctions
import semmle.javascript.frameworks.Credentials
import semmle.javascript.frameworks.CryptoLibraries
import semmle.javascript.frameworks.DigitalOcean

View File

@@ -0,0 +1,67 @@
/**
* Provides classes for reasoning about composed functions.
*/
import javascript
/**
* A function composed from a collection of functions.
*/
private class ComposedFunction extends DataFlow::CallNode {
ComposedFunction() {
exists (string name |
name = "just-compose" or
name = "compose-function" |
this = DataFlow::moduleImport(name).getACall()
) or
this = LodashUnderscore::member("flow").getACall()
}
/**
* Gets the ith function in this composition.
*/
DataFlow::FunctionNode getFunction(int i) {
result.flowsTo(getArgument(i))
}
}
/**
* A taint step for a composed function.
*/
private class ComposedFunctionTaintStep extends TaintTracking::AdditionalTaintStep {
ComposedFunction composed;
DataFlow::CallNode call;
ComposedFunctionTaintStep() {
call = composed.getACall() and
this = call
}
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
exists (int fnIndex, DataFlow::FunctionNode fn |
fn = composed.getFunction(fnIndex) |
// flow out of the composed call
fnIndex = composed.getNumArgument() - 1 and
pred = fn.getAReturn() and
succ = this
or
if fnIndex = 0 then
// flow into the first composed function
exists (int callArgIndex |
pred = call.getArgument(callArgIndex) and
succ = fn.getParameter(callArgIndex)
)
else
// flow through the composed functions
exists (DataFlow::FunctionNode predFn |
predFn = composed.getFunction(fnIndex - 1) |
pred = predFn.getAReturn() and
succ = fn.getParameter(0)
)
)
}
}