我对 CSRF 保护非常陌生,所以如果我做出错误的假设或遗漏了什么,请原谅,但我想确保我正在尽我所能来防止 CSRF。从我到目前为止的研究中,我发现了以下内容:
- CSRF 可以通过在所有 HTML POST 的请求正文中放置一个 nonce 参数来阻止(并且可能是最好的阻止),仅使用 POST 修改数据,并在服务器端验证令牌在处理请求之前是否有效。
- 恶意网站可以向我的网站发送请求(被随机数阻止),但由于浏览器上的同源策略,它们无法读取响应。假设有人使用安全浏览器,恶意站点无法使用 AJAX 从我的站点获取页面、读取随机数并将其用于自己。
- 在大多数(可能是任何)浏览器中,脚本标签不受同源策略的约束,因此可以允许从其他站点读取内容。
当我到达第 3 点时,我决定尝试使用 JSONP 在 Chrome 中获取 HTML 内容;我打开了我的控制台(页面不是来自本地主机)并运行以下代码:
$.ajax({
url: "http://localhost:8080/my-app/",
dataType: "jsonp",
jsonp: "alert"
}).done(function(data) {
alert(data);
});
我在控制台窗口中收到的是:
资源解释为脚本,但使用 MIME 类型 text/html 传输
据我所知,浏览器本质上是在告诉我它收到了内容,继续解析响应,但由于类型不是 application/json 而停止。所以最后,我的问题是,这可以妥协吗?尽管浏览器未能将响应解析为 JSON,但它确实有响应。有没有办法可以将此响应解析为 HTML,获取我的 CSRF 随机数,并破坏我试图强制执行的保护?在我看来(我希望这是真的)浏览器不允许这样做,就像他们首先不允许跨域请求进行基本上所有其他通信一样,这就是我们作为开发人员所依赖的(除了同源政策)来保护我们的网站。我的想法正确吗?