最小权限原则不能阻止sql注入发生,但能严格限制攻击者利用注入账号所能访问的表、字段及操作范围;它依赖列级授权、视图封装、禁用高危权限及修复配置漏洞(如关闭严格模式、public schema可读、密码明文存储)来降低危害。

最小权限原则不能阻止SQL注入发生,但它能决定攻击者注入成功后到底能干成什么事——权限越小,能查的表越少、能读的字段越窄、能执行的操作越受限,甚至根本查不到表名。
SQL注入本质是“借号执行”,不是提权
注入代码最终是以数据库账号身份运行的。如果这个账号只有 SELECT (id, username, email) 权限,那 UNION SELECT @@version, user(), database() 会直接报错或返回空;DROP TABLE logs 或 INSERT INTO users 更是会被拒绝。
常见错误现象:
- 开发以为“防住了拼接就安全了”,结果上线用
root账号连库,一注入就全盘沦陷 - 只配了
GRANT SELECT ON myapp.users TO 'web',没写字段列表,等于把password_hash、phone全敞开
列级授权比表级关键得多
很多团队卡在表级授权就停了,但敏感字段必须单独控制。MySQL 和 PostgreSQL 的列级控制方式不同,容易配错:
- MySQL 必须显式写字段:
GRANT SELECT (id, username) ON myapp.users TO 'web_ro'@'%';不写字段就是全列授权 - PostgreSQL 推荐用视图封装:
CREATE VIEW login_view AS SELECT username, password_hash FROM users WHERE status = 'active' WITH CHECK OPTION,再授SELECT给视图 - SQL Server 要用对象级语法:
GRANT SELECT ON OBJECT::users(username, password_hash) TO app_user,还得确认db_datareader角色没覆盖掉它
三个配置陷阱,踩中一个前功尽弃
权限配得再细,也挡不住这些底层配置漏洞:
- MySQL 关闭严格模式:
sql_mode缺失STRICT_TRANS_TABLES时,SELECT 1,2,3 FROM dual可绕过UNION字段数校验,强行拖出information_schema表名 - PostgreSQL 的
publicschema 默认可读:不执行REVOKE USAGE ON SCHEMA public FROM PUBLIC,攻击者就能跑SELECT table_name FROM information_schema.tables扫库 - 密码明文写在配置文件里:哪怕只剩
SELECT权限,服务器一旦被拿 shell,cat config.yml | grep password就直接连库成功
最小权限不是上线前配一次就完事的事——每次加个报表接口、改个 JOIN 表、新增搜索字段,都要重走一遍权限评审:这个 SQL 真的需要查 syslogins?这个新视图是否意外暴露了基表权限?











