数据库安全这个方向,说难不难,说简单也不简单。我见过太多人复习时一头扎进SQL注入的原理里出不来,结果面试官问到权限管理、审计日志却答得支支吾吾;也见过不少人把备份恢复当成“运维的事”,觉得跟安全没什么关系,结果真出问题的时候连RTO和RPO都说不清楚。我自己早些年备考和带新人时,在这方面踩过的坑、走过的弯路都不少,所以想把这套复习思路整体梳理一遍,从一个相对完整的视角把数据库安全的核心考点、常见攻击面以及防御手段串起来讲清楚。这篇东西既是复习提纲,也是实操笔记,适合正在准备安全方向考试、面试,或者刚入门想系统建立数据库安全知识体系的朋友。
数据库本身是网络安全的“最后一道防线”,因为业务系统可以被攻破、Web服务器可以被拿下,但只要数据库里的数据还是密文、权限还是收紧的、操作日志还在,损失就可控。反过来,如果数据库裸奔,前面的一切防护都形同虚设。我们复习数据库安全,本质上是在回答三个问题:攻击者能从哪些角度碰数据库?我们可以用什么手段挡住这些攻击?万一没挡住,怎么把损失降到最低?把这几个问题拆开,对应的就是认证权限、注入防御、数据加密、审计备份这几大块。
1. 数据库安全的整体认知与复习框架
1.1 为什么数据库安全是安全体系的核心
聊数据库安全之前,先想清楚一个基本事实:几乎所有业务系统的核心资产都躺在数据库里。用户个人信息、订单记录、支付流水、业务配置,这些东西一旦被拖库或者篡改,不光是经济损失的问题,还会直接上升到合规风险。安全圈常说的“数据就是黄金”,放到数据库这个场景里再贴切不过。
从攻击者的视角看,数据库通常意味着“高价值目标”。Web服务器被打下来可能只是拿到一个shell,但数据库被拿下来往往意味着拿到了全部。所以渗透测试里有个常见的优先级判断:先找数据库连接信息,再决定要不要继续深入。很多系统攻防演练中,攻击者通过SQL注入拿到数据库权限之后,直接就是最高权限的接管。防守方如果只盯着Web层面的WAF和防火墙,忽略了数据库本身的防护能力,基本等于开着大门让别人搬黄金。
从合规角度讲,近年来数据安全法、个人信息保护法这些法律法规陆续落地,对数据库的访问控制、审计、加密都提出了明确要求。等保测评里,数据库安全也是必测项,身份鉴别、访问控制、安全审计、入侵防范、数据完整性、数据保密性这几条,几乎每一个都和数据库强相关。所以不管是为了应付考试,还是为了应对真实的合规检查,把数据库安全这块吃透都是刚需。
1.2 复习路线的四个维度
复习数据库安全,我习惯把它拆成四个维度,对应一个数据“从进到出”的完整生命周期。
第一是入口维度:数据库怎么识别和校验来访问的人。这就是身份认证和权限管理,要搞清楚有哪些认证方式、每种方式的强度如何、权限模型怎么设计、最小权限原则怎么落地。
第二是传输与请求维度:数据在网络上传输、以及应用程序向数据库发起请求的过程中,可能会被截获、篡改、或者注入恶意构造的查询。这块的核心是SQL注入的攻防,以及传输加密怎么做。
第三是存储维度:数据落盘之后,如果磁盘被偷了、备份文件被拷走了,数据本身是否安全。这就是静态加密和脱敏的范畴。
第四是事后维度:如果前面都没防住,或者发生了误操作、物理故障,怎么快速发现问题、定位原因、恢复数据。这就是审计日志和备份恢复。
这四条线看起来各自独立,实际上层层递进。复习时最好顺着这个维度走,而不是零散地背知识点。我自己复习时是画了一张表,把每个维度的常见考点、常见工具、常见绕过手段列出来,然后逐个章节深入,这样到后期做综合题的时候,思路会清晰很多。
1.3 复习中常见的三个误区
先泼几盆冷水,这几个坑我基本都踩过,也见过不少同行踩。
第一个误区是重攻击轻防御。很多人一提到数据库安全,第一反应就是SQL注入怎么打、怎么绕过WAF,但真问到参数化查询为什么能防注入,却答不出本质。攻击视角当然要有,但防御视角更关键,尤其是“为什么这个防御手段有效、它挡住了哪一环”这类问题,面试官和考试都特别爱考。
第二个误区是重单点轻全局。只盯着某一个数据库产品(比如某一种关系型数据库)的安全配置,却没有形成跨产品的通用方法论。实际上,不同数据库的认证方式、权限模型、备份策略差异很大,但安全目标是一致的。复习时应当先建立通用框架,再落到具体产品上验证。
第三个误区是重理论轻实操。数据库安全有不少东西光看文档是记不住的。比如权限回收时要注意什么、审计日志会不会把自己锁在外面、备份恢复演练时常见的坑,这些只有实际在环境里操作过、踩过雷,才能形成真正的条件反射。备考阶段一定要给自己搭一套实验环境,哪怕是最简单的本机部署,也比纯看书记得牢。
2. 身份认证与权限管理:数据库的第一道防线
2.1 认证机制的核心逻辑与分类
身份认证是一切访问控制的起点。数据库认证要解决的核心问题是:当前连接的人或程序,到底有没有资格访问这个数据库实例。
常见的认证方式大概有三种。
第一种是口令认证,也就是用户名加密码。这是最基础的方式,几乎所有数据库产品都支持。口令认证的安全性完全取决于口令本身的强度和存储方式。很多人忽略的一点是,数据库用户的密码可能会以哈希形式存储在某些系统表中,如果数据库被注入或者文件被读取,密码哈希就可能泄露出来。如果哈希算法太弱(比如一些老版本数据库还在用可逆加密或者弱哈希),攻击者很容易离线破解。所以复习时至少要清楚一点:生产环境不允许使用空密码、不允许所有账号共用同一个密码、密码要定期轮换,这些不是“建议”,而是底线。
第二种是操作系统认证。某些数据库允许数据库账号和操作系统账号绑定,登录操作系统后可以直接以对应数据库身份访问,不用再输密码。这种方式的好处是运维方便,坏处是它把安全边界转移到了操作系统侧。如果操作系统的账号被劫持,数据库就等于敞开大门。所以生产环境一般会搭配严格的系统账号管理,并且限制这种认证方式的使用范围。
第三种是多因素认证和证书认证。这是目前越来越主流的做法,特别是在核心生产库上。通过数字证书、动态令牌等方式,在口令之外再加一层验证。证书认证的原理是客户端持有私钥、服务端持有公钥,握手时通过签名验证身份。这种方式的抗钓鱼、抗撞库能力强很多,但部署和维护成本也高,复习时理解原理比死记步骤更划算。
2.2 权限模型:最小权限原则的落地方式
认证通过之后,考验的就是权限管理。数据库的权限模型大体上可以理解为“用户-角色-权限”三层结构。直接给用户授权不是不可以,但用户多了之后会非常混乱,不好维护。合理的方式是:创建角色,给角色授权,把用户挂到角色下。这样权限调整只需要动角色,不需要一个个用户去改。
最小权限原则听上去很简单——只给完成工作所必需的权限——但实际落地时经常出问题。我见过不少系统,应用程序连接数据库直接用管理员账号或者拥有全部权限的高权限账号,一台应用服务器被攻破之后,攻击者直接就拿到了数据库全部数据的读取和写入能力。正确做法是给应用账号只开通业务库的增删改查权限,并且限制只能从应用服务器的IP连接(如果数据库支持这类访问限制的话),尽量不给DDL权限。
复习时可以用下面这张表格来梳理常见权限项和推荐策略:
| 权限层级 | 常见权限项举例 | 生产环境推荐策略 |
|---|---|---|
| 实例级 | 创建数据库、管理用户、关闭实例 | 仅数据库管理员持有,绝不给应用账号 |
| 库级 | 建表、修改表结构、备份库 | 按业务团队拆分,不跨库共享 |
| 表级 | 查询、插入、更新、删除 | 应用账号只开业务表的DML权限(必要时仅SELECT) |
| 列级 | 查询特定敏感列 | 敏感列单独授权,非必要不开放 |
| 存储过程级 | 执行特定存储过程 | 优先通过存储过程封装数据访问,而不是直连表 |
2.3 实操配置示例与权限复盘
权限管理的复习不能光背概念,最好自己动手配一遍。以我常用的数据库为例(不同产品大同小异,重点是思路),可以从创建角色、授权、建用户、绑角色四步走。
第一步,创建只读角色,比如专门跑报表的账号就只要读权限:
CREATE ROLE read_only_role; GRANT SELECT ON business_db.* TO read_only_role;第二步,创建应用读写账号,只允许从固定主机连接:
CREATE USER 'app_user'@'10.0.0.5' IDENTIFIED BY '强密码策略生成的口令'; GRANT SELECT, INSERT, UPDATE, DELETE ON business_db.order_table TO 'app_user'@'10.0.0.5'; GRANT EXECUTE ON business_db.proc_daily_stat TO 'app_user'@'10.0.0.5';第三步,管理员账号不直接给业务使用,单独建高权限账号并开启多因素认证,同时定期做权限复盘:
-- 定期执行的权限盘点语句(示例) SELECT user, host, Grant_priv, Super_priv, Create_user_priv FROM mysql.user WHERE user NOT LIKE 'mysql.%';有两点特别注意。第一,授权语句中的主机范围不要写得太宽,能用具体内网IP就不写网段,能写网段就不写“所有主机”。第二,权限回收时记得让权限立即生效,不同数据库生效的方式不一样,有些需要执行刷新命令,有些是动态生效,复习时可以对比一下各自的差异。
3. SQL注入攻防:从原理到落地防御
3.1 注入的本质就是“拼接出歧义”
SQL注入为什么这么经典?因为它直接利用了SQL语言本身的“代码与数据边界模糊”问题。当应用程序把用户输入直接拼接到SQL语句中时,用户输入的一部分会被解析为SQL代码,而不是纯粹的数据。
看过一个特别形象的类比:如果把SQL语句比作一句话,参数就是话里的“引号内容”。正常情况下,“他说:你好”,这里的“你好”是内容;但如果不做处理,直接在完整句子里拼接,用户输入里包含一个“后引号加上一句自己的话再补一个前引号”,整句话的意思就被改写了。用户输入“你好”并不可怕,可怕的是用户输入“你好”后面紧跟着“;删除全表”这样的内容——句子意思彻底变了。
以最经典的登录绕过举例。假设后端代码如下:
String sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";正常情况下输入用户名为alice、密码为123456,SQL就是:
SELECT * FROM users WHERE username = 'alice' AND password = '123456'如果攻击者输入用户名admin' --,密码随意填,SQL就变成了:
SELECT * FROM users WHERE username = 'admin' -- ' AND password = 'whatever'注释符号把后面的密码校验整个注释掉了,这条语句只要admin用户存在,就直接返回该记录。攻击者根本不需要知道密码。
3.2 注入类型与服务端返回差异
复习的时候,SQL注入一定不止一种形式。按数据获取方式分,常见有这么几类。
联合查询注入:通过UNION SELECT把额外数据拼到原查询的结果集里。这类注入的前提是页面能看到查询结果。攻击者会先猜原查询的列数,然后逐列试探哪个字段能回显。经典步骤是ORDER BY n试探列数,再用UNION SELECT构造回显位置。
报错注入:当页面不回显查询结果、但会把数据库报错信息显示出来时,攻击者可以利用报错输出中携带的数据。比如通过UPDATE相关的函数或语法特性,让数据库报错信息里包含子查询结果。
布尔盲注:页面不回显具体数据,但会根据查询结果是真还是假返回不同表现(比如“登录成功”“登录失败”),攻击者通过逐字符拆解的方式,构造条件判断语句去猜数据。
时间盲注:页面什么表现都没有,唯一可用的“侧信道”是数据库执行时延。攻击者用SLEEP这类函数构造条件判断,如果条件成立就延迟返回,通过观察响应时间来判断字符。
复习时最好把这些类型放在一张表里对比,重点关注“页面表现差异”和“检测关键词特征”,做题和实战时能快速定位注入类型:
| 注入类型 | 前提条件 | 核心特征 | 常用检测载荷示例 |
|---|---|---|---|
| 联合查询 | 结果集可见 | 能通过UNION扩充结果 | ' UNION SELECT 1,2,3-- |
| 报错注入 | 报错信息可见 | 数据库错误信息携带数据 | ' AND updatexml(1,concat(0x7e,user()),1)-- |
| 布尔盲注 | 真/假响应不同 | 页面表现变化 | ' AND (SELECT 'a' = 'a')-- |
| 时间盲注 | 无任何直接回显 | 延迟响应 | ' AND IF(1=1,SLEEP(3),0)-- |
3.3 防御方案的本质与选型逻辑
注入的防御方案五花八门,但万变不离其宗:让数据库分辨不出代码和数据,或者让攻击者构造的输入无法成为SQL语法的一部分。
第一优先的方案是参数化查询(预编译)。它的原理是先把SQL语句骨架发给数据库完成语法解析和编译,之后再用参数把数据代入执行。因为语句结构已经固定,输入再怎么构造也只是“参数值”,永远不可能变成SQL关键字或语法符号。以JDBC的PreparedStatement为例:
String sql = "SELECT * FROM users WHERE username = ? AND password = ?"; PreparedStatement ps = connection.prepareStatement(sql); ps.setString(1, username); ps.setString(2, password); ResultSet rs = ps.executeQuery();这里?是占位符,username和password无论传什么进来,都只被当作字符串值处理。这套方案几乎能阻断绝大部分传统注入。
第二是输入验证与过滤。这块要注意,它的作用是“加固”,不是“根治”。比如对整数类型参数做类型强转,使用白名单校验接收的参数值范围。但应对字符型参数时,纯粹的关键字过滤(比如把selectunion替换掉)很容易被变种绕过——大小写混写、注释符号插入、URL编码、二次编码等,绕过手法多到数不清。所以复习时一定不要以为“过滤了关键字就安全了”,只能把它当深度防御的一层。
第三是ORM框架的正确使用。很多项目现在用ORM框架操作数据库。ORM如果实现底层用的是参数化或者转义机制,本身是安全的,但有一个大坑:如果开发者在ORM里用拼接语句或原生查询接口,还是可能注入。比如某些框架的“原生SQL查询”接口,传入字符串拼接后执行,就完全绕开了ORM的防护。所以选型时要看框架底层逻辑,同时要有代码规范约束“不允许拼接SQL”。
3.4 实战排查中的几个关键细节
在真实系统里排查SQL注入风险,我会按顺序做三件事。
先全局搜代码中的SQL拼接点。正则搜+和String拼接SQL的代码,重点关注登录、查询列表、排序字段、报表统计这几个环节。排序字段特别容易出问题,表面上是ORDER BY后面拼列名,实际上很多系统直接拼接用户输入还不做过滤,这在某些数据库上是能构成注入的。
再审查数据库账号权限。就算代码里真的存在拼接点,如果数据库账号是按最小权限给的,注入能造成的破坏也会小很多。比如只读账号只能SELECT,即使注入成功也没法写文件、调存储过程、访问其他业务库。
最后测一遍WAF和数据库防火墙的规则覆盖情况。WAF能在网络层拦截一批攻击特征,但要注意两点:一是规则覆盖面,老规则可能挡不住变种;二是性能开销,开太多规则可能导致正常请求都被误杀。数据库防火墙的方案通常部署在应用和数据库之间,能识别SQL语法层的异常,这类方案比网络层WAF更接近数据库核心,但误报率也可能偏高,需要业务方配合收敛。
4. 数据加密与脱敏:让数据本身变得安全
4.1 存储加密:从文件到列的层层设防
数据躺在数据库文件里,如果攻击者拿到了物理磁盘、备份文件或者数据库文件的复制品,而没有密钥,那这些数据应该是不可读的,这就是存储加密的核心目标。
常见的实现方式有两种。一种是透明数据加密(TDE),数据库在将数据页写入磁盘之前自动加密,读取时自动解密,应用无感知。TDE的好处是对上层业务完全透明,不需要改表结构、不需要改代码;缺点是它只保护“静态数据”,一旦数据被查询出来,返回给应用层的内容是明文。所以TDE解决的是“磁盘被偷”“备份被盗”这类问题,解决不了“查询结果被截获”的问题。
另一种是列级加密,只对敏感字段(比如身份证号、手机号、银行卡号)单独加密。应用层负责加密和解密,数据库存的是密文。这种方式更灵活,敏感字段在数据库内部都是密文,就算SQL注入拿到整表数据,看到的也是一堆无意义字符。代价是查询能力受限——密文没法直接做模糊查询、范围查询、排序,需要额外的索引方案(比如支持密文检索的专用方案),而且密钥管理、加解密性能开销都要规划。
选哪种方案取决于数据场景。全库加密、对性能损耗敏感的选择TDE;核心敏感字段、需要做到“数据库内部不可读”的选择列级加密。两条路也可以结合,目前主流的核心库很多都是“TDE打底+关键列加密兜底”,双保险。
4.2 传输加密:别让数据在网络上裸奔
另一条容易被忽略的线是网络传输。客户端和数据库之间的通信,如果不做加密,攻击者在网络层抓包就能看到明文SQL语句和查询结果。这在生产环境尤其是跨网段、跨机房传输时,是非常严重的安全隐患。
解决方案很明确:启用数据库的TLS/SSL传输加密。启用之后,客户端和服务端之间建立加密通道,握手之后的数据全部加密封装,抓包只能看到一堆乱码。部署时要注意几点:证书链的配置要完整,客户端要信任服务端的CA证书;启用后要测试性能损耗,加密握手和加解密会带来额外CPU开销,特别是在高并发场景;另外,建议关闭不加密的旧协议回退选项,否则客户端可能被降级回落到明文连接,前面的加密等于白做。
4.3 脱敏:用于开发与测试环境的必备手段
生产数据不能直接导到开发测试环境,因为环境和人员都不受控。数据脱敏就是在这个场景下做的一层保护。
脱敏不是简单把字段置空,而是要保持数据格式和业务关联不变,但抹掉真实语义。比如手机号保留前三位后两位,其余打星号或随机替换;身份证号保留区划代码,出生日期和顺序码随机化;姓名做成随机姓氏+随机名字组合。关键要求是:脱敏后的数据仍然能支撑功能开发和测试,比如格式校验能过、关联查询能连得上。
实操中有一个常见问题:脱敏逻辑和真实业务逻辑放一起,有时候会误伤数据。比如某个字段是唯一索引,简单随机替换可能会产生重复值,导致测试环境插入报错。所以脱敏策略要考虑字段的业务特征,不能一刀切。
4.4 密钥管理:加密方案里最容易翻车的环节
加密方案真正翻车的往往不是算法,而是密钥管理。密钥要存在哪、多久轮换一次、谁有权访问、泄露了怎么处置,这些问题比算法选型重要得多。
常见的不良习惯包括:把数据库加密密钥写死在配置文件里;密钥和数据库备份存在同一台机器上;密钥长期不轮换;多个系统共享同一把密钥。这些问题一旦出现,攻击者拿到备份的同时就拿到了密钥,加密等于形同虚设。
正确的做法是用独立的密钥管理系统或硬件安全模块(HSM)来托管密钥,应用只持有访问密钥的授权凭证,而不是密钥本身。密钥轮换要自动化或至少做到可编排,轮换时要保证业务连续性。复习时可以记住一个原则:加密系统的安全性不在算法,在密钥生命周期管理。
5. 审计、备份与故障恢复:安全体系的兜底方案
5.1 审计日志:记录比“防住”更重要的事
数据库做得再安全,也不能100%保证不被人突破。审计日志的作用就是被突破之后还能还原全过程:谁在什么时间从哪个IP用哪个账号执行了什么SQL,影响到了哪些数据。
复习审计时,要抓住几个要点。
第一,审计范围要覆盖关键动作,包括登录成功与失败、权限变更、表结构变更、敏感数据表的访问与修改。一个常见的坑是审计只开了登录日志,查询和修改操作全部没记录,出事之后根本还原不了。
第二,审计日志本身要防篡改。如果攻击者进了数据库之后顺手把审计日志也删了,那审计等于没有。所以生产环境通常会把审计日志实时传输到独立的日志服务器或者安全运营平台,数据库本地只做临时缓存。这么设计的原因是攻击者拿到数据库权限后,可能也会拿到服务器本地文件权限,把日志清掉很容易。
第三,审计日志不能只存不管。定期复盘、设置告警规则,比如同一账号短时间大量失败登录触发告警,敏感表的异常导出操作触发告警。没有告警的审计日志只是死数据。
5.2 备份策略:从全量、增量到恢复目标
备份这件事听起来是运维干的活,但安全场景里它的作用完全值得拿出来单独复习。勒索病毒加密数据库、人为误删除数据、机房故障导致数据库文件损坏,这几类高概率事故,最后都只能靠备份来兜底。
备份的常识要理清楚。全量备份就是整个数据库的完整副本,备份数据量最大、耗时最长,但恢复最简单;增量备份只备份从上一次备份以来变化的数据,备份速度快、占用空间小,但恢复时依赖备份链完整,中间一环损坏就可能导致数据不一致;差异备份备份自上次全量备份以来所有变化的数据,恢复时只需要全量+最近一次差异,比增量恢复简单,但备份文件会随时间越来越大。
恢复指标也要掌握。RPO(恢复点目标)是业务能容忍的最大数据丢失量,比如RPO为15分钟,意味着最多接受15分钟数据丢失,那备份频率至少要达到15分钟一次。RTO(恢复时间目标)是业务能容忍的最大停机时间,比如RTO为4小时,那从灾难发生到数据库恢复可用必须在4小时内完成。这两个指标决定了备份策略的设计,复习时经常考,也是实际方案设计里最需要扣的。
5.3 备份恢复演练:不演练的备份等于没有备份
我见过最经典的“事故后翻车”场景是这样:某系统一直有定时备份任务,大家也都知道有备份,但从来没真正演练过恢复。真到磁盘损坏那天,运维把备份文件拉起来才发现,备份文件本身已经损坏,或者备份命令在三个月前某个配置变更之后就不再正常写入新数据了,只是监控没发现。结果数据和备份全没了。
所以备份恢复验证必须是周期性的常规工作,不是等出了事才想起来。
验证时至少要做三步:第一步,从备份文件恢复到一个独立的测试实例,确认实例能正常启动、数据能正常加载;第二步,对比恢复出来的数据与原业务关键指标,确认数据完整性和一致性;第三步,做一次完整的主从切换演练(如果是主从架构),确认应用层的连接切换能自动或半自动完成,而不是依赖手工切IP。
5.4 安全基线配置:把配置规范变成习惯
除了上述方案,数据库的安全基线配置也是复习中相当重要的一块。安全基线是“默认安全”的配置集合,包括密码复杂度策略、连接数限制、超时设置、远程访问限制等。
密码复杂度策略很容易理解。数据库口令至少要满足长度不少于一定位数(比如12位以上)、同时包含大小写字母数字和特殊字符、不能包含用户名和常见弱口令。更重要的是,配置了复杂度策略之后,要检查存量用户是否仍然存在弱口令,只对新用户生效并不能解决历史遗留问题。
连接数限制的意义在于防止资源耗尽型攻击。如果数据库不限制最大连接数,攻击者只要构造大量并发连接,就能把数据库的连接池占满,正常的业务请求全部无法连上数据库,形成拒服务效果。历史上不少业务故障就是这类攻击引起的。
超时设置的作用是回收空闲连接。很多数据库默认允许空闲连接长时间保持,如果应用侧出故障导致连接不释放,连接数就会慢慢涨爆。合理的超时设置能主动回收这些僵尸连接,降低资源耗尽的风险。
5.5 应急响应与溯源思路
最后说说应急响应的思路。假设数据库已经被入侵,正确顺序是:先隔离,再取证,最后恢复。
隔离阶段的目标是切断攻击者的进一步访问,比如断开数据库的对外网络、暂停应用连接,避免数据持续泄露或被加密破坏。很多初学者在这个阶段容易犯一个错误:直接kill掉数据库进程,导致内存里的数据丢失,还破坏了审计线索。正确做法是在条件允许的情况下先保留现场,再断开网络。
取证阶段要保留原始状态下的日志、进程信息、网络连接记录、文件时间戳。把数据库文件复制一份作为只读备份,所有操作都在副本上进行,防止破坏原始证据。
恢复阶段才轮到修复漏洞、替换口令、改权限配置,然后从备份恢复数据,恢复到干净状态之后重新上线,并且复盘整个入侵路径是不是真的封堵了。如果漏洞没修复就匆匆上线,大概率会被同一个攻击方式再次打穿。
6. 高频考点速查与复习心得
6.1 高频考题/考点速查表
把常见的考试和面试问题整理成一张速查表,复习时可以对着自测:
| 方向 | 常见问题 | 答题要点 |
|---|---|---|
| 认证 | 数据库有哪些认证方式? | 口令、操作系统认证、证书、多因素,区分核心目标和适用场景 |
| 权限 | 最小权限原则怎么落地? | 角色化授权、应用账号不持DDL、限制来源IP、敏感列单独授权 |
| 注入 | 参数化查询为什么能防注入? | SQL结构预编译,输入变成数据而不是代码,语法解析阶段已固定 |
| 注入 | 过滤关键字为什么不可靠? | 变种绕过太多,注释、编码、大小写、二次拼接都能绕 |
| 加密 | TDE和列级加密怎么选? | TDE保护静态文件,列级保护库内数据,按敏感度和性能损耗取舍 |
| 传输 | 数据库传输加密解决什么问题? | 防网络抓包、防中间人,TLS/SSL的配置链路要完整 |
| 审计 | 审计日志为什么需要外送? | 防止攻击者拿到库权限后同时清掉本机日志,独立存储才能溯源 |
| 备份 | RPO和RTO的关系怎么理解? | RPO定丢失上限,RTO定停机上限,两者共同决定备份频率和恢复方案 |
| 应急 | 数据库被入侵先做什么? | 隔离、取证、修复、恢复,顺序颠倒会导致证据破坏或二次入侵 |
6.2 复习阶段的实操建议
复习数据库安全,光靠刷题和看文档效果有限,动手搭建一套试验环境远比“看十篇攻略”有用。做法很简单:在一台本机虚拟机里部署一个数据库实例,按下面几项任务逐一实操一遍,基本就形成了肌肉记忆。
任务一:配置密码策略、创建角色和用户、分配最小权限、验证越权访问被拒绝。
任务二:用原生SQL拼接写一个最简单的登录查询,手工构造攻击载荷验证绕过,再改成参数化查询,确认相同载荷无法生效。这一正一反的对比是最直观的“防御为什么有效”的教学过程。
任务三:开启审计,执行几条增删改查语句,查看审计记录内容,再试着删除审计日志,观察权限是否能阻止、日志外送是否来得及。通过这些操作理解日志保护的必要性。
任务四:做一次全量备份,随便改几条数据造成“误操作”,然后从备份恢复,确认数据回到备份点。有条件的再做一次增量备份恢复演练。
这一套任务走下来,比单纯背十页笔记都管用。我自己带人时经常说一句:数据库安全不是看会的,是练会的。考试和面试里很多“为什么”的问题,只有实际踩过坑、动手验证过,才能答出自己的理解,而不是背别人总结的答案。
6.3 一些值得记在心里的实操心得
最后分享几个我在实际操作中积累的细节经验。
第一,数据库配置项改了之后一定要做回归验证。有一次我调了审计策略,把某类操作从审计列表里去掉,结果业务方反馈某个功能突然变慢,排查半天发现是审计配置影响了执行计划的缓存。配置安全功能不能影响业务正常路径,每次变更都要跑一遍核心链路。
第二,所有敏感操作尽量走存储过程。存储过程天然把SQL语句固化在数据库内部,应用侧只传参数,既利于权限控制和管理,又比应用侧拼接SQL安全得多。我在一些核心系统上见过这个设计,效果确实扎实。
第三,日志切分和归档要提前规划。审计日志增长很快,如果不做按天或按大小自动切分,日志文件会越来越大,影响数据库性能,同时也会让历史日志的检索变成灾难。归档策略要在安全配置时就一并设计好,别等日志把磁盘撑爆了再想办法。
第四,不要轻视“弱口令扫描”这种最基础的检查方式。很多看似安全的系统,最后是被最简单的弱口令打穿的。安全建设是木桶效应,数据库口令是桶底,桶底漏了,桶壁再高也没用。