GraphQL安全挑战
GraphQL的灵活查询能力是双刃剑。客户端可以构造任意复杂的查询,导致独特的安全风险:深度嵌套查询(DoS)、过度数据暴露、批量查询滥用、introspection信息泄露。
查询复杂度限制
深度限制
限制查询嵌套层数(建议最大7层)。使用graphql-depth-limit库在解析阶段拦截过深查询。
复杂度分析
为每个字段分配复杂度分数,计算总复杂度不超过阈值。列表字段乘以预估数量。使用graphql-query-complexity库实现。
查询白名单
生产环境禁用任意查询,只允许预注册的Persisted Queries。客户端发送查询哈希而非完整查询文本。Apollo Server和Relay均支持此模式。
认证与授权
字段级权限
不同角色看到不同字段。使用GraphQL Directives实现声明式权限控制。管理员可查看所有字段,普通用户只能查看公开字段。
数据过滤
在Resolver层根据用户身份过滤数据,确保用户只能访问自己有权限的资源。使用DataLoader批量加载时需要额外注意权限边界。
防护措施
- 禁用Introspection(生产环境)
- 限制批量查询数量(最多5个并行查询)
- 实现查询成本预算(每个用户每分钟最大10000点复杂度)
- SQL注入防护(使用参数化查询,不拼接用户输入)
- 错误信息脱敏(不暴露内部错误堆栈)
监控与审计
记录所有GraphQL操作(operationName、变量、执行时间、错误)。使用Apollo Studio或自建ELK分析查询模式,发现异常访问。设置慢查询告警(执行时间超过5秒)。