在所有其他附加事件处理程序之前,监听所有表单提交事件并执行功能

时间:2011-10-18 13:43:50

标签: java javascript jquery csrf

我正在尝试阻止现有大型网络应用中的CSRF攻击。我选择了一个使用JS注入任何形式的令牌和一个Java Servlet过滤器,它将在允许请求继续之前检查它的存在。首先,我们很高兴要求用户拥有JS。

其次 - 我该怎么做?

最简单的想法:$(document).live("submit", myTokenAddFn);不起作用。

令牌注入部分证明非常棘手,因为正如我所说,网络应用程序非常庞大,并且有许多桥梁要跨越:

  • 在页面加载
  • 后,有一些表单(使用JS)
  • 我们使用JSF(在锚标签上有onclick属性来提交表单)
  • 有使用AJAX提交jQuery表单的实例
  • 已经有很多onclick处理程序附加到表单提交元素

我觉得我非常接近,但我无法相信我不会在较慢的浏览器上影响性能。我开始认为可能有更好的方法。

我做了什么:

  • 要克服jQuery AJAX表单提交:使用ajaxSend方法在发送AJAX请求之前将我的令牌附加到实际数据值
  • 要将令牌添加到页面加载页面上的简单表单元素:页面加载有效地循环表单并添加令牌,然后添加jQuery data此表单具有令牌(以提高下一步的性能)
  • 要克服动态创建的表单:$("input[type='submit'],input[type='image'],button,a[onclick]").live("mousedown", myTokenAddFn); 上面的行处理很多,'myTokenAddFn'实际上只是循环遍历页面,寻找所有没有我在页面加载时添加的jQuery数据项的表单。 它处理使用锚标记的onclick属性提交的JSF表单,不包含在表单中但提交表单的按钮,并确保在任何其他onclick处理程序提交表单(可能存在)之前始终添加令牌

最新一期:

将JS表单动态添加到页面中,当光标位于输入文本字段中时,用户使用回车键提交它。用户(感谢我的Java Servlet)已注销。

最简单的解决方法是将keypress侦听器包含在所有输入元素中,但这里的性能让我感到担忧。

有什么建议吗?重新开始的想法?

提前致谢。

3 个答案:

答案 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如何处理劫持锚标签。