揭开 CSRF 的神秘面纱?
Posted
技术标签:
【中文标题】揭开 CSRF 的神秘面纱?【英文标题】:Demystifying CSRF? 【发布时间】:2018-04-17 11:12:15 【问题描述】:我已经阅读了很多 long explanations of CSRF 和 IIUC,导致攻击的核心是基于 cookie 的服务器会话识别。
换句话说,如果浏览器(请注意,我在这里专门将范围缩小到 Web 浏览器)不使用基于 cookie 的会话密钥来识别服务器上的会话,那么 CSRF 攻击就不会发生。我理解正确吗?
例如,假设有人创建了如下链接:
href="http://notsosecurebank.com/transfer.do?acct=AttackerA&amount;=$100">Read more!
您在登录http://notsosecurebank.com
时被骗点击此链接,但是http://notsosecurebank.com
不使用 cookie 来跟踪您的登录会话,因此该链接不会造成任何伤害,因为该请求无法通过身份验证而只是获取扔进垃圾箱?
假设
OpenID 连接服务器/OAuth 授权服务器已正确实施,不会将身份验证重定向发送到您请求的任何 URL。 攻击者不知道客户端 ID 和客户端密码脚注
我在这个问题中针对的场景是最常谈论的 CSRF 场景。还有其他适合CSRF
标签的场景。这些情况极不可能发生,但需要注意并做好准备。 One of them 具有以下组件:
所以设置它有点像闯入诺克斯堡,但一定要注意。例如,OpenID Connect 或 OAuth 授权提供者应该最有可能标记注册重定向 URL 的客户端,指向其他客户端也注册的重定向 URL。
【问题讨论】:
如果你不使用cookies你用什么? JWT 和 XHR / REST 请求。 Authorization 标头将包含 JWT 令牌。它由创建请求的 javascript 代码放在 XHR 请求上。 你如何通过 JWT?每次你都会在客户端创建一个令牌或重复使用它? 您最初从 OpenID Connect 提供者/OAuth 授权服务器获取 JWT,并将其存储在本地或会话存储中。当您创建 api 请求时,令牌会从本地存储中读取并包含在 Authorization 标头中。 @Ole 那么你不能使用 HttpOnly 并让自己面临更大的 XSS 攻击类别。正确构建您的应用程序(通过要求对不安全操作使用正确的方法)更好。 【参考方案1】:最常见/通常讨论的CSRF Cross Site Request Forgery 场景只有在浏览器存储凭据(作为 cookie 或基本身份验证凭据)时才会发生。
OAuth2 实现(客户端和授权服务器)必须小心 CSRF 攻击。 CSRF 攻击可能发生在客户端的重定向 URI 和授权服务器上。根据specification (RFC 6749):
针对客户端重定向 URI 的 CSRF 攻击允许攻击者 注入自己的授权码或访问令牌,可以 导致客户端使用与 攻击者的受保护资源,而不是受害者的(例如,保存 受害者的银行账户信息到受保护的资源 由攻击者控制)。
客户端必须为其重定向 URI 实施 CSRF 保护。 这通常通过要求将任何请求发送到 重定向 URI 端点以包含将请求绑定到的值 用户代理的身份验证状态(例如,会话的哈希 cookie 用于验证用户代理)。客户应该 利用“状态”请求参数将此值传递给 发出授权请求时的授权服务器。
[...]
针对授权服务器授权的 CSRF 攻击 端点可以导致攻击者获得最终用户授权 对于恶意客户端,无需涉及或提醒最终用户。
授权服务器必须为其实施 CSRF 保护 授权端点并确保恶意客户端无法 在不知情和明确同意的情况下获得授权 资源所有者
【讨论】:
对,但是网站如何允许请求发生?我的理解是标识会话的 cookie 必须与恶意请求一起传递。如果该 cookie 不存在,则无法识别会话,并且不会造成任何伤害?所以看起来有两个组件两个 CSRF 攻击。一种 cookie,用于标识与攻击目标域的浏览器会话以及执行攻击的方法(如图像 href、锚点等)。 是的,cookie 是与用户被欺骗发送的精心制作的请求一起发送的。 如果没有那个cookie,攻击就不会发生吗?因此,只要服务器不发送 Set-Cookie: session = ... 身份验证标头,我们就永远不会受到 CSRF 攻击? 在某些应用程序中,会话 ID 在 url 中。在这种情况下,网站中的恶意 url 可以被视为没有 cookie 的 CSRF。 在 URL 中放置会话 ID 是否需要客户端执行放置它的逻辑?换句话说,攻击者不会事先知道会话 id,所以他们不能把它放在执行攻击的链接中?【参考方案2】:理论上,CSRF 与身份验证方法无关。如果攻击者可以让受害者用户在另一个应用程序中执行受害者不想要的操作,那么该应用程序很容易受到 CSRF 的攻击。
这可以通过多种方式表现出来,最常见的是受害者用户访问恶意网站,该网站反过来从受害者的浏览器向另一个应用程序发出请求,从而执行用户不想要的操作。如果凭据是由受害者浏览器自动发送的,那么这种方式是可能的。到目前为止,最常见的场景是会话 cookie,但也可能有其他场景,例如 HTTP Basic auth(浏览器也会记住这一点),或域中的 Windows 身份验证(Kerberos/SPNEGO),或客户端证书,或在某些情况下甚至是某种 SSO。
有时应用程序身份验证是基于 cookie 的,所有非 GET(POST、PUT 等)请求都受到 CSRF 保护,但 GET 并非出于显而易见的原因。在像 php 这样的语言中,很容易将原本是 POST 请求的调用也用作 GET(想想在 PHP 中使用 $_REQUEST
)。在这种情况下,任何其他网站都可以包含 <img src='http://victim.com/performstuff&param=123>
之类的内容,以静默执行操作。
在复杂系统或流程中也存在不太明显的 CSRF 攻击,例如 CSRF attacks against oauth。
因此,如果 Web 应用程序使用 say 令牌(作为请求标头发送,而不是会话 cookie)进行身份验证,这意味着客户端必须将令牌添加到每个请求中,这可能不容易受到攻击对于 CSRF,但一如既往,魔鬼在细节中。
【讨论】:
谢谢-那里有一些不错的信息!基本的 auth 评论也很有帮助/需要注意。我的最终目标是确保在使用 JWT 令牌的 openid 连接实现中没有任何安全漏洞。 也感谢 OAuth 攻击链接 - Dave 是最棒的!以上是关于揭开 CSRF 的神秘面纱?的主要内容,如果未能解决你的问题,请参考以下文章