CORS - Какова мотивация введения предварительных запросов?


366

Обмен ресурсами между источниками - это механизм, позволяющий веб-странице отправлять запросы XMLHttp в другой домен (из Википедии ).

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

Так что мой вопрос не о том, как работает CORS / preflight, а о причине, по которой я выбрал preflights в качестве нового типа запроса . Я не вижу никакой причины, по которой серверу A необходимо отправлять предварительную проверку (PR) на сервер B, чтобы выяснить, будет ли принят реальный запрос (RR) или нет - B, безусловно, сможет принять / отклонить RR без любой предыдущий пиар.

После долгих поисков я нашел эту информацию на сайте www.w3.org (7.1.5):

Чтобы защитить ресурсы от запросов перекрестного происхождения, которые не могли быть отправлены определенными пользовательскими агентами до того, как эта спецификация существовала, делается предварительный запрос, чтобы гарантировать, что ресурс осведомлен об этой спецификации.

Я считаю, что это самое трудное для понимания предложение. Моя интерпретация (лучше назвать это «предположение») заключается в том, что речь идет о защите сервера B от запросов от сервера C, который не знает о спецификации.

Может кто-нибудь объяснить сценарий / показать проблему, которую PR + RR решает лучше, чем один RR?

Ответы:


323

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

Ключевым моментом является то, что предварительные запросы не являются предметом безопасности . Скорее, они не меняют правила .

Предварительные запросы не имеют ничего общего с безопасностью, и они не имеют отношения к приложениям, которые разрабатываются сейчас, с учетом CORS. Скорее, механизм предварительной проверки полезен для серверов, которые были разработаны без знания CORS, и он функционирует как проверка работоспособности между клиентом и сервером, что они оба поддерживают CORS. Разработчики CORS чувствовали, что было достаточно серверов, которые полагались на предположение, что они никогда не получат, например, междоменный запрос DELETE, что они изобрели механизм предварительной проверки, чтобы обе стороны могли принять участие. Они чувствовали, что альтернатива, которая состояла бы в простой активации междоменных вызовов, сломала бы слишком много существующих приложений.

Здесь есть три сценария:

  1. Старые серверы, которые больше не разрабатываются и разработаны до появления CORS. Эти серверы могут предполагать, что они никогда не получат, например, междоменный запрос DELETE. Этот сценарий является основным бенефициаром предполетного механизма. Да, эти сервисы уже могут быть использованы злонамеренным или несоответствующим пользовательским агентом (и CORS ничего не меняет), но в мире с CORS механизм предварительной проверки обеспечивает дополнительную «проверку работоспособности», чтобы клиенты и серверы не могли перерыв, потому что основные правила в Интернете изменились.

  2. Серверы, которые все еще находятся в стадии разработки, но содержат много старого кода и для которых нецелесообразно / нежелательно проводить аудит всего старого кода, чтобы убедиться, что он работает должным образом в междоменном мире. Этот сценарий позволяет серверам постепенно подключаться к CORS, например: «Теперь я разрешу этот конкретный заголовок», «Теперь я разрешу этот конкретный HTTP-глагол», «Теперь я позволю куки-файлам / информации об аутентификации быть отправлено "и т. д. Этот сценарий использует механизм предварительной проверки.

  3. Новые серверы, которые написаны с осознанием CORS. Согласно стандартной практике безопасности, сервер должен защищать свои ресурсы перед любым входящим запросом - серверы не могут доверять клиентам не делать злонамеренных действий. Этот сценарий не использует механизм предварительной проверки : механизм предварительной проверки не обеспечивает дополнительной безопасности для сервера, который должным образом защитил свои ресурсы.


12
Если это так, почему он отправляется на каждый запрос? Одного запроса на сервер должно быть достаточно, чтобы определить, знает ли сервер о CORS.
Дуглас Фергюсон

3
Спецификация включает в себя preflight-result-cache в браузере. Таким образом, несмотря на то, что он все еще чувствует себя неряшливым и неэффективным в плане безопасности, представляется возможным настроить новые серверы так, чтобы предварительная проверка кэшировалась бесконечно
Майкл Коул

7
Я согласен, что предварительные запросы не связаны с безопасностью, но похоже, что использование предварительных запросов CORS определенно связано с соображениями безопасности. Это больше, чем просто проверка работоспособности, чтобы предотвратить относительно безопасный сценарий ошибки. Если пользовательский агент слепо отправляет запрос на сервер, ложно предполагая, что сервер внедрил CORS, он, скорее всего, будет принимать подделки межсайтовых запросов. Даже если javascript не сможет прочитать ответ, сервер, возможно, уже предпринял некоторые нежелательные действия, такие как удаление учетной записи или банковский перевод.
Александр Тейлор

6
Проблема в том, что preflight-result-cache в основном бесполезен, потому что: 1. он применяется только к точному запросу, а не ко всему домену, поэтому все запросы будут в любом случае предварительно проверяться в первый раз; и 2. как реализовано, оно ограничено 10 минутами в большинстве браузеров, поэтому даже близко не до бесконечности.
Давидголи

2
@VikasBansal Существующий сервер должен «согласиться» и согласиться делиться своими ресурсами между источниками, настраивая, как они отвечают на запрос предварительной проверки. Если они не ответят на предварительный запрос явно, браузер не выдаст фактический запрос. В конце концов, не все серверы захотят обрабатывать перекрестные запросы.
Кевин Ли

218

Какова была мотивация введения предварительных запросов?

Предварительные запросы были введены так, чтобы браузер мог быть уверен, что он имеет дело с сервером, поддерживающим CORS, перед отправкой определенных запросов. Эти запросы были определены как потенциально опасные (с изменением состояния) и новые (невозможные до CORS из-за единой политики происхождения ). Использование запросов предварительной проверки означает, что серверы должны подписаться (путем правильного ответа на предварительную проверку) на новые, потенциально опасные типы запросов, которые CORS делает возможным.

В этом смысл этой части спецификации : «Для защиты ресурсов от запросов разных источников, которые не могли быть отправлены определенными пользовательскими агентами до того, как эта спецификация существовала, делается предварительный запрос, чтобы гарантировать, что ресурс осведомлен об этой спецификации».

Можете ли вы дать мне пример?

Давайте представим, что пользователь браузера вошел на свой банковский сайт по адресу A.com. Когда они переходят к вредоносным программам B.com, эта страница содержит некоторый Javascript, который пытается отправить DELETEзапрос A.com/account. Поскольку пользователь вошел в систему A.com, этот запрос, если он будет отправлен, будет включать файлы cookie, которые идентифицируют пользователя.

До CORS браузер Same Policy Policy блокировал бы его от отправки этого запроса. Но так как целью CORS является сделать возможным только такой тип связи между источниками, это больше не подходит.

Браузер может просто отправить DELETEи позволить серверу решить, как его обработать. Но что, если A.comне знает протокол CORS? Это может пойти дальше и выполнить опасное DELETE. Можно было бы предположить, что - из-за одинаковой политики происхождения браузера - он никогда не мог получить такой запрос, и, таким образом, он никогда не был защищен от такой атаки.

Для защиты таких серверов, не поддерживающих CORS, протокол требует, чтобы браузер сначала отправил предварительный запрос . Этот новый тип запроса - это то, на что только серверы, поддерживающие CORS, могут отвечать должным образом, позволяя браузеру узнать, безопасно ли отправлять фактическое сообщение DELETE.

Почему весь этот шум вокруг браузера, не может ли злоумышленник просто отправить DELETEзапрос со своего компьютера?

Конечно, но такой запрос не будет включать куки пользователя. Предназначенная для предотвращения атаки атака основана на том факте, что браузер будет отправлять файлы cookie (в частности, информацию об аутентификации для пользователя) для другого домена вместе с запросом.

Это звучит , как Cross-Site Request Подделка , где форма на сайте B.comбанке , POSTчтобы A.comс печеньем пользователя и нанести ущерб.

Вот так. Это можно сделать так, что предварительные запросы были созданы таким образом, чтобы не увеличивать поверхность атаки CSRF для серверов, не поддерживающих CORS.

Но, глядя на требования к «простым» запросам, которые не требуют предварительных проверок, я вижу, что POSTэто все еще разрешено. Это может изменить состояние и удалить данные, как DELETE!

Это правда! CORS не защищает ваш сайт от CSRF-атак. Опять же, без CORS вы также не защищены от CSRF-атак. Цель предварительных запросов - ограничить воздействие CSRF на то, что уже существовало в мире до CORS.

Вздох. ОК, я неохотно принимаю необходимость предварительных запросов. Но почему мы должны делать это для каждого ресурса (URL) на сервере? Сервер либо обрабатывает CORS, либо нет.

Вы уверены, что? Многочисленные серверы нередко обрабатывают запросы для одного домена. Например, это может быть случай, когда запросы A.com/url1обрабатываются одним видом сервера, а запросы A.com/url2обрабатываются другим типом сервера. Как правило, сервер, обрабатывающий один ресурс, не может гарантировать безопасность всех ресурсов в этом домене.

Хорошо. Давай пойдем на компромисс. Давайте создадим новый заголовок CORS, который позволит серверу точно указывать, за какие ресурсы он может говорить, чтобы избежать дополнительных предварительных запросов к этим URL-адресам.

Хорошая идея! На самом деле, заголовок Access-Control-Policy-Pathбыл предложен именно для этой цели. В конечном счете, однако, это было исключено из спецификации, по- видимому, потому что некоторые серверы неправильно реализовали спецификацию URI таким образом, что запросы к путям, которые казались безопасными для браузера, на самом деле не были бы безопасны на сломанных серверах.

Было ли это разумным решением, которое отдавало приоритет безопасности над производительностью, позволяя браузерам немедленно внедрять спецификацию CORS, не подвергая риску существующие серверы? Или было недальновидно обречь интернет на потерю пропускной способности и удвоить задержку, просто чтобы учесть ошибки на конкретном сервере в определенное время?

Мнения расходятся.

Ну, по крайней мере, браузеры будут кэшировать предпечатную проверку для одного URL?

Да. Хотя, вероятно, не очень долго. В браузерах WebKit максимальное время кеширования перед полетом в настоящее время составляет 10 минут .

Вздох. Что ж, если я знаю, что мои серверы поддерживают CORS и, следовательно, не нуждаются в защите, предоставляемой предварительными запросами, есть ли способ избежать их?

Ваш единственный реальный вариант - убедиться, что вы соответствуете требованиям «простых» запросов. Это может означать исключение пользовательских заголовков, которые вы в противном случае включили бы (например X-Requested-With), ложь о Content-Typeили больше.

Что бы вы ни делали, вы должны убедиться в наличии надлежащих средств защиты CSRF, поскольку в спецификации CORS не рассматриваются отклонения «простых» запросов, в том числе небезопасных POST. Как сказано в спецификации : «ресурсы, для которых простые запросы имеют значение, отличное от извлечения, должны защищать себя от подделки межсайтовых запросов».


21
Это лучшая вводная часть, которую я читал на CORS. Спасибо!
Кив

5
Потрясающе объяснил.
Пратц

4
Это лучший ответ, который я видел по теме. Очень хорошо объяснил!
Алабуди

3
CORS - сложный материал, и этот пост проливает свет на некоторые скрытые моменты
Станислав Вержиковский

1
@Yos: браузер будет включать эти куки, потому что именно так должны работать браузеры (как кодифицировано в стандартах, таких как RFC 6265 ). Независимо от того, использует ли браузер отдельные процессы для вкладок, это деталь реализации, это не помешает ему отправлять куки.
Кевин Кристофер Генри

51

Рассмотрим мир междоменных запросов до CORS. Вы можете сделать стандартную форму POST или использовать тег scriptили imageдля выдачи запроса GET. Вы не могли сделать какой-либо другой тип запроса, кроме GET / POST, и не могли выдавать пользовательские заголовки для этих запросов.

С появлением CORS авторы спецификаций столкнулись с проблемой внедрения нового междоменного механизма без нарушения существующей семантики сети. Они решили сделать это, предоставив серверам возможность подписаться на любой новый тип запроса. Это согласие является предварительным запросом.

Таким образом, запросы GET / POST без каких-либо пользовательских заголовков не нуждаются в предварительной проверке, поскольку эти запросы уже были возможны до CORS. Но любой запрос с помощью пользовательских заголовков или PUT / DELETE запросов, действительно нужен предполетный, так как они являются новыми для CORS спецификации. Если сервер ничего не знает о CORS, он ответит без заголовков, специфичных для CORS, и фактический запрос не будет выполнен.

Без предварительного запроса серверы могут начать видеть неожиданные запросы от браузеров. Это может привести к проблеме безопасности, если серверы не будут подготовлены к этим типам запросов. Предварительная проверка CORS позволяет междоменным запросам безопасно вводиться в Интернет.


Как сделать запрос POST через скрипт / тег img?
причудливый

2
Ты не можешь Я имел в виду , что вы можете либо сделать форму POST, или сделать GET с помощью сценария / IMG. Я отредактировал пост, чтобы уточнить это.
monsur

Понимаю. В этом есть смысл.
причудливый

5
Спасибо за ответ, который, безусловно, завершил мою картину! К сожалению, я до сих пор не вижу центральную точку предполетных полетов. Относительно вашего ответа: каким будет « неожиданный запрос »? Как это может быть «более» неожиданным / менее безопасным в мире без предварительной проверки, чем в мире предварительной проверки (например, с потерянной предварительной проверкой или вредоносным браузером, который просто «забывает» о предварительной проверке)?
Ян Грот

7
Вероятно, существуют API-интерфейсы, которые полагаются на политику браузера того же происхождения для защиты своих ресурсов. Они должны иметь дополнительную безопасность, но вместо этого они полагаются на политику того же происхождения. Без предварительной проверки пользователь в другом домене теперь может отправить запрос в API. API будет считать запрос действительным (поскольку он ничего не знает о CORS) и выполнит запрос. Браузер может заблокировать ответ от достижения пользователя, но на этом этапе ущерб уже может быть нанесен. Если запрос был PUT / DELETE, ресурс мог быть обновлен или удален.
Монсур

37

CORS позволяет вам указать больше заголовков и типов методов, чем это было возможно ранее при использовании кросс-источника <img src>или <form action>.

Некоторые серверы могли быть (плохо) защищены из-за предположения, что браузер не может сделать, например, DELETEзапрос перекрестного происхождения или запрос перекрестного происхождения с X-Requested-Withзаголовком, поэтому такие запросы являются «доверенными».

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


12
Это должен был быть принятый ответ. Это самый однозначный и точный. По сути, единственной точкой предварительных запросов является интеграция веб-стандартов до CORS с веб-стандартами после CORS.
Тяпка ничья lion4

2
Мне нравится этот ответ, но я чувствую, что это не может быть полной причиной ... «предположение о доверии» должно относиться только к вещам, которые может делать только браузер (в частности, отправка информации о пользователе браузера ограничена их доменом - то есть печенье). Если это не было частью предположения, то что-либо, что может сделать запрос браузера с разными источниками, может уже быть сделано сторонним, не браузерным агентом, верно?
Фабио Бельтрамини

2
@FabioBeltramini Право, не браузеры могут отправлять все, что они хотят. Однако атаки через браузеры являются особыми, потому что вы можете заставить браузеры других людей делать что-то, с их собственного IP, с их собственными cookie-файлами и т. Д.
Kornel

Я начинаю видеть реальную проблему. Спасибо за комментарии и ответ @FabioBeltramini и ответ Кронеля. Если предполетной проверки нет, злоумышленник сможет разместить на своем сайте некоторый код JavaScript, но выполнить его с компьютеров других людей. Всем остальным сложно «нанять» для этого других, в том числе мобильные приложения.
Сяо Пэн - ZenUML.com

16

Вот еще один способ посмотреть на это, используя код:

<!-- hypothetical exploit on evil.com -->
<!-- Targeting banking-website.example.com, which authenticates with a cookie -->
<script>
jQuery.ajax({
  method: "POST",
  url: "https://banking-website.example.com",
  data: JSON.stringify({
    sendMoneyTo: "Dr Evil",
    amount: 1000000
  }),
  contentType: "application/json",
  dataType: "json"
});
</script>

До появления CORS попытка эксплойта, описанная выше, потерпела бы неудачу, поскольку она нарушает политику того же происхождения. Разработанный таким образом API не нуждался в защите XSRF, потому что он был защищен собственной моделью безопасности браузера. Браузер до CORS не мог сгенерировать JSON POST с несколькими источниками.

Теперь на сцену выходит CORS - если не требуется вход в CORS перед полетом, внезапно этот сайт будет иметь огромную уязвимость не по своей вине.

Чтобы объяснить, почему некоторым запросам разрешено пропускать предполёт, на это отвечает спецификация:

Простой перекрестный запрос был определен как совпадающий с запросами, которые могут быть сгенерированы развернутыми в настоящее время пользовательскими агентами, которые не соответствуют этой спецификации.

Чтобы распутать это, GET предварительно не пролетает, потому что это «простой метод», как определено в 7.1.5. (Заголовки также должны быть «простыми», чтобы избежать предполетной подготовки). Обоснованием этого является то, что «простой» перекрестный GET-запрос уже может быть выполнен, например, <script src="">(так работает JSONP). Поскольку любой элемент с srcатрибутом может инициировать GET перекрестного происхождения без предварительной проверки, не было бы никакой выгоды в плане безопасности, требующей предварительного боя на «простых» XHR.


1
@MilesRout: Telnet не является частью модели угроз, которая предварительно направлена ​​на смягчение. Предварительная проверка актуальна для браузеров, которые 1) полагаются на сохраненные «окружающие права» (например, файлы cookie) и 2) могут быть обмануты путем неправомерного использования этих прав третьей стороной (например, подделка межсайтовых запросов). Обобщенная модель известна как проблема запутанного депутата .
Дилан Тэк

Это проблема с окружающим авторитетом, тем не менее, вы всегда можете злоупотреблять этим.
Майлз Рут

13

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

Сценарии:

1) С предполетным полетом . Злоумышленник подделывает запрос с сайта dummy-forums.com, пока пользователь проходит аутентификацию на safe-bank.com.
Если Сервер не проверяет источник и каким-то образом имеет изъян, браузер выдаст запрос перед полетом, OPTION метод. Сервер не знает ни одного из этих CORS, которые браузер ожидает в качестве ответа, поэтому браузер не будет работать (никакого вреда вообще).

2) Без предполетной подготовки . Злоумышленник подделывает запрос в соответствии с тем же сценарием, что и выше, браузер сразу же отправляет запрос POST или PUT, сервер принимает его и может обработать, что может нанести некоторый вред.

Если злоумышленник отправляет запрос напрямую, из разных источников, с какого-то случайного хоста, скорее всего, он думает о запросе без аутентификации. Это поддельный запрос, но не запрос xsrf. поэтому сервер проверит учетные данные и потерпит неудачу. CORS не пытается помешать атакующему, имеющему учетные данные, выдавать запросы, хотя белый список может помочь уменьшить этот вектор атаки.

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


Согласитесь с проблемой атаки CSRF, которая все еще возможна против "новых серверов", упомянутых в ответе @ michael-iles.
угорь ghEEz

Это полезное описание, которое, вероятно, стоит записать в другом месте. Может быть, стоит добавить его на одну из страниц MDN?
Sideshowbarker

Но почему некоторые запросы, такие как POST с Content-Type text / plain, не выполняют предполетный запрос? В моей голове, каждый запрос «запись» (POST, PUT, DELETE) должен иметь этот запрос перед полетом, если безопасность является проблемой.
Израиль Фонсека

POST с text / plain считается простым запросом - обратите внимание, что браузер не будет отображать ответ, если источник не совпадает (что будет в случае, если сервер не настроен для CORS).
Хирако

На стороне атакующего есть интересные вещи, которые можно сделать, используя тот факт, что простые запросы допускаются и будут отправляться большинством браузеров. например это .
Хирако

3

Кроме того, для методов HTTP-запроса, которые могут вызывать побочные эффекты для пользовательских данных (в частности, для HTTP-методов, отличных от GET, или для использования POST с определенными типами MIME), спецификация предписывает браузерам «предварительно проверять» запрос

Источник


2

Предполетные запросы необходимы для запросов, которые могут изменить состояние на сервере. Есть 2 типа запросов -

1) Вызовы, которые не могут изменить состояние на сервере (например, GET) - пользователь может получить ответ на запрос (если сервер не проверяет источник), но если запрашивающий домен не добавлен в заголовок ответа Access-Control- Allow-Origin, браузер не показывает данные пользователю, т. Е. Запрос отправляется из браузера, но пользователь не может просмотреть / использовать ответ.

2) Вызовы, которые могут изменить состояние на сервере (например, POST, DELETE) - поскольку в 1), мы видим, что браузер не блокирует запрос, но ответ, вызовы с изменением состояния не должны быть разрешены без предварительной проверки. , Такие вызовы могут вносить изменения в доверяющий сервер, который не проверяет происхождение вызовов (так называемая подделка межсайтовых запросов), даже если ответ на запрос браузера может быть ошибочным. По этой причине у нас есть концепция предполетных запросов, которые делают вызов OPTIONS, прежде чем любые вызовы, изменяющие состояние, могут быть отправлены на сервер.


1

Разве заранее не просят о производительности ? С помощью предварительно выданных запросов клиент может быстро узнать, разрешена ли операция, прежде чем отправлять большой объем данных, например, в JSON с методом PUT. Или перед перемещением конфиденциальных данных в заголовках аутентификации по проводам.

Факт PUT, DELETE и других методов, кроме пользовательских заголовков, по умолчанию не разрешен (им нужно явное разрешение с помощью «Access-Control-Request-Methods» и «Access-Control-Request-Headers»), что звучит точно так же, как двойная проверка, потому что эти операции могут иметь больше последствий для пользовательских данных, а не GET-запросов. Итак, это звучит как:

«Я видел, что вы разрешаете межсайтовые запросы с http: //foo.example , НО ВЫ УВЕРЕНЫ, что разрешите УДАЛИТЬ запросы? Рассматривали ли вы влияние, которое эти запросы могут оказать на пользовательские данные?»

Я не понял цитируемой корреляции между предварительно выданными запросами и преимуществами старых серверов. Веб-служба, которая была реализована до CORS или без поддержки CORS, никогда не получит ЛЮБОЙ межсайтовый запрос, потому что сначала их ответ не будет иметь заголовка «Access-Control-Allow-Origin».


4
Вы неправильно понимаете Access-Control-Allow-Origin. Отсутствие этого заголовка не мешает браузеру отправлять запросы, а просто мешает JS прочитать данные в ответе.
Дилан Тэк

Не могли бы вы объяснить это: «Отсутствие этого заголовка не мешает браузеру отправлять запросы, оно просто лишает JS возможности считывать данные в ответе» снова, я не получаю его полностью.
СиддхартБхагван

@DylanTack Хороший вопрос. Это заставляет меня задуматься, почему GET xhr также не является предполетным полетом? Хотя это маловероятно, GET-запросы также могут быть вредными / изменяющими данные. Кроме того, поскольку все это может быть решено с помощью CSRF, мне кажется, что браузер чрезмерно защищает серверы, которые слишком небрежны для реализации общих правил безопасности.
Пелег

Принятый ответ хорошо объясняет это как «вещь, не меняющую правила» (обратная совместимость с веб-сайтами, созданными до появления CORS). Тем не менее, интересно видеть код, поэтому я опубликовал еще один ответ с примером кода.
Дилан Тэк

1

В браузере, поддерживающем CORS, запросы на чтение (например, GET) уже защищены политикой того же происхождения: вредоносный веб-сайт, пытающийся сделать аутентифицированный междоменный запрос (например, на веб-сайт интернет-банка жертвы или интерфейс конфигурации маршрутизатора), не будет быть в состоянии прочитать возвращенные данные, потому что банк или маршрутизатор не устанавливают Access-Control-Allow-Originзаголовок.

Однако при написании запросов (например, POST) повреждение наносится, когда запрос поступает на веб-сервер. * Веб-сервер может проверить Originзаголовок, чтобы определить, является ли запрос допустимым, но эта проверка часто не выполняется, поскольку веб-серверу нет необходимости. для CORS или веб-сервера старше, чем CORS, и поэтому он предполагает, что междоменные POST полностью запрещены политикой того же происхождения.

Вот почему веб-серверам предоставляется возможность получать междоменные запросы на запись .

* По сути AJAX-версия CSRF.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.