Почему междоменный Ajax является проблемой безопасности? - PullRequest
41 голосов
/ 21 января 2009

Почему было решено, что использование XMLHTTPRequest для выполнения вызовов XML не должно выполнять вызовы через границу домена? Вы можете извлечь JavaScript, изображения, CSS, iframes и любой другой контент, который я могу придумать, из других доменов. Почему HTTP-запросы Ajax не могут пересекать границы домена? Это кажется странным ограничением, если принять во внимание, что единственный способ, которым я вижу, что он злоупотребляет, - это если кто-то вставит Javascript на страницу. Однако в этом случае вы можете просто добавить в документ элемент img, script или iframe, чтобы он запросил сторонний URL-адрес и отправил его на сервер.

[Редактировать]

В некоторых ответах указываются следующие причины, давайте укажем причины, по которым они не создают основную причину для запрета этого.

XSRF (Подделка межсайтовых запросов, также известная как CSRF, XSRF)

Вы можете проводить атаки XSRF, не используя это вообще. Как правило, XMLHTTPRequest вообще не используется, просто потому, что очень сложно создать XMLHTTPRequest способом, совместимым со всеми основными браузерами. Гораздо проще просто добавить тег img к URL, если вы хотите, чтобы они загружали ваш URL.

Публикация на стороннем сайте

<script type="text/javascript">
  $.post("http://some-bank.com/transfer-money.php", 
         { amount: "10000", to_account: "xxxx" })
</script>

Может быть выполнено с

<body onload="document.getElementById('InvisbleForm').submit()"
    <div style="display:none">
        <form id="InvisbleForm" action="http://some-bank.com/transfer-money.php" method="POST">
            <input type="hidden" name="amount" value="10000">
            <input type="hidden" name="to_account" value="xxxxx">
        </form>
    </div>
</body>

JPunyon: почему вы оставляете уязвимость в новой функции

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

Заключение

Я отмечаю ответ от bobince как правильный, потому что он указал на критическую проблему. Поскольку XMLHTTPRequest позволяет отправлять учетные данные (файлы cookie) на целевой сайт и считывать данные, отправленные обратно с сайта, наряду с отправкой учетных данных пользователей, вы можете организовать некоторый javascript, который будет представлять серию форм, включая формы подтверждения , дополнить произвольными сгенерированными ключами, которые были введены в действие, чтобы попытаться предотвратить XSRF. Таким образом, вы можете просматривать целевой сайт, например банк, и веб-сервер банка не сможет сказать, что это был не обычный пользователь, отправляющий все эти формы.

Ответы [ 9 ]

36 голосов
/ 21 января 2009

Почему Ajax HTTP-запросам не разрешено пересекать границы домена.

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

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

Вы можете просто добавить элемент img, script или iframe в документ

Ни один из этих методов не позволяет вызывающей стороне читать возвращенные данные.

(За исключением сценариев, в которых он намеренно настроен на это, для разрешенных междоменных сценариев - или в тех случаях, когда кто-то совершил ужасный сбой.)

Вы можете проводить XSS-атаки, не используя это вообще. Размещение на стороннем сайте

Это не атака XSS. Это атака по подделке межсайтовых запросов (XSRF). Известны способы решения атак XSRF, такие как одноразовые или криптографические токены для проверки того, что отправка была преднамеренно сделана пользователем и не была запущена из кода злоумышленника.

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

7 голосов
/ 13 октября 2012

Важная разница между POST:

<body onload="document.getElementById('InvisbleForm').submit()" ...

и Ajax заключается в том, что после выполнения любого POST браузер заменяет страницу, а после выполнения вызова Ajax - нет. Результат POST будет:

  1. Четко видно пользователю.
  2. На этом этапе атака застрянет, потому что страница ответа от my-bank.com возьмет на себя управление. Ни один банк не осуществит перевод в один клик .

Сценарий XSRF, если междоменный Ajax будет разрешен, будет выглядеть следующим образом:

  1. Пользователь как-то посещает www.bad-guy.com.
  2. Если в другом экземпляре браузера нет открытой страницы для my-bank.com, атака не удалась.
  3. Но если такая страница открыта и пользователь уже ввел свое имя пользователя / пароль, это означает, что в кеше браузера есть файл cookie для этой сессии.
  4. Код JavaScript на странице от www.bad-guy.com делает Ajax-вызов my-bank.com.
  5. Для браузера это обычный HTTP-вызов, он должен отправить куки my-bank на my-bank.com и отправить их.
  6. Банк обрабатывает этот запрос, поскольку не может отличить этот вызов от обычной активности пользователя.
  7. Тот факт, что код JavaScript может прочитать ответ, не важен. В случае атаки это может быть необязательно. Что действительно важно, так это то, что пользователь перед компьютером не будет знать, что это взаимодействие происходит. Он посмотрит красивые картинки на странице www.bad-guy.com.
  8. Код JavaScript делает несколько других вызовов my-bank.com, если это необходимо.

Суть в том, что не требуется инъекция или подделка страниц.

Лучшим решением может быть позволить сам вызов, но не отправлять куки. Это очень простое решение, которое не требует каких-либо масштабных разработок. Во многих случаях Ajax-вызов идет в незащищенное местоположение, и не отправка файлов cookie не будет ограничением.

CORS (Cross Source Resource Sharing), который сейчас обсуждается, помимо прочего, говорит об отправке / не отправке куки.

2 голосов
/ 21 января 2009

Когда вы отправляете HTTP-запрос на сервер, файлы cookie, установленные сервером, также отправляются браузером обратно на сервер. Сервер использует эти файлы cookie для установления того факта, что пользователь вошел в систему и т. Д.

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

Например, можно попросить пользователя посетить сайт со следующим кодом JavaScript (при условии, что jQuery):

<script type="text/javascript">
  $.post("http://some-bank.com/transfer-money.php", 
         { amount: "10000", to_account: "xxxx" })
</script>

Теперь, если пользователь действительно вошел в банк во время выполнения вышеуказанного кода, злоумышленник мог перевести 10 000 долларов США на счет XXX.

Этот вид атак называется «Подделка межсайтовых запросов» (XSRF). Подробнее об этом можно узнать в Wikipedia .

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

В настоящее время обсуждается вопрос о разрешении междоменного XHR, но мы должны посмотреть, действительно ли это будет принято.

2 голосов
/ 21 января 2009

Ну, видимо, ты не единственный человек, который так чувствует ...

http://www.google.com/search?q=xmlhttp+cross+site

РЕДАКТИРОВАТЬ: есть интересная дискуссия связана с поиском выше:

http://blogs.msdn.com/ie/archive/2008/06/23/securing-cross-site-xmlhttprequest.aspx

Похоже, что в настоящее время готовятся предложения по разрешению межсайтовых запросов xmlhttp (IE 8, FF3 и т. Д.), Хотя я бы хотел, чтобы они были там, когда я писал код для своих сайтов :) И тогда возникает проблема совместимости ... Пройдет некоторое время, прежде чем она станет повсеместной.

1 голос
/ 21 января 2009

С помощью <form> вы можете публиковать данные, но не можете их прочитать. С XHR вы можете сделать оба.

Страница типа http://bank.example.com/display_my_password безопасна для XSRF (при условии, что она только отображает, но не устанавливает пароль) и фреймов (они имеют политику одного и того же происхождения). Однако междоменный XHR будет уязвимостью.

1 голос
/ 21 января 2009

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

Обработка чувствительных AJAX-запросов? Зафиксируйте входящие присоски, проверяя заголовки, сохраняя данные времени сеанса или фильтруя входящие IP-адреса по источникам, которым вы доверяете, или вашим приложениям.

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

1 голос
/ 21 января 2009

Я думаю, что еще одна вещь, которая отличает это от обычной атаки XSRF, - это то, что вы можете делать что-то с данными, которые вы возвращаете, также через javascript.

1 голос
/ 21 января 2009

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

Две самые большие проблемы возникают, когда он используется в сочетании с межсайтовым скриптингом (XSS) и подделкой межсайтовых запросов (CSRF). Обе являются серьезными угрозами (именно поэтому они попали в первую десятку OWASP и в SANS 25).

Единственный способ, которым я мог видеть, что он подвергался насилию, - это если бы кто-то вводил Javascript

Это XSS. Слишком много приложений по-прежнему уязвимы, и, если модели безопасности браузера не препятствуют X-домену AJAX, они открывают своим пользователям значительный вектор атаки.

Вы можете просто добавить элемент img, script или iframe в документ, чтобы он запрашивал сторонний URL

Да, но они отправят HTTP_REFERRER и (другими способами) могут быть заблокированы для предотвращения CSRF. Вызовы AJAX могут легче подделывать заголовки и позволяют использовать другие способы обхода традиционных средств защиты CSRF.

0 голосов
/ 21 января 2009

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

Кроме того, представьте себе межсайтовый скрипт, который крадет все ваши вещи в Facebook. Он открывает IFrame и переходит на Facebook.com

Вы уже вошли в Facebook (cookie), и он читает ваши данные / друзей. И делает больше гадостей.

...