MySQL中创建只读应用账号并限制到单表需先建用户、显式授予列级SELECT权限、撤销全局授权,并验证无宽泛授权。

用低权限账号连接数据库,是SQL注入发生后最实在的止损手段——哪怕代码里漏了预处理,攻击者也只拿到一把锈钥匙,打不开保险柜。
MySQL中如何创建只读应用账号并限制到单表
关键不是“能不能查”,而是“只能查哪张表的哪些字段”。全局SELECT权限等于把整栋楼的门禁卡都交出去。
- 先建用户:
CREATE USER 'web_ro'@'192.168.10.%' IDENTIFIED BY 'p4ss_R3ad0nly_2026'; - 只授单表
SELECT:GRANT SELECT (id, username, email) ON myapp.users TO 'web_ro'@'192.168.10.%';(注意:列级授权需显式列出字段) - 禁止跨库访问:
REVOKE SELECT ON *.* FROM 'web_ro'@'192.168.10.%';(避免隐式继承) - 验证是否生效:
SHOW GRANTS FOR 'web_ro'@'192.168.10.%';,确认输出里没有ON *.*或myapp.*这种宽泛授权
SQL Server里禁用xp_cmdshell为什么不能防注入
禁用xp_cmdshell只是拆掉一把梯子,但攻击者早从正门进来了。注入成功后第一件事不是提权,而是拖库——而拖库只需要SELECT权限。
-
xp_cmdshell只影响“执行系统命令”这一条路径,对UNION SELECT @@version--、AND 1=(SELECT COUNT(*) FROM master..syslogins)完全无效 - 真正起作用的是账号角色:
DENY CONTROL SERVER TO app_user;、ALTER ROLE db_datareader ADD MEMBER app_user;(仅读角色) - 常见翻车点:误以为
db_datareader安全,却忘了它默认能查master、msdb等系统库——必须显式DENY SELECT ON SCHEMA::sys TO app_user;
PostgreSQL中用视图封装+权限隔离的实际效果
视图不是防火墙,是数据过滤网。它不阻止注入语法生效,但能让注入结果“查无可查”。
- 建视图时加
CHECK OPTION防止绕过条件:CREATE VIEW public.active_users AS SELECT id, name FROM users WHERE status = 'active' WITH CHECK OPTION; - 撤掉基表权限后,
INSERT INTO active_users会失败,但SELECT * FROM active_users WHERE id = 123 OR 1=1仍可执行——只是返回的永远是status='active'的数据 - 陷阱:若视图定义里调用了
SECURITY DEFINER函数,且该函数有pg_read_all_data角色,整个视图就变成高危通道 - 验证权限链:
\z public.active_users(查看视图ACL),再SELECT relacl FROM pg_class WHERE relname = 'active_users';
最小权限不是配一次就完事的事。应用迭代时新增的查询语句,往往悄悄要求了新表权限;而测试环境残留的'%'@'%'账号,可能让生产库暴露在内网扫描之下。权限回收要像清理日志一样定期做,而不是等审计报告出来才动手。

















