IAM策略无法防范SQL注入,因其仅控制数据库访问权限而不校验用户输入;SQL注入发生在应用层,载荷在HTTP/gRPC/ORM中构造,IAM在连接建立阶段无法解析SQL内容。

单纯靠IAM策略无法防范SQL注入——它管的是“谁可以访问数据库”,而不是“用户输入是否被恶意构造”。SQL注入发生在应用层,攻击载荷在HTTP body、gRPC payload或ORM参数中,根本不会触达IAM鉴权环节。
为什么IAM策略对SQL注入基本无效
常见错误现象:SELECT * FROM users WHERE id = '1' OR '1'='1' 这类拼接SQL在user-service里执行时,IAM只看到一个合法服务账号发来的连接请求,完全不知道里面执行的是什么语句。
- IAM(如AWS IAM、阿里云RAM)作用于网络连接建立阶段,只校验调用方身份和权限范围(例如
ram:ListDatabases),不解析SQL内容 - 微服务直连数据库时,连接复用、连接池、预编译语句让IAM无从判断每次执行的SQL意图
- JWT token若只校验
sub和exp,未检查scope字段(如缺少db:read:users),攻击者可用合法token发起任意查询 - 东西向流量绕过API网关和边缘IAM控制点,Sidecar代理前的SQL载荷已成型
真正起作用的是IAM + JWT scope校验 + SQL语义解析协同
必须把IAM能力下沉到请求上下文里,而不是只用在数据库连接建立时:
- 在Envoy
ext_authz过滤器中解析JWT,并提取scope字段,例如db:read:orders,拒绝不含该scope的请求 - scope需与SQL意图匹配:检测服务解析出
SELECT * FROM orders后,比对JWT中是否有db:read:orders,而非宽泛的db:read - scope不能硬编码在token里,应由API网关或AuthZ服务动态生成,绑定用户角色+资源路径+操作类型
- 高危操作(如
UNION SELECT、子查询嵌套>3层)直接拒绝,不依赖scope——这是SQL语义层的事,IAM不参与
实操中容易忽略的关键约束
很多人以为配好iam:PassRole就安全了,其实关键细节全在边界上:
- scope校验必须在
ext_authz里做,不能只靠数据库驱动层——JDBC/MySQL client不解析JWT - JWT签名密钥必须轮换,且验证时强制检查
kid头,防密钥固定攻击 - scope粒度要细:允许
db:read:users:id,但禁止db:read:users:%这种模糊通配 - 当检测服务超时或不可用时,
allow_if_no_response: true必须开启,否则整个链路会卡死——IAM本身不能成为单点故障
最危险的误区是把IAM当成SQL防火墙用。它解决不了' OR 1=1 --怎么进来的,只管“谁连上了”。SQL注入的载荷在应用出口就已成型,等它到达数据库时,已经晚了。

















