Прослушивание всех событий отправки формы и выполнение функции перед любыми другими подключенными обработчиками событий - PullRequest
1 голос
/ 18 октября 2011

Я пытаюсь предотвратить атаки CSRF в существующем крупном веб-приложении. Я выбрал токен, который вставляется с использованием JS в любую форму, и фильтр сервлетов Java, который проверит его наличие, прежде чем разрешить продолжить запрос. Во-первых, мы рады, что у пользователя есть JS.

Во-вторых - как мне это сделать?

Самая простая идея: $(document).live("submit", myTokenAddFn); не работает.

Часть ввода токена оказывается очень сложной, поскольку, как я уже сказал, веб-приложение очень велико, и есть несколько мостов для пересечения:

  • Существуют формы, которые создаются (используя JS) после загрузки страницы
  • Мы используем JSF (который имеет атрибуты onclick на тегах привязки для отправки форм)
  • Существуют случаи отправки форм jQuery с использованием AJAX
  • Существует множество обработчиков onclick, прикрепленных к элементам отправки формы

Я чувствую, что я очень близок, но не могу поверить, что не влияю на производительность в медленных браузерах. Я начинаю думать, что мог бы быть лучший способ.

Что я сделал:

  • Чтобы преодолеть отправку jQuery AJAX-форм: Использование метода ajaxSend для добавления моего токена к значениям реальных данных перед отправкой запроса AJAX
  • Чтобы добавить токен в простые элементы формы на странице, которые присутствуют при загрузке страницы: При загрузке страницы эффективно переберите формы и добавьте токен, затем добавьте jQuery data , который говорит, что эта форма имеет маркер (для улучшения производительности следующего шага)
  • Для преодоления динамически создаваемых форм: $("input[type='submit'],input[type='image'],button,a[onclick]").live("mousedown", myTokenAddFn); Вышеприведенная строка отлично справляется со своей задачей, и «myTokenAddFn» фактически просто перебирает страницу снова, ища все формы, в которых нет элемента данных jQuery, который я добавил при загрузке страницы. Он справляется с формами JSF, которые отправляются с атрибутом onclick тега привязки, кнопками, которые не находятся в форме, но отправляют форму, и гарантирует, что токен всегда добавляется до того, как какой-либо другой обработчик onclick отправит форму (которая может присутствовать) .

Последний выпуск:

Форма JS динамически добавляется на страницу, и пользователь отправляет ее с помощью клавиши ввода, когда курсор находится в поле ввода текста. Пользователь (благодаря моему сервлету Java) вышел из системы.

Самое простое решение - включить прослушивание клавиш для всех элементов ввода, но удар по производительности меня беспокоит.

Есть предложения? Идеи для нового старта?

Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 18 октября 2011

Вместо того, чтобы слишком много возиться со структурой HTML, я создал другой подход.Установите cookie до того, как страница будет выгружена, и проверьте наличие и действительность cookie на стороне сервера.

$(window).unload(function(){
    //30 seconds SHOULD be enough to connect to the server
    document.cookie = "crf=" + myTokenAddFn() + "; max-age=30";
});
1 голос
/ 13 июня 2013

В более новых версиях 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/

Посмотрите, как Адди Османи справляется с захватом тегов привязки.

1 голос
/ 18 октября 2011

В вашей простой идее вы привязываете событие к document, но я бы привязал прослушиватель в реальном времени к "form" - выбору всех тегов формы. Кроме того, в прослушивателе событий просто добавьте e.preventDefault(). Вот так:

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

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

Я уже делал вышеупомянутый метод на моих формах, и, похоже, он работает нормально. Надеюсь, это сработает!

РЕДАКТИРОВАТЬ: Я просто хотел убедиться, что это действительно работает, , так что вот быстрый пример . Как видите, он блокирует отправку на google.com и вспыхивает с надписью "Нет!" чтобы показать, что представление было заблокировано.

...