我正在尝试阻止现有大型网络应用中的CSRF攻击。我选择了一个使用JS注入任何形式的令牌和一个Java Servlet过滤器,它将在允许请求继续之前检查它的存在。首先,我们很高兴要求用户拥有JS。
其次 - 我该怎么做?
最简单的想法:$(document).live("submit", myTokenAddFn);
不起作用。
令牌注入部分证明非常棘手,因为正如我所说,网络应用程序非常庞大,并且有许多桥梁要跨越:
我觉得我非常接近,但我无法相信我不会在较慢的浏览器上影响性能。我开始认为可能有更好的方法。
我做了什么:
$("input[type='submit'],input[type='image'],button,a[onclick]").live("mousedown", myTokenAddFn);
上面的行处理很多,'myTokenAddFn'实际上只是循环遍历页面,寻找所有没有我在页面加载时添加的jQuery数据项的表单。
它处理使用锚标记的onclick属性提交的JSF表单,不包含在表单中但提交表单的按钮,并确保在任何其他onclick处理程序提交表单(可能存在)之前始终添加令牌最新一期:
将JS表单动态添加到页面中,当光标位于输入文本字段中时,用户使用回车键提交它。用户(感谢我的Java Servlet)已注销。
最简单的解决方法是将keypress侦听器包含在所有输入元素中,但这里的性能让我感到担忧。
有什么建议吗?重新开始的想法?
提前致谢。
答案 0 :(得分:1)
在您的简单想法中,您将事件绑定到document
,但我将实时监听器绑定到"form"
- 选择所有表单标记。此外,在事件监听器中,只需添加e.preventDefault()
。像这样:
$("form").live("submit", submitListener);
function submitListener(e) {
// your handling stuff goes here
e.preventDefault();
}
我以前在我的表单上完成了上面的方法,似乎工作正常。希望这可以解决问题!
编辑:我只是想确定这确实有效,so here's a quick example。正如您所看到的,它阻止了向google.com的提交,并闪现了“不!”显示提交被阻止。
答案 1 :(得分:1)
我没有过多地使用HTML结构,而是创建了另一种方法。在页面卸载之前设置一个cookie,并在服务器端检查cookie的存在和有效性。
$(window).unload(function(){
//30 seconds SHOULD be enough to connect to the server
document.cookie = "crf=" + myTokenAddFn() + "; max-age=30";
});
答案 2 :(得分:1)
使用更新版本的jQuery:
$(document).on("submit", "form", function(e){
e.preventDefault();
});
使用更新版本的jQuery,但允许在具有数据旁路的表单上提交表单:
$(document).on("submit", "form:not([data-bypass])", function(e){
e.preventDefault();
});
参考:
http://addyosmani.github.io/backbone-fundamentals/
看看Addy Osmani如何处理劫持锚标签。