Comments

"2) Content-Type поддельного POST запроса может быть только application/x-www-form-urlencoded, multipart/form-data или text/plain. Опять же из-за ограничений тега form.


3) Тег form позволяет отправлять только GET/POST запросы. PUT/PATCH/DELETE/MKCOL и прочие не пропускаются."


что мешает использовать ajax? можно любой метод и content-type использовать

Кросс-доменные ajax-запросы фейлятся с ошибкой доступа, если нет плохо настроенного CORS (подставляет любой Origin из запроса в Allow-Access-Control-Origin) или других взаимодействий (postMessage от любого Origin, Flash со слабым crossdomain.xml, т.д.). Всё это отдельные баги, без которых кросс-доменные ajax-запросы невозможны.
Их «фейлит» браузер, не дает прочитать ответ js скрипту (он и не нужен), но сервер обрабатывает запрос как нормальный, если нет csrf защиты. Так что не стоит полагаться, что ajax защитит от csrf.
Можно совершать ajax-запросы без префлайта только для случаев, когда этот же сценарий мог быть совершен через тэг form. Для всего остального совершается префлайт и запрос зафейлится на нём, если нет плохо настренного CORS'а. Т.к. вектор этой атаки — браузер, то встроенная защита работает и защищает от CSRF.

Примеры: GET with credentials — совершится, т.к. это то же самое, что подгрузка картинки с другого домена (находимся на example.com, где есть img src=«www.example2.com/favicon.ico» — в GET-запросе к картинке будут куки пользователя от example2.com)

POST with credentials — совершаются, но только с Content-Type: text/plain, multipart/form-data, application/x-www-form-urlencoded. Если сделать POST with credentials с Content-Type: application/json, запрос зафейлится на префлайте.

PUT, PATCH, DELETE… — требуют префлайт, то же самое.
Only those users with full accounts are able to leave comments. Log in, please.