在 SQLite 数据库中以明文形式存储敏感信息¶
ID: cpp/cleartext-storage-database
Kind: path-problem
Security severity: 7.5
Severity: warning
Precision: medium
Tags:
- security
- external/cwe/cwe-313
Query suites:
- cpp-security-extended.qls
- cpp-security-and-quality.qls
存储在未加密的 SQLite 数据库中的敏感信息可被获取数据库访问权限的攻击者访问。
建议¶
确保如果敏感信息存储在数据库中,则该数据库始终处于加密状态。
示例¶
以下示例展示了两种在 SQLite 数据库中存储信息的方式。在“错误”案例中,凭据以明文形式存储。在“正确”案例中,数据库(以及凭据)已加密。
void bad(void) {
char *password = "cleartext password";
sqlite3 *credentialsDB;
sqlite3_stmt *stmt;
if (sqlite3_open("credentials.db", &credentialsDB) == SQLITE_OK) {
// BAD: database opened without encryption being enabled
sqlite3_exec(credentialsDB, "CREATE TABLE IF NOT EXISTS creds (password TEXT);", NULL, NULL, NULL);
if (sqlite3_prepare_v2(credentialsDB, "INSERT INTO creds(password) VALUES(?)", -1, &stmt, NULL) == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, password, -1, SQLITE_TRANSIENT);
sqlite3_step(stmt);
sqlite3_finalize(stmt);
sqlite3_close(credentialsDB);
}
}
}
void good(void) {
char *password = "cleartext password";
sqlite3 *credentialsDB;
sqlite3_stmt *stmt;
if (sqlite3_open("credentials.db", &credentialsDB) == SQLITE_OK) {
// GOOD: database encryption enabled:
sqlite3_exec(credentialsDB, "PRAGMA key = 'secretKey!'", NULL, NULL, NULL);
sqlite3_exec(credentialsDB, "CREATE TABLE IF NOT EXISTS creds (password TEXT);", NULL, NULL, NULL);
if (sqlite3_prepare_v2(credentialsDB, "INSERT INTO creds(password) VALUES(?)", -1, &stmt, NULL) == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, password, -1, SQLITE_TRANSIENT);
sqlite3_step(stmt);
sqlite3_finalize(stmt);
sqlite3_close(credentialsDB);
}
}
}
参考¶
M. Dowd、J. McDonald 和 J. Schuhm,《软件安全评估艺术》,第 1 版,第 2 章 - “加密的常见漏洞”,第 43 页。Addison Wesley,2006 年。
M. Howard 和 D. LeBlanc,《编写安全代码》,第 2 版,第 9 章 - “保护秘密数据”,第 299 页。Microsoft,2002 年。
常见弱点枚举:CWE-313.