Files
codeql-c-sqli/session.ql
2025-06-05 14:08:01 -07:00

99 lines
2.3 KiB
Plaintext

/**
* @name SQLI Vulnerability
* @description Using untrusted strings in a sql query allows sql injection attacks.
* @kind path-problem
* @id cpp/sqlivulnerable
* @problem.severity warning
*/
import cpp
// from Call cl
// select cl
/*
* int get_new_id() {
* int id = getpid();
* return id;
* }
*/
// Goal: Find connection
// 1. reading user data -- source
// count = read(STDIN_FILENO, buf, BUFSIZE - 1);
// ^^^
// from FunctionCall read, Expr buf
// where read.getTarget().getName() = "read"
// and buf = read.getArgument(1)
// select read, buf
predicate isSource(Expr buf) {
exists(FunctionCall read |
read.getTarget().getName() = "read" and
buf = read.getArgument(1)
)
}
// from Expr buf
// where isSource(buf)
// select buf
class MySource extends Expr {
MySource() {
exists(FunctionCall read |
read.getTarget().getName() = "read" and
this = read.getArgument(1)
)
}
}
// from MySource buf
// select buf
// 2. writing sql -- sink
// rc = sqlite3_exec(db, query, NULL, 0, &zErrMsg);
// ^^^^^
// from FunctionCall exec, Expr query
// where exec.getTarget().getName() = "sqlite3_exec"
// and query = exec.getArgument(1)
// select exec, query
predicate isSink(Expr query) {
exists(FunctionCall exec |
exec.getTarget().getName() = "sqlite3_exec" and
query = exec.getArgument(1)
)
}
// from Expr query
// where isSink(query)
// select query
class MySink extends Expr {
FunctionCall exec;
MySink() {
exec.getTarget().getName() = "sqlite3_exec" and
this = exec.getArgument(1)
}
FunctionCall getTheCall() { result = exec }
}
// from MySink query
// select query, query.getTheCall()
// 3. find call path between 1 and 2 them
import semmle.code.cpp.dataflow.new.TaintTracking
module SqliFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
exists(MySource ms | ms = source.asDefiningArgument())
}
predicate isSink(DataFlow::Node sink) { exists(MySink ms | ms = sink.asIndirectArgument()) }
}
module MyFlow = TaintTracking::Global<SqliFlowConfig>;
import MyFlow::PathGraph
from MyFlow::PathNode source, MyFlow::PathNode sink
where MyFlow::flowPath(source, sink)
select sink, source, sink, "Possible SQL injection"
// from MySource ms
// select ms.getASuccessor*()