Closed github-learning-lab[bot] closed 3 years ago
exists
quantifierSo far, we have declared variables in the from
section of a query clause. Sometimes we need temporary variables in other parts of the query, and don't want to expose them in the query clause. The exists
keyword helps us do this. It is a quantifier: it introduces temporary variables and checks if they satisfy a particular condition.
To understand how exists
works, visit the documentation.
Then let's take an example. In a previous step you created a query to get calls to $
:
from CallExpr dollarCall
where dollarCall.getCalleeName() = "$"
select dollarCall
How would you transform this query to get only calls to $
that have at least one argument? You could write:
from CallExpr dollarCallWithArgument, Expr dollarArg
where dollarCallWithArgument.getCalleeName() = "$" and dollarArg = dollarCallWithArgument.getAnArgument()
select dollarCallWithArgument
But in that query dollarArg
is not used other than as a temporary variable, so another way to write the same thing is to use the exists
quantifier:
from CallExpr dollarCallWithArgument
where dollarCallWithArgument.getCalleeName() = "$" and exists(Expr dollarArg | dollarArg = dollarCallWithArgument.getAnArgument())
select dollarCallWithArgument
And we can simplify the query to finally write:
from CallExpr dollarCallWithArgument
where dollarCallWithArgument.getCalleeName() = "$" and exists(dollarCallWithArgument.getAnArgument())
select dollarCallWithArgument
You will transform the previous query you wrote to identify the places in the program which receive jQuery plugin options, into a predicate called isSource
, by using the exists
quantifier.
Edit the file sources.ql
and fill in the TODOs
in the template below.
The from ... where ... select
query here is just there to test your isSource
predicate,
and should give you the same results as your previous query.
You notice that below the source
is of type DataFlow::Node
whereas in your previous query you used
DataFlow::ParameterNode
. This is ok as a ParameterNode
is a Node
.
Submit your query.
import javascript
predicate isSource(DataFlow::Node source) {
exists(<TODO: declare temporary variables> |
<TODO: clause that identifies your source as a jquery plugin option>
)
}
from DataFlow::Node node
where isSource(node)
select node
Congratulations, looks like the query you introduced in 79dbd28ff89b05de8b0525a275f54c202664a0bc finds the correct results!
Take a look at the instructions for the next step to continue.
Step 9: Detecting the sources
We have now identified places in the program which receive jQuery plugin options, and which may be considered as sources of untrusted data. In this step we'll create a predicate that will hold true if a
DataFlow::Node
is such a source. This predicate will be helpful for our last query.