mysql如何防止权限越权_mysql权限控制建议

4次阅读

mysql权限越权本质是授权粒度粗,非自身漏洞;关键在最小权限原则、限定库表、禁用all privileges与通配符,并结合mysql.db表、连接参数及中间件路由实现双重控制。

mysql如何防止权限越权_mysql权限控制建议

MySQL 权限越权的本质是授权粒度太粗

越权不是 MySQL 本身有漏洞,而是 GRANT 时用了 ALL PRIVILEGES* 或给错数据库/表名。比如对 test.* 授权却让应用连的是 production 库——只要连接用户没被限制库名,它照样能切过去执行 USE production,再操作数据。

关键判断点:权限是否绑定到具体对象(库、表、列),是否限制了可访问的数据库范围(通过 mysql.userdb 字段或代理层路由)。

用最小权限原则配置用户,别碰 ALL PRIVILEGES

生产环境用户应只拥有其业务逻辑真正需要的权限,且限定在明确的库和表上。

  • GRANT select, INSERT ON myapp.users TO 'app_user'@'10.20.30.%'; —— 比 GRANT ALL ON myapp.* 安全得多
  • 避免通配符滥用:GRANT SELECT ON `order_%`.* 看似方便,但一旦新建 order_backup_2024 库就自动获得权限,容易失控
  • 敏感操作(如 DROPALTERFILESUPER)必须单独审批,不随业务账号下发
  • 应用账号禁用 USAGE 以外的全局权限(即不要给 ON *.* 的任何权限)

限制用户可访问的数据库,靠 db 表 + 连接参数双重控制

仅靠 GRANT 不够,MySQL 允许用户连接后用 USE 切库。要真正隔离,得配合 mysql.db 表和客户端连接参数:

  • 插入记录到 mysql.db 表:INSERT INTO mysql.db (Host, Db, User, Select_priv, Insert_priv) VALUES ('10.20.30.%', 'myapp', 'app_user', 'Y', 'Y');,再 FLUSH PRIVILEGES;
  • 应用连接字符串中显式指定 database=myapp,避免连接后自由切换
  • 若用中间件(如 ProxySQL、MaxScale),在路由规则里硬性绑定用户 → 库映射,比单纯依赖 MySQL 权限更可靠
  • 注意:mysql.db 表不支持通配符库名,Db 字段必须是字面量(如 myapp_v2),不能写 myapp_%

定期审计权限,重点查 SELECTEXECUTE 越界风险

SELECT 权限最容易被忽视——它不改数据,但能拖走全部用户手机号、身份证;EXECUTE 若开放给存储过程,也可能间接调用高权限逻辑。

  • 查越界读权限:SELECT host, user, db FROM mysql.db WHERE db NOT IN ('myapp', 'information_schema') AND user = 'app_user';
  • 查全局权限残留:SELECT user, host, Super_priv, File_priv FROM mysql.user WHERE user = 'app_user';,确认为 N
  • SHOW GRANTS FOR 'app_user'@'10.20.30.%'; 输出结果,人工核对是否含未声明的库或 WITH GRANT OPTION
  • 权限变更必须走版本化 SQL 脚本,禁止直接在生产库 GRANT,否则无法追溯

最常被忽略的一点:MySQL 权限检查是“叠加生效”的,mysql.db 表权限 + mysql.tables_priv 表权限 + mysql.columns_priv 列权限会合并判断。哪怕某张表只开了 SELECT,但如果 mysql.db 里对应库的 Select_privY,那这张表就自动继承——这种隐式继承极易漏审。

text=ZqhQzanResources