From 999f665ceba918f580e3e636ab6635e04c4cc741 Mon Sep 17 00:00:00 2001 From: Michael Hohn Date: Wed, 22 Jul 2020 14:24:44 -0700 Subject: [PATCH] The isSink Predicate --- codeql-dataflow-sql-injection.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/codeql-dataflow-sql-injection.md b/codeql-dataflow-sql-injection.md index f7813d9..457b689 100644 --- a/codeql-dataflow-sql-injection.md +++ b/codeql-dataflow-sql-injection.md @@ -566,9 +566,33 @@ select exec, sink ``` Second, we need this as a predicate of a single argument, `predicate -isSink(DataFlow::Node sink)` +isSink(DataFlow::Node sink)`. For this we introduce the `exists()` +[quantifier](https://help.semmle.com/QL/ql-handbook/formulas.html?highlight=exists#exists) +to move the `FunctionCall exec` into the body of the query and remove it from the +result: +```ql +from DataFlow::Node sink +where + exists(FunctionCall exec | + exec.getTarget().getName() = "sqlite3_exec" and + sink.asExpr() = exec.getArgument(1) + ) +select sink +``` +To turn this into a predicate, `from` contents become arguments, the `where` +becomes the body, and the `select` is dropped: + +```ql +predicate isSink(DataFlow::Node sink) { + // rc = sqlite3_exec(db, query, NULL, 0, &zErrMsg); + exists(FunctionCall exec | + exec.getTarget().getName() = "sqlite3_exec" and + sink.asExpr() = exec.getArgument(1) + ) +} +``` ### The Data Source