【发布时间】:2018-07-11 07:25:49
【问题描述】:
我正在努力解决我的 React/Phoenix 应用程序中的 CSRF 漏洞,在我看来我的应用程序是安全的......但我不是这些问题的专家,我想求助于社区看看我是否忽略了某些事情或者我太天真了。
Phoenix 是一个纯 API,与 React 客户端分开运行,所以我正在处理 CORS - 允许来源的白名单在 Phoenix router.ex 中设置:
pipeline :api do
plug CORSPlug, [origin: "localhost:3000"]
plug :accepts, ["json"]
plug Guardian.Plug.VerifyHeader, realm: "Bearer"
plug Guardian.Plug.LoadResource
end
如您所见,我正在使用 Guardian(它使用 JWT 进行用户身份验证)来处理授权。
授权客户端将 JWT 存储在 localStorage 中,而 Guardian 设置为在请求的 Authorization 标头中查找该值作为 Bearer... 受保护的 Phoenix 控制器包括:
plug Guardian.Plug.EnsureAuthenticated
我设置了一个测试攻击者,在 localhost:5000 上运行以尝试模拟 CSRF 攻击。首先,我尝试了 AJAX 攻击——我从登录窗口的localStorage 复制了一个有效的 JWT 值,并将其设置在我的模拟攻击者的请求标头中。正如预期的那样,这失败了,因为localhost:5000 没有被列入白名单
The 'Access-Control-Allow-Origin' header contains the invalid value 'null'. Origin 'http://localhost:5000' is therefore not allowed access.
为了测试,我将localhost:5000 添加到 Phoenix 白名单中,并且请求确实有效......所以看起来,即使攻击者设法窃取了有效的 JWT,他们也会被白名单阻止。
然后我测试了一个从 OWASP 文档借来的自动表单提交:
<body onload='document.CSRF.submit()'>
<form action='http://localhost:4000/api/v1/user' method='POST' name='CSRF'>
<input type='hidden' name='name' value='Hacked'>
<input type='hidden' name='password' value='Hacked'>
</form>
<body>
但这会被 API 控制器中设置的Guardian.Plug.EnsureAuthenticated 捕获,因为没有Authorization 标头,也没有有效的 JWT:
[info] POST /api/v1/user
[debug] Processing with MyApp.UserController.create/2
Parameters: %{"name" => "Hacked", "password" => "[FILTERED]"}
Pipelines: [:api]
[info] Sent 401 in 21ms
[debug] MyApp.UserController halted in
Guardian.Plug.EnsureAuthenticated.call/2
所以我的印象是,即使使用有效的 JWT,AJAX 攻击也会失败,因为 CORS 白名单......简单的请求会失败,因为它们不包含 Authorization 标头。
在使用 JWT 进行授权时,我已经阅读了很多关于 CSRF 保护的内容,但似乎没有两个人可以就什么是安全的和不安全的达成一致。我是否遗漏了什么,或者 CORS 白名单和 Guardian JWT 检查的组合足以保护 CSRF?
【问题讨论】:
标签: security jwt csrf phoenix-framework