[Перевод] История Same Origin Policy
В начале 90-х интернет был очень базовым и простым для понимания. По сути, это были два компонента: веб-сервер и браузер.
На локальном компьютере вы устанавливали браузер, который, получив URL, отправлял HTTP GET-запрос на сервер, на котором запрашиваемый ресурс. Затем этот сервер отвечал текстом, но не просто текстом. HTTP означает протокол передачи гипертекста, и этот гипертекст может быть, например, HTML-документом. Проще говоря, это текстовый файл с HTML-кодом, а браузер — это программа, которая интерпретирует этот код и отображает для вас приятный интерфейс веб-сайта.
Но настоящая сила заключается в возможности связывать ресурсы вместе с помощью тегов link
. Вы можете ссылаться на другие документы и другие веб-сайты.
При нажатии на такую ссылку ваш браузер изменял «местоположение» (location
).
Информация теперь стала по-настоящему взаимосвязанной и ее было легко просматривать (»browse-ить»).
Но это было только начало. Примерно в 1994–1995 годах в интернете появился Amazon.
Это было время, когда в интернете стало появляться все больше и больше реальных услуг: онлайн-банки, интернет магазины, веб-почты и т.п.
Технологии развивались очень быстро.
На стороне клиента, в браузере, появилось больше возможностей, например формы.
Люди могли вводить текст в формы и отправлять контент на сервер. И, конечно же, развивалось серверное ПО.
Инженерам приходилось придумывать решения новых проблем, например, как хранить товары в корзине интернет-магазина на стороне клиента, на его компьютере.
Так в июне 1994 года разработчики браузера Netscape изобрели cookie.
Вот как они описывают cookie:
»Когда вы просматриваете веб-страницу, любые cookie, которые серверы могут отправлять на вашу копию Netscape Navigator хранятся в памяти вашего компьютера. Когда вы выходите из Netscape Navigator, любые cookie, срок действия которых еще не истек, записываются в файл cookie, чтобы их можно было загрузить снова при следующем запуске Netscape Navigator …
Netscape Navigator не отправляет никакие cookie на другие веб-серверы, для которых они не предназначены».
Вот, например, у меня есть старая версия Netscape, и я создал простую страницу входа с cookie.
После ввода данных входа, вы видите, как это работает, мы можем войти в систему как администратор.
Теперь начинается самое интересное. Вот примечания к выпуску бета-версии Netscape 2.0:
»LiveScript в настоящее время реализован только в Windows. Остальные платформы будут поддерживаться в бета-версии 2».
К сожалению, ссылка на документацию по LiveScript, похоже, утеряна.
Вскоре после этого, взглянув на страницу выпуска бета-версии 2, мы можем прочитать следующее:»Built-in JavaScript». LiveScript теперь называется JavaScript.
»Netscape Navigator теперь включает встроенный язык сценариев (скриптов), называемый JavaScript. JavaScript разработан на основе языка JAVA, который расширяет и улучшает возможности HTML документов. JavaScript поддерживает большинство синтаксисов выражений JAVA и основные конструкции потока управления, но без строгой проверки типов и статической типизации JAVA. JavaScript встроен в HTML-документ с помощью тега SCRIPT, и для запуска сценария не требуется компиляция».
И вот документация с красивой таблицей сравнения JavaScript и Java:
Как мы знаем сегодня, это изменило все. В интернете теперь есть обработчики событий, которые могут реагировать на клики и наведения курсора мыши, вы можете определять объекты или работать со временем и датами, а так же получать доступ к формам и текстовым вводам от пользователя и т.п., все это прямо в браузере пользователя. JavaScript сделал веб-сайты динамичными.
Теперь воспользуемся Netscape 2.0, выпущенную в сентябре 1995 года, который впервые поддерживает JavaScript.
В то время веб-сайты активно использовали фреймы (теги ). Они является предшественниками сегодняшних тегов
. В документации JavaScript вы можете увидеть, например, HTML-код для
framest
с двумя столбцами, где каждый frame
ссылается на отдельный URL.
Так вы можете реализовать панель навигации и содержимое страницы.
Вот, например, сайт Элвиса Пресли:
Как вы видите, фреймы действительно интегрированы в браузер. И посмотрите на документацию. JavaScript так же может взаимодействовать с фреймами
Разберем на примере. Вот код с frameset
с разными веб-сайтами.
Как вы видите, это разные домены.
Один домен — это страница входа, которую показывали ранее.
А другой фрейм — это страница злоумышленника.
Теперь загрузим страницу с этими двумя фреймами в браузере Netscape и посмотрим, что произойдет:
В фреймах два разных сайта, но сайт атакующего получил доступ до имени пользователя, его пароля и файл cookie сессии со страницы /login.php
другого сайта.
Если посмотреть на код сайта злоумышленника, то мы сможем найти JavaScript-код, ответственный за такое поведение:
После небольшого timeout, чтобы дать другому сайту достаточно времени для загрузки, вызывается метод stealPassword()
. А данный метод просто следует иерархии фреймов.
Он переходит к фрейму top
, далее получает доступ к frame2
, оттуда к объекту window
, далее к document
, а там получает доступ к форме документа с именем пользователя и паролем. И, конечно, он так же имеет доступ к document.cookie
.
Далее данные помещается в текстовое поле для демонстрации:
Теоретически мы могли бы отправить эту информацию злоумышленнику.
С сегодняшней точки зрения это кажется абсолютным безумием. Просто посетить вредоносный веб-сайт, который с помощью фреймов может загрузить фрейм банковского сайта, украсть ваши cookie или даже выполнить транзакции по переводу денег. Но для того времени это был совершенно новый вектор атаки, и еще не существовало такого понятия, как Cross-Site Scripting (XSS).
Однако разработчикам не потребовалось много времени, чтобы осознать проблему. Несколько месяцев спустя они выпустили Netscape 2.02 с исправлением.
И вот перед нами новый браузер. Попробуем теперь открыть зловредный веб-сайт, чтобы воспроизвести атаку, но сталкиваемся с ошибкой »Формы нельзя индексировать как массив»:
Эта ошибка означает, что мы больше не можем получить доступ к формам другого веб-сайта:
Даже убрав код доступа к формам и попытавшись получить доступ до файла cookie другого сайта, ничего не получится.
Давайте кратко рассмотрим примечание к выпуску и обновлениям безопасности в версии 2.02 относительно JavaScript:
»Из-за проблемы с реализацией Netscape Navigator 2.0 возникла проблема конфиденциальности, поскольку серверный скрипт мог получить доступ к списку имен локальных файлов и каталогов на машине пользователя … Navigator 2.02 исправляет эту проблему, запрещая скрипту с сервера доступ к просмотру имен файлов и директорий с локальной машины пользователя».
Это имеет смысл, т.к. браузер так же может просматривать локальную файловую систему:
Итак, вместо «фрейминга» другого веб-сайта, мы могли бы «фреймить» локальную директорию, например, папку C:\
:
Посмотрите на написанный JavaScript код, мы просто получаем доступ ко всем ссылкам на странице и извлекаем их:
Я думаю, именно ЭТО они на самом деле осознали как проблему (issue). Возможно это была самая первая уязвимость, связанная с JavaScript в истории.
Теперь эта фраза »…поскольку серверный скрипт мог получить доступ к списку имен локальных файлов и каталогов на машине пользователя» имеет смысл
Итак, как вы можете видеть, проблема доступа к данным с других веб-сайтов здесь явно не упоминается, проблема заключалась именно в доступе к локальным файлам и именам директорий.
Итак, каким-то образом они сделали так, что другой скрипт больше не может получить доступ к фреймам с именами файлов. Но то, как они решили эту проблему, становится намного яснее с выпуском Netscape 3:
»Navigator версии 2.02 и более поздние версии автоматически не позволяет скриптам на одном сервере получить доступ к свойствам документов на другом сервере»
Теперь становится понятно, что Netscape только что изобрел ту самую Политику Одного Источника (Same Origin Policy) — JavaScript, работающий на одном источники (или сервере) не может получить доступ к данным на другом источнике (сервере).
Сегодня мы знаем последствия этого решения. Все эти уязвимости на стороне клиента, такие как CSRF, XSS, Clickjacking и т.п. связаны с этим основным принципом безопасности Политики Одного Источника. Однако в то время, в 1995 году, не было очевидно, что это будет иметь такое большое значение.