-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Open
Labels
Description
When I use taint tracking to test code below
function Compiler(source){
this.pp = source.pretty;
sink1(this.pp)
}
Compiler.prototype = {
compile: function (){
sink2(this.pp);
}
}
function generateCode(source) {
return new Compiler(source).compile();
}
var data = easySource();
generateCode({pretty: data.pretty})/**
* @name data-flow
* @kind path-problem
* @problem.severity warning
* @tags security
* @id js
*/
import javascript
import DataFlow::PathGraph
DataFlow::SourceNode easySourceTracker(DataFlow::TypeTracker t) {
t.start() and
result instanceof MyTestSource
or
exists(DataFlow::TypeTracker t2 | result = easySourceTracker(t2).track(t2, t))
}
class MyTestSource extends DataFlow::Node {
MyTestSource(){
exists(CallExpr call |
call.getCalleeName()="easySource" |
this.asExpr() = call
)
}
}
class MyTestSink extends DataFlow::Node {
MyTestSink(){
exists(DataFlow::InvokeNode call |
call.getCalleeName().indexOf("sink") != -1 |
this = call.getAnArgument()
)
}
}
class TestConfiguration extends TaintTracking::Configuration {
TestConfiguration() { this = "TestConfiguration" }
override predicate isSource(DataFlow::Node source) {
source = easySourceTracker(_)
}
override predicate isSink(DataFlow::Node sink) {
sink instanceof MyTestSink
}
}
from TestConfiguration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, DataFlow::InvokeNode call
where cfg.hasFlowPath(source, sink)
and call.getAnArgument() = sink.getNode()
select sink.getNode(), source, sink, call.getCalleeName()I found codeql can not find the taint flow to sink2(this.pp);
But if I modify generateCode({pretty: data.pretty}) to generateCode(data), codeql now can find sink2(this.pp);.
Although I found we could add localFieldStep to record all step from pred to succ through a field accessed through this in a class.
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
DataFlow::localFieldStep(pred, succ)
}But I am confused, why can codeql handled this case after modify generateCode({pretty: data.pretty}) to generateCode(data) or why it can’t be handled before the modification.