AWS DynamoDB IAM DENY策略拦截特定属性查询条件失效问题
AWS DynamoDB IAM 字段级拦截DENY策略不生效排查
问题根因
当前配置的DENY策略完全不生效是两个核心逻辑错误导致的:
- 条件运算符使用错误:你选用的
ForAllValues:StringEquals判定规则为请求侧传入的所有dynamodb:Attributes值,必须全部属于策略指定的受限字段列表,条件才会成立。如果用户请求同时查询普通字段和受限字段(例如Attributes列表为['user_id', 'restricted_field1']),因为普通字段不在受限列表中,条件判定为不匹配,DENY规则不会触发,用户可以直接越权拿到受限字段。 dynamodb:Select条件存在大面积漏判:你添加的条件强制要求dynamodb:Select必须等于SPECIFIC_ATTRIBUTES才触发拦截,但DynamoDB默认查询场景(未指定返回字段的GetItem、走索引的Query/Scan返回全投影字段)的Select值为ALL_ATTRIBUTES或ALL_PROJECTED_ATTRIBUTES,这些场景会直接返回包含受限字段在内的全量数据,却被你的条件完全排除在拦截范围外。
正确配置方案
DENY规则需要覆盖两类越权场景,只要满足任意一类就直接拦截:
- 请求未明确指定返回特定属性,默认返回全量/索引投影全量字段,必然包含受限内容
- 请求明确指定了返回特定属性,但属性列表中包含任意一个受限字段
对应CDK代码实现如下:
const psAllow = new PolicyStatement({ resources: [tableArn], actions: ['dynamodb:GetItem','dynamodb:BatchGetItem','dynamodb:Query','dynamodb:Scan'], effect: Effect.ALLOW }); // 拦截默认返回全量字段的请求 const psDenyFullScan = new PolicyStatement({ resources: [tableArn], actions: ['dynamodb:GetItem','dynamodb:BatchGetItem','dynamodb:Query', 'dynamodb:Scan'], effect: Effect.DENY }); psDenyFullScan.addCondition('StringNotEquals', { 'dynamodb:Select': 'SPECIFIC_ATTRIBUTES' }); // 拦截指定返回字段但包含受限属性的请求 const psDenyRestrictedAttr = new PolicyStatement({ resources: [tableArn], actions: ['dynamodb:GetItem','dynamodb:BatchGetItem','dynamodb:Query', 'dynamodb:Scan'], effect: Effect.DENY }); psDenyRestrictedAttr.addCondition('StringEquals', { 'dynamodb:Select': 'SPECIFIC_ATTRIBUTES' }); psDenyRestrictedAttr.addCondition('ForAnyValue:StringEquals', { 'dynamodb:Attributes': ['restricted_field1','restricted_field2'] });
配置说明
- 无论调用方使用旧版SDK的
AttributesToGet参数,还是新版SDK的ProjectionExpression参数,AWS都会自动解析最终返回的字段列表填充到dynamodb:Attributes上下文键,不需要额外写条件兼容两种传参方式 - 字段级权限拦截场景不要使用
ForAllValues运算符,该运算符的匹配逻辑天生存在越权漏判风险,涉及多值匹配的拦截逻辑优先使用ForAnyValue - 不要随意给DENY规则添加缩小范围的条件,优先保证所有可能的越权路径被覆盖,避免后续SDK、API参数迭代导致拦截失效
内容的提问来源于stack exchange,提问作者JKK
相关产品推荐
相关产品推荐

