Skip to content

Commit d89b8ba

Browse files
authored
Merge pull request github#12469 from MathiasVP/speedup-CleartextSqliteDatabase
C++: Restrict sinks in `cpp/cleartext-storage-database`
2 parents 67a07e9 + 84a61d1 commit d89b8ba

File tree

1 file changed

+55
-8
lines changed

1 file changed

+55
-8
lines changed

cpp/ql/src/Security/CWE/CWE-313/CleartextSqliteDatabase.ql

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,54 @@ import semmle.code.cpp.security.SensitiveExprs
1616
import semmle.code.cpp.ir.dataflow.TaintTracking
1717
import FromSensitiveFlow::PathGraph
1818

19-
class SqliteFunctionCall extends FunctionCall {
20-
SqliteFunctionCall() { this.getTarget().getName().matches("sqlite%") }
19+
abstract class SqliteFunctionCall extends FunctionCall {
20+
abstract Expr getASource();
21+
}
22+
23+
class SqliteFunctionPrepareCall extends SqliteFunctionCall {
24+
SqliteFunctionPrepareCall() { this.getTarget().getName().matches("sqlite3\\_prepare%") }
25+
26+
override Expr getASource() { result = this.getArgument(1) }
27+
}
28+
29+
class SqliteFunctionExecCall extends SqliteFunctionCall {
30+
SqliteFunctionExecCall() { this.getTarget().hasName("sqlite3_exec") }
31+
32+
override Expr getASource() { result = this.getArgument(1) }
33+
}
34+
35+
class SqliteFunctionAppendfCall extends SqliteFunctionCall {
36+
SqliteFunctionAppendfCall() {
37+
this.getTarget().hasName(["sqlite3_str_appendf", "sqlite3_str_vappendf"])
38+
}
39+
40+
override Expr getASource() { result = this.getArgument(any(int n | n > 0)) }
41+
}
42+
43+
class SqliteFunctionAppendNonCharCall extends SqliteFunctionCall {
44+
SqliteFunctionAppendNonCharCall() {
45+
this.getTarget().hasName(["sqlite3_str_append", "sqlite3_str_appendall"])
46+
}
47+
48+
override Expr getASource() { result = this.getArgument(1) }
49+
}
50+
51+
class SqliteFunctionAppendCharCall extends SqliteFunctionCall {
52+
SqliteFunctionAppendCharCall() { this.getTarget().hasName("sqlite3_str_appendchar") }
53+
54+
override Expr getASource() { result = this.getArgument(2) }
55+
}
2156

22-
Expr getASource() { result = this.getAnArgument() }
57+
class SqliteFunctionBindCall extends SqliteFunctionCall {
58+
SqliteFunctionBindCall() {
59+
this.getTarget()
60+
.hasName([
61+
"sqlite3_bind_blob", "sqlite3_bind_blob64", "sqlite3_bind_text", "sqlite3_bind_text16",
62+
"sqlite3_bind_text64", "sqlite3_bind_value", "sqlite3_bind_pointer"
63+
])
64+
}
65+
66+
override Expr getASource() { result = this.getArgument(2) }
2367
}
2468

2569
predicate sqlite_encryption_used() {
@@ -57,17 +101,20 @@ predicate isSinkImpl(DataFlow::Node sink, SqliteFunctionCall c, Type t) {
57101
* A taint flow configuration for flow from a sensitive expression to a `SqliteFunctionCall` sink.
58102
*/
59103
module FromSensitiveConfiguration implements DataFlow::ConfigSig {
60-
predicate isSource(DataFlow::Node source) { isSourceImpl(source, _) }
61-
62-
predicate isSink(DataFlow::Node sink) {
63-
isSinkImpl(sink, _, _) and
64-
not sqlite_encryption_used()
104+
predicate isSource(DataFlow::Node source) {
105+
isSourceImpl(source, _) and not sqlite_encryption_used()
65106
}
66107

108+
predicate isSink(DataFlow::Node sink) { isSinkImpl(sink, _, _) }
109+
67110
predicate isBarrier(DataFlow::Node node) {
68111
node.asExpr().getUnspecifiedType() instanceof IntegralType
69112
}
70113

114+
predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
115+
116+
predicate isBarrierOut(DataFlow::Node node) { isSink(node) }
117+
71118
predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet content) {
72119
// flow out from fields at the sink (only).
73120
// constrain `content` to a field inside the node.

0 commit comments

Comments
 (0)