我有一个网页,可以在用户访问该页面时跟踪他们。这是一个“个人资料页面”,如果有人访问您的“个人资料页面”,他的访问将被跟踪,您将收到通知。
这类似于跟踪个人资料视图的stackoverflow's profile page(虽然细节不同)。只要唯一身份访问者访问您的个人资料页面,配置文件视图计数器就会递增。
我使用存储在浏览器cookie中的随机生成的令牌对用户进行身份验证。这就是我有一个很大的CSRF问题,因为任何随机网站都可以代表我的用户访问网页,而不知道。例如,攻击者的网页可能只是嵌入了iframe或图像,指向我的网页:
<img src="http://mysite.com/profile-page">
or
<iframe src="http://mysite.com/profile-page"></iframe>
每当我的用户访问攻击者的网页时,他们就会在没有他们知道的情况下访问某个人的个人资料页面(然后会记录访问)。
让我用一个具体的例子来证明我的观点:
如今,许多网站都允许用户发布图片网址。用户可以发布如下图像:
<img src="https://stackoverflow.com/users/632951/pacerier">
图片代码的src
确实不是图片文件,但浏览器仍会发出请求并显示空图片:
这意味着攻击者刚刚代表用户成功向https://stackoverflow.com/users/632951/pacerier发出请求,很可能用户甚至不知道。{/ p>
如Preventing CSRF and XSRF Attacks中所述,我们可以添加一些隐藏的输入字段和一个表示“您确定要请求此页面吗?”的表单。缺点是每个请求页面的真正用户现在都需要在他们访问网页之前点击按钮是,确认请求页面,这将严重破坏可用性。 我不想强迫用户点击 确认 来查看每个跟踪的网页。
还有其他更方便用户使用的方法来阻止CSRF获取请求吗?
如果网页http://mysite.com是嵌入式页面,则我们如何告诉浏览器不要请求网页{{3}}(浏览器的网址栏未显示请求的网页,这意味着它是嵌入式的图像,框架,iframe等)?
答案 0 :(得分:2)
这是一种应该相当简单和可靠的方法:
不计算对页面的请求,而是对在页面上的请求进行计数(例如,AJAX请求和/或请求)页面上的图像)。这会照顾img
黑客,因为浏览器实际上不会尝试将HTML页面呈现为图像,因此不会运行任何JavaScript或加载页面上的任何(子)图像。
在页面中添加X-Frame-Options: DENY
标题,以便浏览器也不会在iframe
中呈现它。对于旧版浏览器(或者只是作为腰带和吊带方法的一部分),您还可以在发送AJAX确认之前检查window.parent == window
的JavaScript。
最后,为了保护您从欺骗中计算 计数的(AJAX /图像)请求,请包含一个唯一的,不可预测的令牌,该令牌在每个令牌中只有一次有效。一种方法是随机生成令牌并将它们保存在数据库中(或在会话存储中),直到它们被收回(或变得太旧)。
或者,如果您不想将令牌存储在数据库中,则可以计算时间戳的MAC(例如用户的IP地址),并将两者一起发送给请求,并使用错误的MAC或陈旧的时间戳。