侦听所有表单提交事件并在任何其他附加事件处理程序之前执行函数

发布于 2024-12-11 00:16:49 字数 1453 浏览 0 评论 0原文

我正在尝试防止现有大型网络应用程序中的 CSRF 攻击。我选择使用 JS 将令牌注入到任何表单中,并选择一个 Java Servlet 过滤器,该过滤器将在允许请求继续之前检查其存在。首先我们很高兴要求用户拥有 JS。

其次 - 我该怎么做?

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

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

  • 页面加载后(使用 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 表单动态添加到页面,用户在光标位于输入文本字段时使用 Enter 键提交它。用户(感谢我的 Java Servlet)已注销。

最简单的解决方法是将按键监听器包含到所有输入元素中,但这里的性能影响让我担心。

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

提前致谢。

I'm trying to prevent CSRF attacks in a an existing large web app. I've opted for a token that is injected using JS into any form and a Java Servlet filter that will check for its presence before allowing the request to continue. Firstly we are happy to require the user has JS.

Secondly - how do I do it?

The simplest idea: $(document).live("submit", myTokenAddFn); doesn't work.

The token injection part is proving very tricky since, as I said, the web app is very large, and there a number of bridges to cross:

  • There are forms that are created (using JS) after the page has loaded
  • We make use of JSF (which has onclick attributes on anchor tags to submit forms)
  • There are instances of jQuery form submits using AJAX
  • There are plenty of onclick handlers attached to form submit elements already

I feel I am very close but I can't believe I'm not impacting performance on slower browsers. I am starting to think that there might be a better way.

What I have done:

  • To overcome jQuery AJAX form submissions: Using the ajaxSend method to append my token to the real data values before the AJAX request is sent
  • To add the token to simple form elements on the page that are there on page load: On page load effectively loop through forms and add the token, then add jQuery data that says this form has the token (to improve performance of next step)
  • To overcome dynamically created forms: $("input[type='submit'],input[type='image'],button,a[onclick]").live("mousedown", myTokenAddFn);
    The above line copes with a lot and the 'myTokenAddFn' actually just loops through the page again looking for all forms that don't have the jQuery data item I added on page load.
    It copes with JSF forms that are submitted with an anchor tag's onclick attribute, buttons that don't reside in a form but submit a form and ensures that the token is always added before any other onclick handler submits the form (that might be present).

The latest issue:

A JS form is dynamically added to the page and the user submits it using the enter key while the cursor is in an input text field. The user (thanks to my Java Servlet) is logged out.

The easiest fix would be to include keypress listeners to all input elements, but the performance hit here worries me.

Any suggestions? Ideas for a fresh start?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

生寂 2024-12-18 00:16:49

在您的简单想法中,您将事件绑定到 document,但我将实时侦听器绑定到 "form" - 选择所有表单标签。另外,在事件监听器中,只需添加e.preventDefault()。就像这样:

$("form").live("submit", submitListener);

function submitListener(e) {
   // your handling stuff goes here
   e.preventDefault();
}

我之前在我的表单上完成了上述方法,它似乎工作得很好。希望这能起到作用!

编辑:我只是想确保这确实有效,所以这是一个简单的示例 。正如您所看到的,它会阻止向 google.com 的提交,并闪烁显示“不!”显示提交被阻止。

In your simple idea, you're binding the event to document, but I'd bind the live listener to "form" - selecting all form tags. Also, in the event listener, just add e.preventDefault(). Like so:

$("form").live("submit", submitListener);

function submitListener(e) {
   // your handling stuff goes here
   e.preventDefault();
}

I've done the above method on my forms before and it seems to work fine. Hope this does the trick!

EDIT: I just wanted to be sure this actually works, so here's a quick example. As you can see, it blocks the submission to google.com and flashes up with a "nope!" to show the submission was blocked.

梨涡 2024-12-18 00:16:49

我没有过多地搞乱 HTML 结构,而是创建了另一种方法。在页面卸载之前设置cookie,并在服务器端检查cookie的存在性和有效性。

$(window).unload(function(){
    //30 seconds SHOULD be enough to connect to the server
    document.cookie = "crf=" + myTokenAddFn() + "; max-age=30";
});

Instead of messing too much with the HTML structure, I've created another approach. Set a cookie before the page unloads, and perform a check on the existence and validity of the cookie at the server's side.

$(window).unload(function(){
    //30 seconds SHOULD be enough to connect to the server
    document.cookie = "crf=" + myTokenAddFn() + "; max-age=30";
});
月下客 2024-12-18 00:16:49

使用较新版本的 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 如何处理劫持锚标记。

With newer versions of jQuery:

$(document).on("submit", "form", function(e){ 
    e.preventDefault(); 
});  

With newer versions of jQuery, but allowing form submissions on forms that have data-bypass:

$(document).on("submit", "form:not([data-bypass])", function(e){ 
    e.preventDefault(); 
}); 

Reference:

http://addyosmani.github.io/backbone-fundamentals/

Look how Addy Osmani handles hijacking anchor tags.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文