Skip to content

Commit 43e99d0

Browse files
committed
[TEST] C++: CleartextSqliteDatabase: add new test
1 parent ec605b2 commit 43e99d0

File tree

3 files changed

+141
-0
lines changed

3 files changed

+141
-0
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
typedef unsigned long size_t;
2+
typedef struct sqlite3 sqlite3;
3+
typedef struct sqlite3_stmt sqlite3_stmt;
4+
typedef struct sqlite3_str sqlite3_str;
5+
6+
int snprintf(char *str, size_t size, const char *format, ...);
7+
int sqlite3_open(const char *filename, sqlite3 **ppDb);
8+
int sqlite3_close(sqlite3*);
9+
int sqlite3_exec(sqlite3*, const char *sql, int (*callback)(void*,int,char**,char**), void *, char **errmsg);
10+
int sqlite3_prepare_v2(sqlite3 *db, const char *zSql, int nByte, sqlite3_stmt **ppStmt, const char **pzTail);
11+
int sqlite3_step(sqlite3_stmt*);
12+
int sqlite3_finalize(sqlite3_stmt*);
13+
int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
14+
sqlite3_str* sqlite3_str_new(sqlite3*);
15+
void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...);
16+
char* sqlite3_str_finish(sqlite3_str*);
17+
18+
#define SQLITE_TRANSIENT ((void(*)(void*))-1)
19+
20+
// Simulate a sensitive value
21+
const char* getSensitivePassword() {
22+
return "super_secret_password";
23+
}
24+
25+
void storePasswordCleartext(sqlite3* db, const char* password) {
26+
// BAD: Storing sensitive data in cleartext
27+
char sql[256];
28+
// Unsafe: no escaping, for test purposes only
29+
snprintf(sql, sizeof(sql), "INSERT INTO users(password) VALUES('%s');", password); // $ Source
30+
char* errMsg = 0;
31+
sqlite3_exec(db, sql, 0, 0, &errMsg); // $ Alert
32+
}
33+
34+
void storePasswordWithPrepare(sqlite3* db, const char* password) {
35+
// BAD: Storing sensitive data in cleartext using sqlite3_prepare
36+
char sql[256];
37+
snprintf(sql, sizeof(sql), "INSERT INTO users(password) VALUES('%s');", password); // $ Source
38+
sqlite3_stmt* stmt = 0;
39+
sqlite3_prepare_v2(db, sql, -1, &stmt, 0); // $ Alert
40+
sqlite3_step(stmt);
41+
sqlite3_finalize(stmt);
42+
}
43+
44+
void storePasswordWithBind(sqlite3* db, const char* password) {
45+
// BAD: Storing sensitive data in cleartext using sqlite3_bind_text
46+
const char* sql = "INSERT INTO users(password) VALUES(?);";
47+
sqlite3_stmt* stmt = 0;
48+
sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
49+
sqlite3_bind_text(stmt, 1, password, -1, SQLITE_TRANSIENT); // $ Alert
50+
sqlite3_step(stmt);
51+
sqlite3_finalize(stmt);
52+
}
53+
54+
void storePasswordWithAppendf(sqlite3_str* pStr, const char* password) {
55+
// BAD: Storing sensitive data in cleartext using sqlite3_str_appendf
56+
sqlite3_str_appendf(pStr, "INSERT INTO users(password) VALUES('%s');", password); // $ Alert
57+
}
58+
59+
// Example sanitizer: hashes the sensitive value before storage
60+
void hashSensitiveValue(const char* input, char* output, size_t outSize) {
61+
// Dummy hash for illustration (not cryptographically secure)
62+
unsigned int hash = 5381;
63+
for (const char* p = input; *p; ++p)
64+
hash = ((hash << 5) + hash) + (unsigned char)(*p);
65+
snprintf(output, outSize, "%u", hash);
66+
}
67+
68+
void storeSanitizedPasswordCleartext(sqlite3* db, const char* password) {
69+
// GOOD: Sanitizing sensitive data before storage
70+
char hashed[64];
71+
hashSensitiveValue(password, hashed, sizeof(hashed));
72+
char sql[256];
73+
snprintf(sql, sizeof(sql), "INSERT INTO users(password) VALUES('%s');", hashed);
74+
char* errMsg = 0;
75+
sqlite3_exec(db, sql, 0, 0, &errMsg);
76+
}
77+
78+
void storeSanitizedPasswordWithBind(sqlite3* db, const char* password) {
79+
// GOOD: Sanitizing sensitive data before storage with bind
80+
char hashed[64];
81+
hashSensitiveValue(password, hashed, sizeof(hashed));
82+
const char* sql = "INSERT INTO users(password) VALUES(?);";
83+
sqlite3_stmt* stmt = 0;
84+
sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
85+
sqlite3_bind_text(stmt, 1, hashed, -1, SQLITE_TRANSIENT);
86+
sqlite3_step(stmt);
87+
sqlite3_finalize(stmt);
88+
}
89+
90+
void storeSanitizedPasswordWithAppendf(sqlite3_str* pStr, const char* password) {
91+
// GOOD: Sanitizing sensitive data before storage with appendf
92+
char hashed[64];
93+
hashSensitiveValue(password, hashed, sizeof(hashed));
94+
sqlite3_str_appendf(pStr, "INSERT INTO users(password) VALUES('%s');", hashed);
95+
}
96+
97+
int main() {
98+
sqlite3* db = 0;
99+
sqlite3_open(":memory:", &db);
100+
101+
// Create table
102+
const char* createTableSQL = "CREATE TABLE users(id INTEGER PRIMARY KEY, password TEXT);";
103+
sqlite3_exec(db, createTableSQL, 0, 0, 0);
104+
105+
const char* sensitive = getSensitivePassword();
106+
107+
storePasswordCleartext(db, sensitive);
108+
storePasswordWithPrepare(db, sensitive);
109+
storePasswordWithBind(db, sensitive);
110+
storeSanitizedPasswordCleartext(db, sensitive);
111+
storeSanitizedPasswordWithBind(db, sensitive);
112+
113+
// If sqlite3_str is available
114+
sqlite3_str* pStr = sqlite3_str_new(db);
115+
storePasswordWithAppendf(pStr, sensitive);
116+
storeSanitizedPasswordWithAppendf(pStr, sensitive);
117+
sqlite3_str_finish(pStr);
118+
119+
sqlite3_close(db);
120+
return 0;
121+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#select
2+
| CleartextSqliteDatabase.cpp:31:5:31:16 | call to sqlite3_exec | CleartextSqliteDatabase.cpp:29:77:29:84 | password | CleartextSqliteDatabase.cpp:31:22:31:24 | *sql | This SQLite call may store $@ in a non-encrypted SQLite database. | CleartextSqliteDatabase.cpp:29:77:29:84 | password | sensitive information |
3+
| CleartextSqliteDatabase.cpp:39:5:39:22 | call to sqlite3_prepare_v2 | CleartextSqliteDatabase.cpp:37:77:37:84 | password | CleartextSqliteDatabase.cpp:39:28:39:30 | *sql | This SQLite call may store $@ in a non-encrypted SQLite database. | CleartextSqliteDatabase.cpp:37:77:37:84 | password | sensitive information |
4+
| CleartextSqliteDatabase.cpp:49:5:49:21 | call to sqlite3_bind_text | CleartextSqliteDatabase.cpp:49:32:49:39 | password | CleartextSqliteDatabase.cpp:49:32:49:39 | password | This SQLite call may store $@ in a non-encrypted SQLite database. | CleartextSqliteDatabase.cpp:49:32:49:39 | password | sensitive information |
5+
| CleartextSqliteDatabase.cpp:56:5:56:23 | call to sqlite3_str_appendf | CleartextSqliteDatabase.cpp:56:76:56:83 | password | CleartextSqliteDatabase.cpp:56:76:56:83 | password | This SQLite call may store $@ in a non-encrypted SQLite database. | CleartextSqliteDatabase.cpp:56:76:56:83 | password | sensitive information |
6+
edges
7+
| CleartextSqliteDatabase.cpp:29:77:29:84 | password | CleartextSqliteDatabase.cpp:31:22:31:24 | *sql | provenance | TaintFunction |
8+
| CleartextSqliteDatabase.cpp:37:77:37:84 | password | CleartextSqliteDatabase.cpp:39:28:39:30 | *sql | provenance | TaintFunction |
9+
nodes
10+
| CleartextSqliteDatabase.cpp:29:77:29:84 | password | semmle.label | password |
11+
| CleartextSqliteDatabase.cpp:31:22:31:24 | *sql | semmle.label | *sql |
12+
| CleartextSqliteDatabase.cpp:37:77:37:84 | password | semmle.label | password |
13+
| CleartextSqliteDatabase.cpp:39:28:39:30 | *sql | semmle.label | *sql |
14+
| CleartextSqliteDatabase.cpp:49:32:49:39 | password | semmle.label | password |
15+
| CleartextSqliteDatabase.cpp:56:76:56:83 | password | semmle.label | password |
16+
subpaths
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
query: Security/CWE/CWE-313/CleartextSqliteDatabase.ql
2+
postprocess:
3+
- utils/test/PrettyPrintModels.ql
4+
- utils/test/InlineExpectationsTestQuery.ql

0 commit comments

Comments
 (0)