GraphQL 特有的风险面
GraphQL 把接口合并成单一端点,灵活性带来几类特有风险:introspection 会暴露全部类型与字段定义,深嵌套查询可放大资源消耗,字段级授权缺失造成越权,批量查询能力会被用于撞库类滥用。防护要从关闭生产 introspection、限制深度与复杂度、字段级授权三条主线入手。
基本信息
| 端点形态 | 通常单一路径,如 /graphql |
|---|---|
| 特有风险 | introspection、深嵌套查询、字段越权、批量滥用 |
| 主要防护 | 关闭 introspection、深度与复杂度限制、字段级授权 |
| 实现差异 | graphql-ruby、gqlgen、Apollo 等各有插件机制 |
| 错误处理 | 统一错误信息,避免回显 schema 细节 |
典型使用场景
- 上线核查:确认生产环境 introspection 已关闭或仅内网开放
- 性能防护:为深嵌套查询设置深度与复杂度上限,防止单查询打满数据库
- 越权排查:逐个 resolver 检查是否做了权限校验,而不只校验入口
- 撞库防护:限制批量操作与同一查询的重复执行
- 日志与审计:记录查询指纹,识别异常查询模式
防护配置要点
防护配置要点
1. 生产关闭 introspection(或仅内网开启,按需鉴权)
2. 限制查询深度与复杂度,设置单查询超时
3. 限制批量查询合并(batching),防止撞库类滥用
4. 字段级授权:每个 resolver 校验主体权限,不只校验入口
5. 错误信息统一,避免暴露 schema 细节与内部堆栈
6. 记录查询指纹与耗时,异常模式纳入告警限制项(概念示意)
限制项(概念示意)
max_depth: 10
max_complexity: 1000
query_timeout: 5s
max_batch: 1
# 具体实现依赖所用框架:graphql-ruby、gqlgen、Apollo 插件等
# 阈值应结合实测调整:过紧会误伤正常业务查询风险面与防护
| 风险 | 成因 | 防护 |
|---|---|---|
| Schema 泄露 | introspection 开放 | 生产关闭或仅内网开放 |
| 资源耗尽 | 深嵌套或高复杂度查询 | 深度与复杂度限制、超时 |
| 越权访问 | 仅校验入口不校验子字段 | 字段级授权,逐个 resolver 校验 |
| 撞库与滥用 | 批量查询接口无限制 | 限制 batching 与频率 |
GraphQL 鉴权最容易漏在嵌套字段层:入口查询校验通过后,子对象被间接带出,形成越权面;评审时按字段而不是按接口逐个确认。
关闭 introspection 不等于安全:它只提高外部理解成本,越权与资源耗尽两类问题与它无关,需要独立验证。