7.1 门口保安:权限体系与SQL注入防御


7.1 门口保安:权限体系与 SQL 注入防御

本节摘要:安全的第一层是权限最小化,第二层是杜绝 SQL 注入,第三层是网络与密码策略。本节给出可落地的权限模板、参数化查询示范与审计思路。

权限模板:三个角色覆盖大多数团队

-- 应用账号:只对业务库的表有 DML 权限 CREATE USER 'app'@'10.0.1.%' IDENTIFIED BY '强随机密码'; GRANT SELECT, INSERT, UPDATE, DELETE ON clinic.* TO 'app'@'10.0.1.%'; -- 值班账号:可看所有库,可杀连接,不能改数据 GRANT SELECT ON *.* TO 'oncall'@'10.0.1.%'; GRANT PROCESS ON *.* TO 'oncall'@'10.0.1.%'; -- DBA:全权,但限制来源网段 GRANT ALL ON *.* TO 'dba'@'10.0.0.%' WITH GRANT OPTION;

配套的密码与登录卫生:密码策略开启 validate_password;host 限内网网段而不是 %;离职第一件事收号。

SQL 注入:一次事故还原

用户登录框拼出来的 SQL:

-- 应用层拼接:"... WHERE user_name = '" + input + "'" -- 输入 admin' -- 后实际执行: SELECT * FROM clinic_user WHERE user_name = 'admin' --' AND pass='...'; -- 后半句被注释,密码校验直接消失

处方是参数化查询,任何语言驱动都支持:

cursor.execute( "SELECT user_id FROM clinic_user WHERE user_name = %s AND pass_hash = %s", (name, pwd_hash) )

动态表名、排序列这类无法参数化的位置,用白名单映射,绝不拼接用户输入。

网络与审计

[mysqld] bind-address = 10.0.0.5 # 只在内网口监听 require_secure_transport = ON

审计层面,通用查询日志太重,生产上通常只开慢查询日志加连接审计;合规要求高的场景再上企业版审计插件或通用审计插件。

图:纵深防御四道门

图:纵深防御四道门

注入的变种图谱

字符串拼接只是注入的入门款,完整的变种图谱值得巡一遍。第二种是数字注入:WHERE id = 这个数字位置没有引号,攻击者不用闭合引号,直接拼 UNION 拖库。第三种是 LIKE 注入:拼接的搜索框里塞进通配符,轻则把索引打失效,重则配合时间函数做盲注探测。第四种是 ORDER BY 注入:排序列拼接用户输入,这是参数化救不了的位置——列名不能当参数传,必须白名单:

# 排序列白名单映射,用户输入永远只是字典的键 SORTABLE = {"created": "created_at", "amount": "amount", "id": "order_id"} order_col = SORTABLE.get(request_sort, "order_id") cursor.execute(f"SELECT * FROM clinic_order ORDER BY {order_col} LIMIT 20")

白名单的本质是:用户输入只能从有限的候选里选,不能进入代码层。这条原则适用于一切"拼接不可避免"的位置。

一份安全巡检清单

把本节内容收敛成季度巡检清单,逐条打勾。账号:是否存在无密码账号、host 为百分号的账号、九十天未登录的账号、拥有 GRANT OPTION 的非 DBA 账号。密码:validate_password 是否开启、应用配置里的密码是否轮换过。网络:3306 是否暴露在公网(一条端口扫描即可确认)、是否强制加密传输。语句:抽查应用代码里是否还有字符串拼接 SQL、ORM 的原生查询接口有没有被滥用。日志:慢日志与错误日志的访问权限是否最小化——日志里常有敏感数据。清单不长,二十分钟过完一遍,堵住的是九成被拖库团队事后懊悔的那几扇门。

-- 账号体检三连:空密码、任意主机、超权限 SELECT user, host, authentication_string='' AS empty_pwd FROM mysql.user WHERE host='%'; SELECT user, host FROM mysql.user WHERE Grant_priv='Y';

巡检发现的每个问题都记进台账,整改期限与责任人写清楚。安全这件事没有"完成时",只有"最近一次巡检"。

加密与脱敏的最后一层

纵深防御的最内层是数据本身。静态加密:透明数据加密在 8.0 已内置,密钥管理配好即可让磁盘文件整卷加密,防的是"磁盘被拔走"这种物理层事故。传输加密:require_secure_transport 加证书体系,防的是内网嗅探。字段级脱敏:手机号、身份证在报表与测试环境里的展示脱敏,可以在应用层做,也可以用视图直接内置脱敏逻辑,给分析人员只授权脱敏视图:

CREATE VIEW v_user_masked AS SELECT user_id, CONCAT(LEFT(phone,3), '****', RIGHT(phone,4)) AS phone_masked, created_at FROM clinic_user; GRANT SELECT ON clinic.v_user_masked TO 'analyst'@'%';

三层加密脱敏的思想与权限体系同构:假设外层每一道都可能被突破,内层仍要有兜底。安全预算永远有限时,优先补的是"被突破后损失最小"的那层。

收个真实感的尾巴:安全工作最难的不是技术是坚持。权限台账三个月没人更新就开始腐烂,巡检清单跑两周就有人开始跳步,注入扫描在三次全绿后被移出发布流程。防疫科的对抗性恰恰在这里——攻击者只需要成功一次,防御者需要每次都成功。把本章的清单接进自动化:账号体检写成定时脚本输出到巡检群,代码扫描做成发布流水线的卡点,权限变更强制走带审批的工单。用人盯安全,安全一定会输给遗忘;用系统盯安全,才有人能下班。

本节要点回顾

  • 三角色权限模板:应用、值班、DBA 各就各位
  • 注入防线只有一条:参数化查询,动态部分用白名单
  • 纵深防御:网络、账号、语句、审计四道门层层设卡

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