Add def-use code sample and query

This commit is contained in:
Michael Hohn
2023-11-28 17:04:57 -08:00
committed by =Michael Hohn
parent 60ee4295b2
commit bf9197cb57
7 changed files with 189 additions and 1 deletions

36
cruft/snapshot-query-1 Executable file
View File

@@ -0,0 +1,36 @@
#!/bin/bash
usage="Take a snapshot of the current session1.ql
Usage:
$0 TheSnapShotName
"
if [ $# -ne 1 ]
then
echo "$usage"
exit 1
fi
if [ "$1" = "-h" ]
then
echo "$usage"
exit 1
fi
qname=$1
# create the tests
mkdir -p tests/$qname
touch tests/$qname/$qname.expected
echo $qname.ql > tests/$qname/$qname.qlref
git add tests/$qname/$qname.expected
git add tests/$qname/$qname.qlref
# snapshot the session
cp sample-utility-0.js tests/$qname/
git add tests/$qname/sample-utility-0.js
cp sample-utility-1.js tests/$qname/
git add tests/$qname/sample-utility-1.js
cp session/session1.ql solutions/$qname.ql
git add solutions/$qname.ql

View File

@@ -11,5 +11,6 @@ then
fi
mkdir -p tests
mkdir -p solutions
echo 'import javascript' > session.ql
echo 'import javascript' > session/session.ql
echo 'import javascript' > session/session1.ql

80
solutions/DefUseSample.ql Normal file
View File

@@ -0,0 +1,80 @@
/**
* @kind path-problem
* @problem.severity warning
* @id javascript/example/multiflow
*/
import javascript
// XX: debug flow query
// import semmle.javascript.explore.ForwardDataFlow
import DataFlow::PathGraph
// Flow to consider:
//
// var value = this.getParameter('value'); //: source 1
// var ua = new GR('status'); //: source 2
// ua.setValue('status',value); //: taint step
// ua.update(); //: sink (if from source 2)
// var value = this.getParameter('value'); //: source 1
class ParameterSource extends CallExpr {
ParameterSource() {
exists(Expr inst |
this.getCalleeName() = "getParameter" and
(this.getReceiver().(ThisExpr) = inst or this.getReceiver().(Identifier) = inst)
)
}
}
// ua.setValue('status',value); //: taint step
predicate setValueTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
exists(DotExpr temp, MethodCallExpr mce, VarAccess gr, VarAccess postgr |
temp.getPropertyName() = "setValue" and
mce.getReceiver() = temp.getBase() and
gr = mce.getReceiver() and
pred.asExpr() = mce.getArgument(1) and
//
// Taint all accesses after setValue call.
// Trying data flow, this would be:
// succ = gr.flow().getASuccessor+() and
//
// Using control flow:
gr.getASuccessor+() = postgr and
succ.asExpr() = postgr
)
}
// ua.update(); //: sink (if from source 2)
DotExpr updateExpression() { result.getPropertyName() = "update" }
VarRef recordUpdate() { result = updateExpression().getBase() }
// var ua = new GR('status'); //: source 2
class GR extends NewExpr {
GR() { this.getCalleeName() = "GR" }
}
class FromRequestToGrUpdate extends TaintTracking::Configuration {
FromRequestToGrUpdate() { this = "FromRequestToGrUpdate" }
override predicate isSource(DataFlow::Node source) {
exists(ParameterSource getParameter | source.asExpr() = getParameter)
}
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
setValueTaintStep(pred, succ)
}
override predicate isSink(DataFlow::Node sink) {
exists(VarRef grUpdate |
sink.asExpr() = recordUpdate() and
grUpdate = sink.asExpr() and
grUpdate.getName() = "ua"
)
}
}
from FromRequestToGrUpdate dataflow, DataFlow::PathNode source, DataFlow::PathNode sink
where dataflow.hasFlowPath(source, sink)
select sink, source, sink, "Data flow from $@ to $@.", source, source.toString(), sink,
sink.toString()

View File

@@ -0,0 +1,30 @@
WARNING: Unused class GR (/Users/hohn/local/codeql-javascript-multiflow/solutions/DefUseSample.ql:53,7-9)
nodes
| sample-utility-0.js:5:6:5:39 | value |
| sample-utility-0.js:5:14:5:39 | this.ge ... value') |
| sample-utility-0.js:5:14:5:39 | this.ge ... value') |
| sample-utility-0.js:17:27:17:31 | value |
| sample-utility-0.js:18:6:18:7 | ua |
| sample-utility-0.js:18:6:18:7 | ua |
| sample-utility-1.js:2:9:2:42 | value |
| sample-utility-1.js:2:17:2:42 | this.ge ... value') |
| sample-utility-1.js:2:17:2:42 | this.ge ... value') |
| sample-utility-1.js:14:23:14:27 | value |
| sample-utility-1.js:15:2:15:3 | ua |
| sample-utility-1.js:15:2:15:3 | ua |
edges
| sample-utility-0.js:5:6:5:39 | value | sample-utility-0.js:17:27:17:31 | value |
| sample-utility-0.js:5:14:5:39 | this.ge ... value') | sample-utility-0.js:5:6:5:39 | value |
| sample-utility-0.js:5:14:5:39 | this.ge ... value') | sample-utility-0.js:5:6:5:39 | value |
| sample-utility-0.js:17:27:17:31 | value | sample-utility-0.js:17:27:17:31 | value |
| sample-utility-0.js:17:27:17:31 | value | sample-utility-0.js:18:6:18:7 | ua |
| sample-utility-0.js:17:27:17:31 | value | sample-utility-0.js:18:6:18:7 | ua |
| sample-utility-1.js:2:9:2:42 | value | sample-utility-1.js:14:23:14:27 | value |
| sample-utility-1.js:2:17:2:42 | this.ge ... value') | sample-utility-1.js:2:9:2:42 | value |
| sample-utility-1.js:2:17:2:42 | this.ge ... value') | sample-utility-1.js:2:9:2:42 | value |
| sample-utility-1.js:14:23:14:27 | value | sample-utility-1.js:14:23:14:27 | value |
| sample-utility-1.js:14:23:14:27 | value | sample-utility-1.js:15:2:15:3 | ua |
| sample-utility-1.js:14:23:14:27 | value | sample-utility-1.js:15:2:15:3 | ua |
#select
| sample-utility-0.js:18:6:18:7 | ua | sample-utility-0.js:5:14:5:39 | this.ge ... value') | sample-utility-0.js:18:6:18:7 | ua | Data flow from $@ to $@. | sample-utility-0.js:5:14:5:39 | this.ge ... value') | this.ge ... value') | sample-utility-0.js:18:6:18:7 | ua | ua |
| sample-utility-1.js:15:2:15:3 | ua | sample-utility-1.js:2:17:2:42 | this.ge ... value') | sample-utility-1.js:15:2:15:3 | ua | Data flow from $@ to $@. | sample-utility-1.js:2:17:2:42 | this.ge ... value') | this.ge ... value') | sample-utility-1.js:15:2:15:3 | ua | ua |

View File

@@ -0,0 +1 @@
DefUseSample.ql

View File

@@ -0,0 +1,23 @@
var SampleUtility = function(){};
SampleUtility.prototype = Object.extendsObject(Processor, {
setUserStatus: function() {
var value = this.getParameter('value');
var ua = new GR('users');
ua.query();
if(!ua.hasNext()){
ua.initialize();
ua.setValue('status',value);
ua.insert();
}
else {
ua.next();
ua.setValue('status',value);
ua.update();
}
},
type: 'SampleUtility'
});

View File

@@ -0,0 +1,17 @@
var SampleUtility = function() {
var value = this.getParameter('value');
var ua = new GR('users');
ua.query();
if(!ua.hasNext()){
ua.initialize();
ua.setValue('status',value);
ua.insert();
}
else {
ua.next();
ua.setValue('status',value);
ua.update();
}
}