数据库访问控制 漏洞
2019年,数据某头部电商平台的库访安全团队做了一次内部审计。他们发现一个测试环境遗留的问控数据库账号,密码是制漏弱口令,权限却是数据db_owner。这个账号在代码仓库里躺了三年,库访被十几个微服务引用。问控攻击者如果拿到它,制漏能直接拖走用户订单和支付流水。数据问题出在哪?库访不是防火墙,不是问控加密算法,是制漏访问控制本身被绕过了。
数据库访问控制的数据核心逻辑就一句话:谁,能对哪些数据,库访做什么操作。问控听起来简单,落地时到处都是裂缝。最常见的漏洞类型是权限提升。比如一个只读账号,通过调用某个存储过程,间接获得了写权限。SQL Server里有个经典案例:EXECUTE AS子句如果配置不当,低权限用户能模拟高权限用户执行动态SQL。开发人员当时只想着“这个存储过程方便复用”,没意识到它成了提权跳板。
另一种高频漏洞是水平越权。用户A能查用户B的订单,只因为接口把user_id参数直接拼进了SQL,而数据库层没有行级安全策略。MySQL 8.0之前没有原生的行级安全,很多团队靠应用层过滤。应用层一旦有注入点或者逻辑遗漏,数据库就裸奔。我见过一个真实系统,用WHERE user_id = $current_user,但$current_user是从Cookie里取的明文值。改个Cookie就能看别人的数据。数据库那边完全不知情,因为它只认SQL语句。
还有一类容易被忽视的:元数据泄露。攻击者不需要直接读业务表,通过information_schema就能摸清库表结构、字段名、甚至外键关系。很多数据库账号默认能访问information_schema,而运维觉得“这又不是业务数据”。可攻击者拿到表名和字段名后,下一步就是精准注入或撞库。某金融公司的一次渗透测试中,测试人员用低权限账号从information_schema.tables里找到了名为user_credit_card_backup_2021的表,虽然表本身没权限读,但表名已经暴露了备份策略和年份。
访问控制漏洞的根因往往不在数据库本身,而在权限的生命周期管理。账号创建时给了SELECT, INSERT, UPDATE, DELETE,后来业务只读化了,没人回收DELETE。人员离职了,数据库账号还在。微服务拆分后,新服务复用了旧服务的连接串。这些操作层面的疏忽,比CVE漏洞更普遍。Oracle有一个DBA_USERS视图能查所有账号的创建时间和最后登录时间,很多团队从来不查。我见过一个生产库,里面有37个账号,其中12个超过一年没登录,权限却是DBA。
怎么防?别指望单一手段。数据库防火墙能拦SQL注入,但拦不住合法账号的越权查询。审计日志能事后追溯,但事后往往已经晚了。真正有效的做法是最小权限+定期回收+行级控制。PostgreSQL的ROW LEVEL SECURITY策略可以强制每个查询带上租户ID过滤,应用层忘了加WHERE条件,数据库自己会补上。MySQL 8.0也支持了角色和动态权限,别再给GRANT ALL ON *.*了。另外,把information_schema的访问也纳入权限体系,别让低权限账号随便查。
最后说个细节。很多团队用ORM框架,觉得“框架会处理权限”。Hibernate的@Filter或者MyBatis的拦截器确实能加行级过滤,但前提是配置正确。我见过一个项目,@Filter注解写在了实体类上,但Session没有enableFilter,等于没生效。测试环境数据少,没发现;生产环境数据多了,越权查询直接拖垮数据库。访问控制不是配一次就完事的东西,它需要持续验证。每次发版,跑一遍越权测试用例,比写十页安全规范都管用。
(责任编辑:休闲)














