8.3 安全加固


8.3 安全加固:注入面、权限、加密与 schema 纪律

本节摘要:SQLite 没有端口、没有账号体系,它的攻击面与 MySQL、PostgreSQL 完全不同:不防"网络上的陌生人",防的是"拿到文件的人"与"能发语句的代码路径"。本节按四个层面组织加固清单:语句层防注入、文件层做访问控制、存储层上加密扩展、schema 层守纪律,并对照三库的权限与加密模型。

第一层:语句面——参数绑定是唯一正解

进程内引擎的语句注入风险与 Web 场景同源:把用户输入拼进 SQL 字符串。区别在于后果半径——注入成功的代码运行在应用进程里,能读写的正是应用能读写的全部文件。防御在机制层面完成(第 3 章讲过的占位符):

/* 错误:拼接。输入 ' OR '1'='1 直接改写语义 */ char sql[512]; snprintf(sql, sizeof sql, "SELECT * FROM users WHERE name='%s'", input); /* 正确:占位符。输入永远是数据,不是代码 */ sqlite3_stmt *stmt; sqlite3_prepare_v2(db, "SELECT * FROM users WHERE name = ?1", -1, &stmt, 0); sqlite3_bind_text(stmt, 1, input, -1, SQLITE_TRANSIENT);

两个常被忽略的语句面风险。ATTACHATTACH DATABASE ?1 AS aux 让一条语句引入外部文件——任何能执行任意 SQL 的路径都能借此读写新文件。加固手段是用 sqlite3_set_authorizer 回调白名单化允许的语句类型与访问对象,或干脆禁止动态 SQL。PRAGMA 函数化:新版本允许 pragma_table_info() 等以表函数形态出现在查询里,schema 探测更容易了,配合只读连接使用是稳妥姿势。

第二层:文件面——权限即身份

SQLite 的访问控制就是文件系统的访问控制。这带来模型上的根本简化与几个必须执行的纪律:

  • 最小权限落地为文件权限:应用以专用系统用户运行,库文件与 WAL 伴生文件只对该用户可读写,其他任何用户无权。-wal-shm 的权限要与主文件一致——它们在检查点间隙承载最新数据,泄了伴生文件等于泄了库。
  • 只读场景用只读打开sqlite3_open_v2(path, &db, SQLITE_OPEN_READONLY, 0) 让"误写"在接口层就被拒绝;配合文件层只读挂载双保险。
  • 临时文件的归宿:temp_store 为 FILE 时排序溢出写到临时目录,目录权限同样要收口;内存充裕的场景直接 MEMORY,少一个泄密面。

对照三库:MySQL 与 PostgreSQL 把"谁能读哪行"做成精细的授权体系(账号、库、表、列级,行级策略),SQLite 把这件事完全交给文件系统——粒度粗到只有"能碰与不能碰",但边界清晰到没有旁路。单用户嵌入式场景里,这套粗粒度反而更难配错。

第三层:存储面——加密扩展

官方的分发包不含加密;需要静态加密时两条路:

  1. SEE(官方扩展):商业授权,编译进 amalgamation,PRAGMA key = '口令' 即启用,整库含 WAL 全加密,兼容性与官方构建一致。
  2. SQLCipher 等开源方案:以补丁形态替换 pager 的读写路径,页级 AES 加密,API 与 SQLite 完全兼容,移动端事实标准。

两个共同的工程要点:口令的传递与内存清零要纳入应用的安全设计(口令在进程内存里的残留是常见疏漏);加密页与页大小的关系——加密不改变 B-Tree 结构但可能调整每页有效载荷(预留校验与 IV 空间),建库前就要定好,中途启用加密等于换库。对照服务端:MySQL 的表空间加密与 PostgreSQL 的 TDE 变体同为静态加密,粒度是表空间或集群;SQLite 的加密粒度是整库,没有列级加密——敏感列的细粒度需求在应用层做字段级加密再入库存 BLOB。

第四层:schema 面——纪律清单

最后一批暗门在 DDL 与配置习惯里:

PRAGMA trusted_schema = OFF; -- 3.31+:schema 里的对象不得调用任意应用函数 PRAGMA defensive = ON; -- 3.26+:阻止直接写 sqlite_schema 等内部表 -- 迁移脚本纪律:每个 DDL 变更走版本号迁移表,禁止运行期动态建表 -- 视图收敛:给不可信查询方只暴露视图,不暴露基表

trusted_schemadefensive 两个开关是官方对"嵌入式场景里 SQL 来自多方"这一现实的回应——前者的旧世界(默认信任 schema 内置函数)在恶意构造的数据库文件上可被利用为代码执行入口。对照服务端:PostgreSQL 对 public schema 的默认权限收紧走的是同一条安全演进路线,教训相通——schema 即代码,代码要 Review,运行期不改 schema

常见问题速答

**SQLite 适合存密码吗?**永远不要存明文密码,这一点与所选数据库无关。正确分层:口令本身用应用层的自适应哈希(bcrypt、argon2 这类)处理后入库,SQLite 只存哈希结果;字段加密解决的是"内容保密"而不是"认证"。SQLCipher 或 SEE 加密解决的是另一层——拿到数据库文件的攻击者连哈希都看不到,暴力破解无从下手。三层各司其职:哈希防库内泄露、整库加密防文件窃取、参数绑定防注入拼接。

**只读场景还有哪些防呆手段?**三道闸从软到硬。接口层 SQLITE_OPEN_READONLY 拒绝一切写语句;文件层把库文件设为只读权限,连引擎的写系统调用都会失败;WAL 模式的库不适合设文件只读(写事务的检查点需要碰主文件),只读分发件应先用 TRUNCATE 检查点收尾并切回 DELETE 模式再锁死——随应用分发的参考数据库大多走这条路。

本节要点回顾

  • SQLite 的攻击面在文件与语句,不在网络:防御对象是"拿到文件的人"与"能发语句的代码"。
  • 参数绑定从机制上消灭注入;ATTACH 与动态 SQL 是仅剩的两个语句面出口,用 authorizer 白名单管住。
  • 文件权限即访问控制:主文件与 WAL 伴生文件同权限,只读场景用 READONLY 打开。
  • 加密选 SEE 或 SQLCipher,粒度是整库;trusted_schema 与 defensive 两个开关封住 schema 暗门。

安全收官,最后一节处理部署:从链接到升级的实战清单。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U