我试图了解CSRF的整个问题以及预防它的适当方法.(资源我已阅读,理解并同意:OWASP CSRF预防报告表,关于CSRF的问题.)
据我了解,CSRF的漏洞是通过假设(从网络服务器的角度来看)传入HTTP请求中的有效会话cookie反映经过身份验证的用户的意愿而引入的.但是,原始域的所有cookie都被浏览器神奇地附加到请求上,因此实际上所有服务器都可以通过请求中存在的有效会话cookie来推断该请求来自具有经过身份验证的会话的浏览器; 它无法进一步假设该浏览器中运行的代码,或者它是否真正反映了用户的意愿.防止这种情况的方法是在请求中包含其他身份验证信息("CSRF令牌"),这些信息由浏览器的自动cookie处理以外的某些方式携带.然后,松散地说,会话cookie验证用户/浏览器,并且CSRF令牌验证在浏览器中运行的代码.
简而言之,如果您使用会话cookie来验证Web应用程序的用户,您还应该为每个响应添加一个CSRF令牌,并在每个(变异)请求中要求匹配的CSRF令牌.然后,CSRF令牌从服务器到浏览器进行往返回服务器,向服务器证明发出请求的页面是由该服务器批准(甚至由该服务器生成).
关于我的问题,这是关于在该往返中用于该CSRF令牌的特定传输方法.
看起来很常见(例如在AngularJS,Django,Rails中)将CSRF令牌从服务器发送到客户端作为cookie(即在Set-Cookie头中),然后让客户端中的Javascript将其从cookie中删除并附加它作为单独的XSRF-TOKEN标头发送回服务器.
(另一种方法是由例如Express推荐的方法,其中由服务器生成的CSRF令牌通过服务器端模板扩展包含在响应主体中,直接附加到将其提供回服务器的代码/标记,例如作为一个隐藏的表单输入.这个例子是一个更多的Web 1.0-doh的做事方式,但是可以很好地推广给更多JS的客户端.)
为什么使用Set-Cookie作为CSRF令牌的下游传输是如此常见/为什么这是一个好主意?我想所有这些框架的作者都仔细考虑了他们的选择,并没有弄错.但乍一看,使用cookie解决基本上对cookie的设计限制似乎很愚蠢.实际上,如果您使用cookie作为往返传输(Set-Cookie:服务器的下游标头告诉浏览器CSRF令牌,而Cookie:上游标题,浏览器将其返回给服务器)您将重新引入漏洞正试图解决.
我意识到上面的框架不会使用cookie来进行CSRF令牌的整个往返; 他们使用Set-Cookie下游,然后在上游使用其他东西(例如X-CSRF-Token标头),这确实可以关闭漏洞.但即使使用Set-Cookie作为下游传输也可能具有误导性和危险性; 浏览器现在将CSRF令牌附加到每个请求,包括真正的恶意XSRF请求; 充其量只会使请求变得比它需要的更大,而在最坏的情况下,一些善意但误导的服务器代码实际上可能会尝试使用它,这将是非常糟糕的.此外,由于CSRF令牌的实际预期接收者是客户端Javascript,这意味着此cookie不能仅使用http保护.因此,在Set-Cookie标头中向下游发送CSRF令牌对我来说似乎非常不理想.
我正在尝试为基于ajax的登录表单确定最安全的方法来进行身份验证并设置客户端cookie.我见过有关XSS攻击的事情,比如:
和
http://www.codinghorror.com/blog/archives/001167.html
所以,我想我的核心问题是......
1)使用纯粹的ajax来设置cookie是否安全,如果是,那么最安全的方法是什么(httpOnly + SSL +加密值等)?
2)纯粹的ajax方法是否涉及设置cookie客户端?这一切都安全吗?
3)在所有主流浏览器/操作系统中以这种方式设置cookie是否可靠?
4)使用隐藏的IFrame是否更安全(调用网页来设置cookie)?
5)如果可能的话,是否有人为此编写代码(PHP是我的后端)?
我的目标是设置cookie并让它们可用于下次调用服务器而无需离开页面.
我真的想要确定共识,最安全的方式来做到这一点.最终,这个代码计划成为开源的,所以请不要使用商业代码(或者没有任何不能经得起公众监督的代码)
谢谢, - 托德
我想知道,当我使用jQuery 创建$ .post(...)时,是否在发布请求中将任何cookie发送到服务器?
谢谢!
我必须将一些私人数据从服务器发送到浏览器。我想把它存储在cookie中。该数据稍后将在 Javascript 代码中使用。但当浏览器执行 HTTP 请求时(出于安全考虑),我想永远不会(!)将此私有数据发送到服务器。我知道我可以在 cookie 中设置“路径”值(即某个抽象路径),但随后我将无法读取此 cookie(我将能够从此抽象路径读取,但如果是这样,浏览器将无法读取该 cookie)将此 cookie 发送到服务器一次 - 但正如我所说,此数据无法发送到服务器)。
所以,我的问题是:是否有可能不通过 HTTP 请求发送 cookie?
我找到了这个链接
但在最下方则说此信息可能不再是最新的。 所以我的问题是,将使用AJAX发送http_only cookie吗?可以通过AJAX响应设置http_only cookie吗?
编辑1:假设有一个用户登录到系统。他的会话开始,并且设置了http_only cookie。他尝试通过AJAX获取朋友列表并发送JSON。发出AJAX请求时,我是否需要特别说明要发送或不发送Cookie?默认情况下,每个请求都会将cookie发送到服务器吗?响应会发回Cookie吗(假设我正在更新用户的上次活动时间)?