测试范围定义和GraphQL测试准备
在开始GraphQL API渗透测试之前,必须明确定义测试边界并获得书面授权。GraphQL与REST API的架构不同:REST API使用多个固定端点,而GraphQL使用单一入口点处理结构化查询。这种架构差异需要对标准网络测试方法论进行调整。GraphQL的单一端点接收POST请求,请求体包含GraphQL查询字符串,这改变了攻击面和测试方法。
准备工作包括通过内省(introspection)进行模式发现,这通常默认启用。使用GraphQL查询工具和专用客户端,可以枚举所有可用的类型、字段和操作。彻底记录API模式对于理解功能和后续风险分析至关重要。内省查询提供关于API支持哪些操作以及它们期望和返回什么数据结构的元数据。通过发送特定的内省查询,可以获取完整的类型定义、字段列表和操作描述。
- 在进行任何安全测试之前获得书面授权
- 在生产环境中禁用GraphQL内省以限制信息收集
- 文档化API端点、支持的操作和查询结构
- 识别使用的身份认证机制和授权模型
身份认证和授权测试
GraphQL API中的身份认证通常通过HTTP头(Authorization头中的Bearer令牌)或Cookie实现。在测试期间,验证未认证的请求被拒绝,提供的凭证得到正确验证。提交带有过期、伪造或修改令牌的请求,确保服务器适当拒绝访问。检查API是在解析器级别还是仅在端点级别强制执行身份认证。令牌的有效期应该严格执行,过期的令牌不应该被接受。同时需要检查令牌刷新机制是否安全实现。
GraphQL中的授权需要字段级别和类型级别的验证。具有受限权限的用户不应该访问为其他角色设计的字段或变更操作。尝试以普通用户身份请求管理字段或执行特权操作。验证授权检查是否在解析器内进行,而不仅仅在查询入口点进行。测试服务器是否为不同操作和对象类型正确实现了基于角色的访问控制(RBAC)。某些字段可能包含敏感信息,只应该对具有特定角色的用户可见。
- 测试未认证查询和变更的拒绝机制
- 验证令牌验证和过期强制执行
- 尝试以用户级权限调用受保护的变更操作
- 确认敏感字段根据用户角色被正确过滤
注入分析和查询操作
GraphQL API容易受到查询参数中的注入攻击,特别是当用户输入直接传递给SQL、LDAP或其他系统而没有适当的清理时。使用常见的注入模式:单引号、双引号、通配符和特殊字符来测试文本字段。仔细观察服务器错误消息,因为它们经常会暴露数据库结构或处理逻辑。测试基于布尔的注入、基于时间的盲注入和其他适配于GraphQL上下文的技术。通过构造特殊的输入,可以改变SQL查询的含义或绕过服务器端的检查。
验证对通过深度嵌套查询(查询深度攻击)或查询复杂性过载进行资源耗尽攻击的保护。GraphQL允许在单个查询中请求任意深度的相关数据;没有限制的情况下,这可能导致拒绝服务。测试提交具有过度嵌套深度或大型批量操作的查询。检查服务器是否实现查询复杂性分析或对复杂查询的速率限制。攻击者可以构造查询来请求数千层嵌套数据,这会消耗大量服务器资源。
- 将特殊字符和引号注入文本参数以测试SQL或代码注入
- 分析错误消息中是否存在信息披露漏洞
- 验证查询深度限制和复杂性限制的执行
- 测试速率限制和对批量查询攻击的保护
枚举和信息披露
GraphQL内省通常默认启用,允许任何客户端在不进行身份认证的情况下检索完整的API模式。虽然这支持开发工作流,但在生产环境中暴露模式会显著增加攻击面。测试是否可以在没有凭证的情况下访问内省查询,提交完整的内省查询来验证。此外,检查错误消息是否暴露关于可用字段、类型或内部系统详情的信息。内省查询会返回所有类型定义、字段名称、参数类型和返回类型,这对攻击者来说是极其有价值的信息。
使用枚举技术发现未文档化的操作或字段。尝试查找可能仅对特权用户可访问的隐藏或内部变更操作。在潜在的字段和操作名称上执行基于名称的模糊测试。从错误响应和头部中提取版本信息、软件依赖项或内部标识符,这些信息可能帮助攻击者制作针对性的漏洞。隐藏的字段可能通过直接在查询中指定字段名称来访问,即使它们不在公开文档中。
- 测试GraphQL内省查询在没有身份认证时的可访问性
- 通过内省枚举可用的类型、字段和变更操作
- 尝试名称模糊测试来发现未文档化的操作
- 从错误响应和头部提取版本或系统信息
业务逻辑测试和操作自动化
在验证了基本的身份认证和注入漏洞后,通过GraphQL变更操作测试应用程序的业务逻辑。尝试执行无效操作,例如批准自己的请求、绕过验证步骤或修改其他用户的数据。检查是否存在操作速率限制、是否强制执行时间窗口,或是否防止有问题的状态转换的一致性检查。测试GraphQL API对可能创建竞态条件的并发变更的处理。某些操作可能只允许在特定时间范围内执行,或者对每个用户有操作次数限制。
通过编写脚本自动化测试,这些脚本提交具有不同参数的一系列请求并分析响应。监控意外的状态变化、来自并发操作的竞态条件,以及通过操作顺序操作来绕过安全检查的机会。测试变更操作的幂等性,验证重复相同的变更操作是否产生一致的结果或被适当拒绝。两个同时执行的操作可能相互影响,导致不一致的结果或安全漏洞。
- 以意外顺序执行操作以测试状态机逻辑
- 检查已执行变更操作的重放保护
- 尝试通过授权绕过修改其他用户的数据
- 使用并发请求来识别关键操作中的竞态条件
响应分析和错误处理
GraphQL以JSON格式返回响应,'data'字段用于结果,'errors'字段用于错误消息。详细的错误消息可能暴露关于服务器结构、底层技术或处理逻辑的信息。检查错误是否包含数据库类型信息、文件系统路径或软件版本详情。比较成功和失败请求之间的响应,以识别可能表示信息泄露的行为差异。某些错误消息可能包含堆栈跟踪、SQL语句或其他调试信息,这些信息不应该在生产环境中暴露。
验证对边界情况的正确处理:空值、极大的数字、字符串中的特殊字符和无效的数据类型。确认响应不包括仅对其他用户或角色可见的敏感数据。使用网络代理拦截和分析所有HTTP头、响应时间和内容。注意Cookie、缓存头和其他可能暴露额外攻击向量的HTTP机制。某些HTTP头可能暴露服务器软件版本或其他敏感信息。响应时间的差异也可能被用来推断服务器的内部状态或数据库内容。
- 分析错误消息的详细程度是否存在信息披露
- 测试对边界情况的处理,包括空值、大数字和特殊字符
- 验证敏感数据不包括在未授权用户的响应中
- 使用HTTP拦截工具监控请求和响应流量的所有方面
文档记录和补救建议
完成安全评估后,文档记录所有识别的漏洞,包括重现步骤、潜在影响和补救指导。包括演示每个漏洞的GraphQL查询示例和服务器响应截图。根据行业标准风险评级框架按严重程度分类漏洞。详细记录包括漏洞的具体位置、攻击难度、影响范围和所需的修复步骤。
建议应该是具体且可行的:在生产环境中禁用内省、在解析器级别实现查询复杂性限制、执行严格的输入验证、进行GraphQL安全实现模式的开发团队培训。与开发团队协调以验证修复并对关键漏洞进行复测,然后再部署到生产环境。建立一个反馈和持续改进的流程,确保类似的漏洞不会在未来的开发中重复出现。