Javascript XSS и Crazy Iframe Stuff

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

Методов реализации оказалось немало, и в основном они хорошо описаны в интернете, потому я не стану повторяться и дам ссылки на те статьи, которые помогли разобраться мне в этом вопросе.

Очень хорошая обзорная статья на хабре - Cross-domain «ajax» — простое решение (31 мая 2011) упоминает о 8 способах организации XSS:

  • postMessage из стандарта HTML5
  • JSONP (JSON Padding). Пример использования этого метода в сочетании с jQuery можно, найти в статье Кросс-доменный Ajax в jQuery (28 февраля 2010)
  • Cross-origin resource sharing (CORS) - спецификация поддерживается большинством современных браузеров, за исключением IE, который в качестве альтернативы предлагает использовать XDomainRequest
  • document.domain - позволяет организовать кросс-доменный AJAX с прямым поддоменом (именно этот метод используется в Realplexor)
  • window.name transport работает за счет изменения свойства window.name Этот метод использован в библиотеке srax.xss.js, с описанием которой можно познакомиться на хабре - JavaScript Cross Site (XSS) POST (5 октября 2008)
  • server-side proxy - решает проблему через создание серверного скрипта, который переправляет запросы на другой домен
  • CRAZY IFRAME STUFF - решение за счет совместного доступа к адресу страницы загруженной в iftame
  • flash - метод испольует возможность ActionScript

Далее автор харба-статьи предлагает использовать библиотеку easyXDM - Cross-Domain Messaging made easy, которая сама выбирает способ организации XSS в зависимости от браузера и его версии.

Собственно об этом же рассказывает презентация Breaking the cross domain barrier (05 июня 2010), уделяя каждому из методов чуть больше внимания. В ней же говорится о том, что наиболее универсальным методом является CRAZY IFRAME STUFF, который я и решил испытать.

CRAZY IFRAME STUFF

С подробным описанием метода можно ознакомиться в статье Cross-Domain Communication with IFrames (31 марта 2008 с обновлением от 6 мая 2011). Я же приведу те четыре "закона" на которых базируется данный метод:
  • Любое окно в иерархии может получить ссылку (handle) на любое другое окно
  • Из одного окна можно получить доступ к объектам другого, только если они отображают данный с одного домена
  • Любое окно в иерархии может изменить (но не прочитать) значение свойства location для другого окна, даже относящегомся к другому домену
  • Если d URL вы меняете только значение хеша, то страница не перезагружается

Третье правило делает возможным использование iframe для передачи данных между окнами, контент которых загружен с разных доменов. В некоторых статьях говорится о возможности менять значение свойства loacation.href у окна, загруженного в iframe, и это действительно работает, например в FF, но IE и Opera выдают security exception при попытке изменить значение этого свойства. Для того чтобы избежать этого необходимо изменять свойство src у самого фрейма, при этом изменять надо только часть адреса после символа #, в этом случае страница так же не будет перезагружена.

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

  1. server/index.php
  2. <body style="background:#009;">
  3. <h2>server</h2>
  4. <button id="test" onclick="alert(window.BFrame.AFrame.location.hash);">Test</button>
  5. <br>
  6. <iframe name="BFrame" src="http://comet/index.php" style="width: 400px; height: 300px;"></iframe>
  7. <div id="ts"></div>
  8. <body>
  9.  

  1. server/iframe.php
  2. <body
  3. style="background:#009;"
  4. onLoad="parent.parent.document.getElementById('ts').innerHTML = '<?echo mktime();?>';">
  5. <h2>server iframe</h2>
  6. </body>
  7.  

  1. comet/index.php
  2. <body style="background:#900;">
  3. <h2>comet (another domain)</h2>
  4. <br>
  5. <input id="val" value="123">
  6. <button id="set"
  7. onclick="document.getElementById('transport').src
  8. = 'http://server/iframe.php#'
  9. + document.getElementById('val').value">Set</button>
  10. <iframe name="AFrame" id="transport" src="http://server/iframe.php#test"></iframe>
  11. </body>
  12.  

Дополнительные ссылки в тему

How to build a personal mashup page with jQuery

Cross-domain requests with jQuery

Читайте в блоге

Установка собственного OpenID сервера phpMyID
Использование \K в регулярных выражениях. Игнорирование начальной части совпадения.
Запуск Play! из IntelliJ IDEA

Метки: xss javascript ajax iframe

Комментарии:

<font color="red">test</font> @ 12.11.2012 09:41

12

Войдите на сайт, чтобы оставить комментарий