kamakauzy/graphql-hunter

GitHub: kamakauzy/graphql-hunter

一款功能全面的 GraphQL API 安全测试工具,覆盖从内省探测到注入攻击的多种漏洞检测,并提供 Burp Suite 插件与详细的报告生成功能。

Stars: 24 | Forks: 1

# GraphQL Hunter

GraphQL Hunter

一款全面的 GraphQL 安全测试工具,像凌晨 3 点精神抖擞的安全研究员一样精准地搜寻 GraphQL API 中的漏洞。测试注入漏洞、身份验证绕过、DoS 向量等。基本上,它是那个直言不讳告诉你 API 安全真相的朋友。 ## 功能特性 ### [+] 全面的安全扫描 *也就是“你需要听到的坏消息”* - **Introspection Analysis (内省分析)** - 检查你是否把 Schema 文档敞开了(剧透:你大概率是) - **Information Disclosure (信息泄露)** - 发现那些你泄露给攻击者的有用堆栈跟踪信息 - **Authentication/Authorization (身份验证/授权)** - 测试你的“auth”更像是一个建议而非强制要求 - **Injection Testing (注入测试)** - SQL 注入、NoSQL 注入、命令注入……基本上所有的注入 - **DoS Vectors (DoS 向量)** - 看看需要多少嵌套查询才能让你的服务器崩溃 - **Batching Attacks (批量攻击)** - 测试攻击者是否能像 2010 年那样垃圾邮件般轰炸你的 API - **Aliasing Abuse (别名滥用)** - 检查你是否像兔子一样成倍增加漏洞 - **Mutation Security (Mutation 安全性)** - 因为 `deletEverything` 不应该是公开可访问的 - **Rate Limiting (速率限制)** - 测试你的 API 能否处理洪水般的请求(剧透:大概率不能) - **CSRF Protection (CSRF 防护)** - 检查 Mutation 是否容易受到跨站请求伪造攻击 - **File Upload (文件上传)** - 测试路径遍历、超大文件和恶意扩展名 - **Mass Assignment (批量赋值)** - 检测 Mutation 是否接受意外的敏感字段 - **Brute-Force Protection (暴力破解防护)** - 测试登录 Mutation 是否有速率限制和账户锁定 - **Token Expiration (Token 过期)** - 验证 JWT Token 是否正确过期并在过期后被拒绝 ### [+] 用户友好的界面 *“友好”是相对的,当它在吐槽你的安全态势时* - 彩色终端输出(红色意味着恐慌,绿色意味着庆祝) - **漂亮的 HTML 报告**(用渐变色给管理层留下深刻印象!) - JSON 导出(当你需要机器可读的证据时) - 实时进度报告(看着结果滚滚而来!) - 带有 CWE 参考的详细描述(这样你在会议上听起来很聪明) - 基于严重性的分类(CRITICAL = 更新你的简历) - 适合打印的 HTML 布局(为了留个纸面记录) ### [+] 灵活的配置 *因为一刀切根本不存在* - **Scan Profiles (扫描配置文件)**: Quick、Standard、Deep 和 Stealth 模式 - **Safe Mode (安全模式)**: 当你不想意外地把生产环境 DoS 掉时(再次) - **Custom Headers (自定义 Headers)**: 带上你自己的 auth Token - **Rate Limiting (速率限制)**: 做一个有礼貌的黑客 - **Proxy Support (代理支持)**: 像专业人士一样通过 Burp Suite 路由 - **Selective Scanning (选择性扫描)**: 跳过那些伤害你感情的各种扫描器 ## 快速开始 ### 安装 ``` # 克隆仓库(常规操作) git clone https://github.com/kamakauzy/graphql-hunter.git cd graphql-hunter # 安装依赖(比冲咖啡还快) pip install -r requirements.txt # 可选:安装 CLI 入口点 python -m pip install . # 运行测试扫描(准备好接受坏消息) gqlh -u https://countries.trevorblades.com/graphql ``` CLI 说明: - 首选命令:`pip install .` 后使用 `gqlh ...` 或 `graphql-hunter ...` - 源码检出回退:`python3 gqlh.py ...` - 旧的 `python3 graphql-hunter.py ...` 用法仍然有效 ### 基本用法 ``` # 基础扫描(温和入门) python graphql-hunter.py -u https://api.example.com/graphql # 认证扫描(假装你是真实用户) python graphql-hunter.py -u https://api.example.com/graphql -t YOUR_TOKEN # 深度扫描并输出(当你想要所有坏消息时) python graphql-hunter.py -u https://api.example.com/graphql -p deep -o results.json # 安全模式(跳过 DoS 测试,运维团队会感谢你) python graphql-hunter.py -u https://api.example.com/graphql --safe-mode # 隐身模式(偷偷摸摸,慢慢移动,别吵醒 WAF) python graphql-hunter.py -u https://api.example.com/graphql -p stealth --delay 2 ``` ### Burp Suite Professional 插件 (`.jar`) 此仓库现在还在 `burp-extension/` 下包含一个 **原生 Burp Suite Professional 插件**。 目前它的功能: - 作为 **Java `.jar`** 安装在 Burp Pro 中 - 添加一个 **GraphQL Hunter** 套件选项卡 - 通过上下文菜单从 Burp 导入 GraphQL 请求 - 自动将导入的 auth Headers 带入 Burp auth 工作区 - 支持不与 Burp 扩展状态一起持久化的仅运行时 auth 密钥 - 根据隔离的匿名基线验证 auth,而不是重用已验证的 Burp 会话 - 包含 Burp 侧工作区,用于: - 请求编辑 - Auth 设置和验证 - 粘贴导入解析 - 发现分析和应用 - JSON / HTML 导出,带有编辑过的重放伪影和真实扫描覆盖元数据 - 原生 Burp 漏洞发布 - 对导入的端点运行专注的原生检查: - Introspection (内省) - Information Disclosure (信息泄露) - Auth 暴露差异和登录暴力破解防护启发式分析 - Batching (批量) 和大批量审查 - Injection (注入),包括仅查询的时间型和在深度启用配置文件中的保守布尔差分探测 - DoS / 深度 / 复杂度 - Aliasing (别名) - 循环查询审查 - XSS 反射审查 - JWT 审查,包括 `alg:none` 和过期 Token 接受检查 - 并发速率限制 - CSRF 审查,包括缺失 Origin 抑制和跨站 Origin 验证探测 - 文件上传面审查 - Mutation 审查启发式分析 Burp 插件是**增量的**。现有的 Python CLI 仍然是主要的独立工作流程,并且保持不变。 构建 Burp 插件: ``` cd burp-extension ./gradlew clean fatJar test ``` 产物: ``` burp-extension/build/libs/GraphQLHunterBurp.jar ``` 在 Burp Suite Professional 中加载: 1. 打开 **Extensions**。 2. 添加一个新的 **Java** 扩展。 3. 选择 `burp-extension/build/libs/GraphQLHunterBurp.jar`。 4. 使用 Burp 的 HTTP 消息上下文菜单将 GraphQL 请求发送到 **GraphQL Hunter** 选项卡。 5. 使用该选项卡的 **Auth** 和 **Import & Discovery** 工作区来验证 auth、解析粘贴的请求、自动应用导入的 auth Headers、分析笔记、管理仅运行时密钥、导出带有 cURL / Burp 重放片段以及已执行/已跳过/已失败扫描器覆盖的发现,并将发现发布为原生 Burp 漏洞。 ## 使用指南 ### 扫描配置文件 *选择你的战士* ``` # 快速扫描(安全扫描中的快餐) python graphql-hunter.py -u https://api.example.com/graphql -p quick # 标准扫描(恰到好处的选择)- 默认 python graphql-hunter.py -u https://api.example.com/graphql -p standard # 深度扫描(坐稳了,这得花点时间) python graphql-hunter.py -u https://api.example.com/graphql -p deep # 隐身扫描(忍者模式激活 🥷) python graphql-hunter.py -u https://api.example.com/graphql -p stealth --delay 2 ``` ### 身份验证 *"没有 auth header,你是谁?"* ``` # 使用 Bearer token(现代方式) python graphql-hunter.py -u https://api.example.com/graphql -t YOUR_TOKEN # 使用自定义 headers(因为你是特别的) python graphql-hunter.py -u https://api.example.com/graphql -H "Authorization: Bearer TOKEN" python graphql-hunter.py -u https://api.example.com/graphql -H "X-API-Key: KEY" -H "X-User-ID: 123" ``` ### 高级身份验证工作流程 (OAuth, cookie sessions, CSRF) GraphQL Hunter 还可以通过 `config/auth.yaml` 中的 **auth profiles** 运行 **auth workflows**(Token 获取 + 刷新 + cookie 会话)。 ``` # OAuth2 client-credentials(服务对服务) python graphql-hunter.py -u https://api.example.com/graphql \ --auth-profile oauth2_client_credentials \ --auth-var client_id=YOUR_CLIENT_ID \ --auth-var client_secret=YOUR_CLIENT_SECRET \ --auth-var scope="read:graphql" # OAuth2 auth-code(半手动:打开 URL,然后粘贴代码) python graphql-hunter.py -u https://api.example.com/graphql \ --auth-profile oauth2_auth_code \ --auth-var client_id=YOUR_CLIENT_ID \ --auth-var client_secret=YOUR_CLIENT_SECRET \ --auth-var oauth_code=PASTE_CODE_HERE # Cookie session + CSRF(半手动变量;步骤在 config/auth.yaml 中定义) python graphql-hunter.py -u https://api.example.com/graphql \ --auth-profile cookie_session_with_csrf \ --auth-var username=YOUR_USERNAME \ --auth-var password=YOUR_PASSWORD ``` 注意: - 默认 auth 配置路径是 `config/auth.yaml`(可安全提交的模板;**不要**在其中存储密钥)。 - 你也可以通过前缀为 `GQLH_` 的环境变量提供变量(例如:`GQLH_CLIENT_ID`,`GQLH_CLIENT_SECRET`)。 - 详细输出和报告会**编辑**常见的密钥(Token、Cookie、密码)。 ### Auth 向导 (交互式) 如果你更喜欢交互式提示,输出一个可以直接运行的命令(不打印密钥),请运行: ``` python graphql-hunter.py --auth-wizard ``` ### 自动发现 *"从我的笔记里自己搞清楚"* 该工具可以从笔记、JSON、YAML 文件或任何文本中自动发现身份验证和配置: ``` # 从 notes 文件自动发现 python graphql-hunter.py --auto-discover notes.txt # 显示发现的内容(不运行扫描) python graphql-hunter.py --auto-discover notes.txt --show-discovery # 从多个来源自动发现 python graphql-hunter.py --auto-discover notes.txt config.json request.yaml ``` **它能发现:** - URL 和端点 - 身份验证方法 (tokenAuth, OAuth 等) - 凭据 (邮箱, 密码, Token) - Headers 和 Token - 文件中的 Query 和 Mutation - 生成可直接运行的命令 **示例:** 提供一个包含 email/password/URL 的笔记文件,工具将自动: 1. 检测身份验证方法 2. 配置 auth profile 3. 设置凭据 4. 运行扫描 详细文档请参阅 `AUTO_DISCOVERY.md`。 ### 导入请求 *"我已经有这些请求了,为什么要重新输入?"* GraphQL Hunter 可以从各种格式导入请求,使测试更容易: ``` # 从 Postman Collection 导入(JSON) python graphql-hunter.py --import my-collection.json -u https://api.example.com/graphql # 从 JSON 文件导入 python graphql-hunter.py --import request.json --validate-auth # 从 YAML 文件导入 python graphql-hunter.py --import request.yaml -H "Authorization: Bearer TOKEN" # 从 cURL 命令导入 python graphql-hunter.py --import-curl "curl -X POST https://api.example.com/graphql -H 'Authorization: Bearer TOKEN' -d '{\"query\":\"{__typename}\"}'" # 列出 Postman collection 中的所有请求 python graphql-hunter.py --import collection.json --list-imported ``` **支持的格式:** - **Postman Collection v2.1** - 自动从集合中提取所有请求 - **JSON** - 简单的请求格式,包含 url, headers, query, variables - **YAML** - 与 JSON 相同,但是 YAML 格式 - **cURL commands / cURL text files** - 解析 cURL 命令字符串或包含 cURL 请求的文本文件 - **Raw HTTP** - 解析原始 HTTP 请求字符串 **JSON 格式示例:** ``` { "url": "https://api.example.com/graphql", "headers": { "Authorization": "Bearer TOKEN" }, "query": "mutation { ... }", "variables": { "key": "value" }, "operation_name": "MyMutation" } ``` 导入时,工具将自动: - 提取 URL、Headers、Query 和 Variables - 如果使用了 `--validate-auth`,则使用导入的请求进行 auth 验证 - 将导入的 Headers 与命令行 Headers 合并(CLI Headers 优先) - 尽可能将 JSON 字符串 `variables` 值规范化为对象 ### 输出选项 ``` # 将结果保存为 JSON(为了留档和明确责任) python graphql-hunter.py -u https://api.example.com/graphql -o results.json # 将结果保存为 HTML(给管理层的好看报告) python graphql-hunter.py -u https://api.example.com/graphql --html report.html # JSON 和 HTML 都要(面面俱到) python graphql-hunter.py -u https://api.example.com/graphql -o results.json --html report.html # 详细模式(所有细节,准备好面对信息过载) python graphql-hunter.py -u https://api.example.com/graphql -v # 禁用颜色(为了长久保存日志) python graphql-hunter.py -u https://api.example.com/graphql --no-color > scan.txt ``` 报告现在区分: - **confirmed** (已确认) 发现 - 运行时证据强力支持该问题 - **potential** (潜在) 发现 - 观察到信号,但影响仍需审查 - **manual_review** (人工审查) 发现 - 应由人工验证的攻击面或启发式结果 JSON/HTML 输出还包含状态计数和已确认严重性汇总,以便自动化系统可以区分噪音和已确认的风险。 JSON 报告包含一个 `scan` 部分,描述已执行、已跳过和已失败的扫描器,以便你可以确切了解实现了哪些覆盖范围。 ### 选择性扫描 *"我不想知道那个问题"* ``` # 跳过可怕的扫描器 python graphql-hunter.py -u https://api.example.com/graphql --skip-dos --skip-batching # 只运行你在情感上能承受的扫描器 python graphql-hunter.py -u https://api.example.com/graphql \ --skip-info-disclosure \ --skip-auth \ --skip-dos \ --skip-batching \ --skip-aliasing \ --skip-circular \ --skip-mutation-fuzzing ``` ### 代理使用 *当你想看到一切时* ``` # HTTP 代理(通过 Burp Suite 路由) python graphql-hunter.py -u https://api.example.com/graphql --proxy http://127.0.0.1:8080 # 实时查看请求(莫名地爽) python graphql-hunter.py -u https://api.example.com/graphql --proxy http://127.0.0.1:8080 -v ``` ## 示例与测试用例 ### 公共测试端点 *熟能生巧(或者至少不那么尴尬)* ``` # Countries API(推荐 - 不会让你被炒鱿鱼) python graphql-hunter.py -u https://countries.trevorblades.com/graphql # SpaceX API(因为太空很酷) python graphql-hunter.py -u https://api.spacex.land/graphql/ # GitHub GraphQL API(带上你的 token 否则回家) python graphql-hunter.py -u https://api.github.com/graphql -t YOUR_GITHUB_TOKEN ``` ### 易受攻击的测试应用程序 *当你想感觉自己像个黑客之神却没有法律后果时* **[Damn Vulnerable GraphQL Application (DVGA)](https://github.com/dolevf/Damn-Vulnerable-GraphQL-Application)** 非常适合练习: ``` # 克隆并运行 DVGA(需要 Docker,那必须的) git clone https://github.com/dolevf/Damn-Vulnerable-GraphQL-Application.git cd Damn-Vulnerable-GraphQL-Application docker build -t dvga . docker run -t -p 5013:5013 -e WEB_HOST=0.0.0.0 dvga # 对它释放 GraphQL Hunter(它毫无胜算) python graphql-hunter.py -u http://localhost:5013/graphql -p deep -o dvga-scan.json ``` DVGA 包含非常适合测试的故意漏洞: - SQL Injection (SQL 注入,经典之作) - OS Command Injection (操作系统命令注入,执行 66 号令) - Authorization bypass (授权绕过,大摇大摆地穿过大门) - DoS vectors (DoS 向量,让服务器崩溃) - Information disclosure (信息泄露,过度分享是一种关心?) - 还有更多!(到处都是漏洞) ### 示例场景 **场景 1:测试新 API** ``` # 温和开始(像初次约会一样) python graphql-hunter.py -u https://api.example.com/graphql -p quick # 如果发现问题,深入挖掘(关系变得认真了) python graphql-hunter.py -u https://api.example.com/graphql -p deep -o results.json # 审查损害 cat results.json | python -m json.tool ``` **场景 2:已认证测试** ``` # 使用 API key 测试(你有 VIP 通行证) python graphql-hunter.py -u https://api.example.com/graphql \ -H "X-API-Key: your-api-key-here" \ -o authenticated-results.json # 使用 JWT token 测试(高大上!) python graphql-hunter.py -u https://api.example.com/graphql \ -t eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... \ -v ``` **场景 3:专注于特定漏洞** ``` # 仅测试 injection(因为这已经很糟糕了) python graphql-hunter.py -u https://api.example.com/graphql \ --skip-info-disclosure \ --skip-auth \ --skip-dos \ --skip-batching \ --skip-aliasing \ --skip-circular \ --skip-mutation-fuzzing ``` ## 命令行选项 *所有的旋钮和开关* ``` Required Arguments: -u, --url URL GraphQL endpoint URL Authentication & Headers: -H, --header HEADER Custom headers (can be used multiple times) -t, --token TOKEN Bearer token for authentication Auth Workflow Engine: --auth-config FILE Auth config YAML path (default: config/auth.yaml) --auth-profile NAME Auth profile name from auth config --auth-var KEY=VALUE Auth variable override (can be used multiple times) --auth-detect Enable best-effort auth/CSRF diagnostics (default) --no-auth-detect Disable best-effort auth/CSRF diagnostics --auth-wizard Interactive auth wizard (prints a ready-to-run command without exposing secrets) Scan Configuration: -p, --profile PROFILE Scan profile: quick, standard, deep, stealth (default: standard) --safe-mode Skip potentially destructive DoS tests --delay SECONDS Delay between requests in seconds (defaults to profile setting) Scanner Selection: --skip-introspection Skip introspection scanner --skip-info-disclosure Skip information disclosure checks --skip-auth Skip authentication/authorization tests --skip-injection Skip injection tests --skip-dos Skip DoS vector tests --skip-batching Skip batching attack tests --skip-aliasing Skip aliasing abuse tests --skip-circular Skip circular query tests --skip-mutation-fuzzing Skip mutation fuzzing --skip-xss Skip XSS tests --skip-jwt Skip JWT security tests --skip-rate-limit Skip rate limiting tests --skip-csrf Skip CSRF tests --skip-file-upload Skip file upload tests --brute-force-attempts N Number of brute-force attempts (defaults to profile setting) --rate-limit-concurrency N Number of concurrent workers for rate limit tests --rate-limit-requests N Total requests to send during rate limit tests Output Options: -o, --output FILE Output JSON file path --html FILE Output HTML report file path -v, --verbose Verbose output (show requests/responses) --no-color Disable colored output Proxy Settings: --proxy URL Proxy URL (e.g., http://127.0.0.1:8080) ``` ## 理解结果 ### 严重性级别 *“哦不”的层级* - **CRITICAL** - 放下一切,立即修复(你的 API 基本上就是潜艇上的纱门) - **HIGH** - 尽快修复,真的很快(攻击者可能已经在利用它了) - **MEDIUM** - 应该解决这个问题(在它变成 HIGH 之前) - **LOW** - 小问题(但千刀万剐还是会死) - **INFO** - 信息性(或者正如我们所说的,“好消息”) ### 退出代码 *给自动化爱好者* - `0` - 没有 **已确认的** critical/high 发现 - `1` - 检测到已确认的高严重性发现 - `2` - 检测到已确认的严重严重性发现 - `130` - 扫描被用户中断(Ctrl+C 是你的朋友) ### 解读发现 *如何读茶叶* 每个发现现在都包含一个 **status (状态)**: - **confirmed (已确认)** - 行为强力支持该问题 - **potential (潜在)** - 观察到信号,但尚未完全证实 - **manual_review (人工审查)** - 应人工检查的攻击面或启发式结果 关键发现示例: ``` { "title": "SQL Injection Vulnerability Detected", "severity": "CRITICAL", "status": "confirmed", "scanner": "injection", "description": "SQL error messages detected when testing query.field with injection payload", "impact": "SQL injection allows attackers to manipulate database queries...", "remediation": "Use parameterized queries or ORM methods...", "cwe": "CWE-89: SQL Injection", "evidence": { "query": "exampleQuery", "argument": "id", "payload": "' OR '1'='1" } } ``` **响应步骤**(又名“损害控制”): 1. 人工验证发现(也许它错了?不过大概率没错) 2. 修复漏洞(真正修复它,不要只是添加一个 TODO) 3. 重新扫描以确认修复(信任但要验证) 4. 记录修复(未来的你会感谢现在的你) ## 检测到的常见漏洞 *精选集专辑* ### 1. Introspection Enabled (Introspection 已启用) **问题**: GraphQL Introspection 在生产环境中启用 **影响**: 攻击者免费获得 API 地图 **补救措施**: 禁用它。就……禁用它。 ### 2. SQL Injection (SQL 注入) **问题**: 用户输入直接进入数据库(哎呀) **影响**: 数据库拜拜了 **补救措施**: 参数化查询是你的朋友 ### 3. Authentication Bypass (身份验证绕过) **问题**: API 像 24/7 便利店一样开放 **影响**: 未经授权访问所有内容 **补救措施**: 添加实际的身份验证(新奇的概念!) 4. DoS via Deep Nesting (通过深度嵌套进行 DoS) **问题**: 没有查询深度限制(有人想要无限循环吗?) **影响**: 服务器变成散热器 **补救措施**: 实施深度限制(5-7 层是合理的) ### 5. Batching Attacks (批量攻击) **问题**: 无限查询批量处理(这是自助餐!) **影响**: 速率限制变成装饰品 **补救措施**: 将批量大小限制为 5-10 个查询 ### 6. Field Aliasing Abuse (字段别名滥用) **问题**: 对字段别名没有限制(乘法很有趣!) **影响**: 一个查询变成 100 个查询 **补救措施**: 在查询成本中计算别名 ### 7. IDOR in Mutations (Mutation 中的 IDOR) **问题**: 可以修改其他用户的数据(哎呀) **影响**: 隐私?没听说过她 **补救措施**: 在 Mutation 之前检查用户是否拥有该资源 ### 8. Rate Limiting Missing (缺少速率限制) **问题**: API 端点没有速率限制 **影响**: 暴力破解攻击和 DoS 变得微不足道 **补救措施**: 实施速率限制(每个 IP 每分钟 100-1000 个请求) ### 9. CSRF Vulnerabilities (CSRF 漏洞) **问题**: Mutation 接受没有 Origin 验证的请求 **影响**: 攻击者可以代表用户执行操作 **补救措施**: 验证 Origin/Referer Headers,使用 CSRF Token,实施 SameSite Cookie ### 10. File Upload Vulnerabilities (文件上传漏洞) **问题**: 文件上传容易受到路径遍历、超大文件、恶意扩展名的攻击 **影响**: 服务器受损、DoS、未授权文件访问 **补救措施**: 验证文件名,强制执行大小限制,检查文件类型(MIME,而不是扩展名),存储在 Web 根目录之外 ### 11. Mass Assignment (批量赋值) **问题**: Mutation 接受意外的敏感字段(例如 `role: "admin"`) **影响**: 权限提升、未授权数据修改 **补救措施**: 使用已接受字段的允许列表,明确排除敏感字段,验证所有输入 ### 12. Weak Authentication (弱身份验证) **问题**: 没有暴力破解防护,仍然接受过期的 Token **影响**: 账户受损、无限期 Token 使用 **补救措施**: 对登录实施速率限制、账户锁定、CAPTCHA,强制 Token 过期 ## 补救指南 *如何修复我们发现的问题* ### 通用 GraphQL 安全最佳实践 1. **在生产环境中禁用 Introspection** // Apollo Server example const server = new ApolloServer({ introspection: process.env.NODE_ENV !== 'production' }); // 是生产环境?那就没 Schema 给你看! 2. **实施查询深度限制** // Using graphql-depth-limit import depthLimit from 'graphql-depth-limit'; const server = new ApolloServer({ validationRules: [depthLimit(7)] // 7 层足够了 }); 3. **实施查询复杂度分析** // Using graphql-query-complexity import { createComplexityLimitRule } from 'graphql-validation-complexity'; const server = new ApolloServer({ validationRules: [createComplexityLimitRule(1000)] // 选个数字,任何数字 }); 4. **要求身份验证** // Apollo Server context example const server = new ApolloServer({ context: ({ req }) => { const token = req.headers.authorization || ''; if (!token) throw new Error('Not authenticated'); return { user: verifyToken(token) }; } }); // 没有 Token,禁止入内。简单! 5. **实施字段级授权** // Using graphql-shield import { shield, rule } from 'graphql-shield'; const isAuthenticated = rule()(async (parent, args, ctx) => { return ctx.user !== null; // 必须有用户,抱歉了机器人 }); const permissions = shield({ Query: { sensitiveData: isAuthenticated } }); 6. **禁用查询批量处理(或限制它)** // Apollo Server const server = new ApolloServer({ allowBatchedHttpRequests: false // 直接说不 }); 7. **实施速率限制** // Using express-rate-limit or similar const rateLimit = require('express-rate-limit'); const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 分钟 max: 100 // 每个 IP 在 windowMs 内限制 100 个请求 }); app.use('/graphql', limiter); 8. **防范 CSRF** // 为 Mutation 验证 Origin header app.use('/graphql', (req, res, next) => { if (req.method === 'POST' && req.body.query.includes('mutation')) { const origin = req.headers.origin; const expectedOrigin = process.env.ALLOWED_ORIGIN; if (origin !== expectedOrigin) { return res.status(403).json({ error: 'CSRF validation failed' }); } } next(); }); 9. **安全文件上传** // 验证文件上传 const multer = require('multer'); const upload = multer({ limits: { fileSize: 10 * 1024 * 1024 }, // 最大 10MB fileFilter: (req, file, cb) => { const allowedTypes = ['image/jpeg', 'image/png']; if (allowedTypes.includes(file.mimetype)) { cb(null, true); } else { cb(new Error('Invalid file type')); } }, storage: multer.diskStorage({ destination: '/uploads', // Web 根目录之外 filename: (req, file, cb) => { // 生成唯一文件名 cb(null, `${Date.now()}-${Math.random().toString(36)}.${file.originalname.split('.').pop()}`); } }) }); 10. **防止批量赋值** // 为 Mutation 输入使用允许列表 const allowedFields = ['name', 'email', 'bio']; const input = {}; for (const field of allowedFields) { if (args.input[field] !== undefined) { input[field] = args.input[field]; } } // 仅复制允许的字段,忽略敏感字段 11. **实施暴力破解防护** // 限制登录 Mutation 速率 const loginLimiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 5, // 15 分钟内 5 次尝试 message: 'Too many login attempts, please try again later' }); // 多次失败后账户锁定 let failedAttempts = {}; if (failedAttempts[email] >= 5) { throw new Error('Account temporarily locked'); } 12. **强制 Token 过期** // 验证 JWT 过期 const jwt = require('jsonwebtoken'); const decoded = jwt.verify(token, secret); const now = Math.floor(Date.now() / 1000); if (decoded.exp < now) { throw new Error('Token expired'); } ## 高级扫描器 *新来的孩子* ### 速率限制扫描器 测试你的 API 处理请求洪水的能力: - 发送 100+ 个并发请求 - 检测 429 (Too Many Requests) 响应 - 测量响应时间退化 - 测试特定 Mutation 的速率限制 **用法**: 在 standard/deep 配置文件中自动启用。在 safe mode 中禁用。 ### CSRF 扫描器 测试 Mutation 是否存在跨站请求伪造漏洞: - 检测基于 Cookie 的身份验证 - 使用缺失的 Origin header 进行测试 - 使用不匹配的 Origin header 进行测试 - 验证 CSRF Token 的存在 **用法**: 自动启用。仅在存在 Cookie 时进行测试。 ### 文件上传扫描器 检测并测试文件上传 Mutation: - 识别 Schema 中的 Upload 标量类型 - 当无法自动执行完整的 multipart 利用时,将其标记为人工审查 - 建议测试路径遍历 - 建议测试超大文件 - 建议测试恶意扩展名 **用法**: 自动启用。除非捕获到真实的 multipart 利用证据,否则发现通常以 `manual_review` 形式发出。 ### 增强的 Mutation 测试 Mutation 模糊测试器现在包括: - **批量赋值审查**: 标记可疑的输入对象以供人工验证 - **增强的 IDOR 审查**: 突出显示值得进行授权测试的对象 ID Mutation 面 - **权限提升审查**: 建议在适用的地方进行角色/管理员字段注入检查 ### 增强的身份验证测试 Auth 扫描器现在包括: - **暴力破解测试**: 测试登录 Mutation 是否有速率限制和账户锁定 - **Token 过期测试**: 验证 JWT Token 是否正确过期(JWT 扫描器) ### 增强的注入/XSS 测试 两个扫描器现在都测试 Mutation(不仅仅是 Query): - **注入扫描器**: 使用 Schema 有效的操作,并将后端特定的错误签名报告为潜在发现 - **XSS 扫描器**: 将反射的 Payload 视为审查候选者,除非有浏览器可执行的 Sink 证据 ## 测试指南 *细则* ### 在测试你自己的 API 之前 GraphQL Hunter 专为**授权的安全测试**而设计。测试前: 1. ✅ 获得书面许可(说真的,要书面形式) 2. ✅ 先在非生产环境中测试(生产环境是神圣的) 3. ✅ 最初使用 `--safe-mode`(循序渐进) 4. ✅ 从 quick 配置文件开始(慢慢来) 5. ✅ 仔细审查发现(误报是存在的) **[!] 警告**: 未经授权的测试可能是非法的。不要成为那种人。一定要先获得许可。我们不会为你保释。 ### 误报 *有时工具是错的(喘口气!)* 有些发现可能是误报或可接受的: - **Introspection Enabled** - 在开发环境中可能没问题(重点在“在开发中”) - **Verbose Errors** - 可能是为了调试而故意为之(但大概率不应该) - **Circular References** - 如果强制执行深度限制,则是常见模式 在惊慌之前,请务必人工验证发现。 ## 示例输出 *成功(或失败)的样子* 查看 `examples/` 目录中的 **真实漏洞扫描**: - **[dvga-scan.json](examples/dvga-scan.json)** - 机器可读的 JSON 报告 (16.5 KB) - **[dvga-report.html](examples/dvga-report.html)** - 漂亮的 HTML 报告 (37.5 KB) - 在浏览器中打开 这些是从 **DVGA** (Damn Vulnerable GraphQL Application) 的 **深度扫描** 生成的,显示了 **15 个真实发现**: - **confirmed** 发现,其中运行时证据确凿 - **potential** 发现,其中行为可疑但未完全证实 - **manual_review** 发现,突出显示值得人工验证的攻击面 ### 终端输出 ``` =============================================================== GRAPHQL HUNTER - Security Scanner v1.0 Comprehensive GraphQL API Security Testing =============================================================== [i] Target: https://api.example.com/graphql [i] Profile: standard ---------------------------------------------------------------------- [*] Introspection ---------------------------------------------------------------------- [!] Introspection is ENABLED [MEDIUM] GraphQL Introspection Enabled Metadata: scanner=introspection, status=confirmed, confidence=confirmed Description: The GraphQL endpoint has introspection enabled... Impact: Attackers can map the entire API surface area... Remediation: Disable introspection in production environments... [*] SCAN SUMMARY ---------------------------------------------------------------------- Total Findings: 5 Critical: 1 High: 2 Medium: 1 Low: 1 Confirmed: 2 Potential: 1 Manual review: 2 Overall Risk: CRITICAL - Immediate action required! (Translation: panic responsibly) ``` ## 故障排除 *当事情变得一团糟时* ### 连接错误 ``` [X] Failed to initialize client: Connection failed ``` **解决方案**: 检查 URL、网络、SSL 证书。通常的嫌疑人。 ### 超时错误 ``` [!] Request timeout ``` **解决方案**: 服务器慢或死了。增加超时或 `--delay`。 ### 无可用 Schema ``` [i] Schema not available, skipping... ``` **解决方案**: Introspection 已禁用(很好!)但某些测试将受到限制。 ## 单元测试 运行离线单元测试套件: ``` python3 -m unittest discover -s tests -p "test_*.py" ``` ## 项目结构 *给好奇者和贡献者* ``` graphql-hunter/ ├── graphql-hunter.py # The main show ├── burp-extension/ # Native Burp Suite Professional addon (.jar) ├── requirements.txt # Dependencies (not many!) ├── README.md # You are here ├── quickstart.bat # For Windows folks ├── test_tool.py # Self-test script ├── config/ │ ├── payloads.yaml # Attack payloads (the spicy stuff) │ └── auth.yaml # Auth workflow profiles (safe template) ├── lib/ │ ├── graphql_client.py # Talks to GraphQL │ ├── auth/ # Auth workflow engine (OAuth, cookies, CSRF, wizard) │ ├── reporter.py # Makes things pretty │ ├── utils.py # Random useful stuff │ └── introspection.py # Schema parser └── scanners/ ├── introspection_scanner.py # Finds exposed schemas ├── info_disclosure_scanner.py # Finds leaky errors ├── auth_bypass_scanner.py # Tests auth (or lack thereof) ├── injection_scanner.py # Injection detection ├── dos_scanner.py # DoS tests (carefully!) ├── batching_scanner.py # Batch attack tests ├── aliasing_scanner.py # Aliasing abuse detection ├── circular_query_scanner.py # Finds loops ├── mutation_fuzzer.py # Mutation security ├── xss_scanner.py # XSS detection └── jwt_scanner.py # JWT security tests ``` ## 贡献 *想让它变得更好?太棒了!* 欢迎贡献!重点关注: - 添加新的漏洞检查(多多益善!) - 提高检测准确性(请减少误报) - 更好的报告格式(让它变漂亮) - 文档改进(帮助未来的人类) 请保持工具对道德使用的关注。我们是好人。 ## 联系方式 *如有问题、击掌或安全合作* **Brad Crawford** Email: brad@securit360.com GitHub: [@kamakauzy](https://github.com/kamakauzy) ## 许可证 该工具仅用于教育和授权测试目的。不要用它作恶。我们是认真的。 ## 免责声明 **GraphQL Hunter 是一款安全测试工具。请负责任且合法地使用。** - 仅测试你有权测试的系统(书面获得!) - 某些测试可能会影响系统性能(因此有 `--safe-mode`) - 作者不对滥用负责(别让我们后悔这个) - 始终遵循负责任的披露做法(做个好人) ## 版本 GraphQL Hunter v1.0 - 2025 年 11 月 *用咖啡 ☕、讽刺和让 GraphQL API 更安全的真诚愿望构建* **[+] 祝你(合乎道德的)狩猎愉快!** *记住:能力越大,责任越大。伟大的发现伴随着伟大的补救工作。祝你好运! 🎯*
标签:API 安全, CISA项目, CSRF, DoS, GraphQL, JS文件枚举, NoSQL 注入, PoC, SQL 注入, Web 安全, XXE攻击, 信息泄露, 命令注入, 对称加密, 开源安全工具, 批量查询, 拒绝服务, 授权测试, 文档结构分析, 暴力破解, 注入攻击, 网络安全, 自动化审计, 认证绕过, 资产探测, 逆向工具, 逆向工程平台, 隐私保护