限制数据库账户权限是防范SQL注入最基础也最有效的手段之一。即使应用层存在漏洞,低权限账户也能大幅压缩攻击者可操作的空间,比如无法读取系统表、无法写入文件、无法执行命令等。
最小权限原则:只给必需的权限
为每个应用创建独立的数据库用户,避免使用 root 或高权限账号。例如,一个仅需查询用户信息的前端模块,应只授予 SELECT 权限,且仅限于 user_info 表:
CREATE USER 'app_reader'@'%' IDENTIFIED BY 'strong_pass_2024'; GRANT SELECT ON mydb.user_info TO 'app_reader'@'%'; FLUSH PRIVILEGES;禁止授予 FILE、PROCESS、SUPER、SHUTDOWN 等高危权限,除非有明确运维需求并已隔离使用场景。
禁用危险函数与功能
部分MySQL内置函数(如 LOAD_FILE()、INTO OUTFILE、sys_exec())常被注入后用于提权或持久化。可通过配置限制:
在 my.cnf 中设置 secure_file_priv = /var/tmp/,限制文件读写路径,甚至设为 secure_file_priv = "" 彻底禁用(MySQL 8.0+ 支持); 移除 mysql.func 表中非必要自定义函数; 避免安装 lib_mysqludf_sys 等扩展,防止通过UDF执行系统命令。分离数据库角色与连接上下文
不同业务环节使用不同权限账户,例如:
前端展示层 → 只读账户(SELECT); 后台管理接口 → 读写账户(SELECT/INSERT/UPDATE),但禁止 DROP/ALTER/CREATE; 定时任务或ETL脚本 → 单独账户,限定IP + 临时授权 + 自动过期(如用 MySQL Enterprise 的 password expiration 策略)。配合 sql_mode 设置(如启用 STRICT_TRANS_TABLES 和 NO_AUTO_CREATE_USER),可进一步抑制异常语法绕过。
定期审计与权限回收
权限不是一劳永逸的配置。建议每月执行一次权限清理:
查出长期未登录的用户:SELECT user, host, last_password_change FROM mysql.user WHERE last_password_change 检查越权访问痕迹:SELECT * FROM mysql.tables_priv WHERE table_priv LIKE '%Insert%'; 回收测试环境残留权限,尤其注意 '%'@'%' 这类通配主机账户。配合应用日志中的SQL慢查或错误模式,能更快识别异常权限滥用迹象。
