diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/task.md b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/task.md index db49fb3d..3bb9a2d8 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/task.md +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/task.md @@ -4,13 +4,11 @@ Нужно написать функцию, которая показывает подсказку при *наведении* на элемент, но не при *быстром проходе* над ним. -То есть, если посетитель именно навёл курсор мыши на элемент и почти остановился -- подсказку показать, а если быстро провёл над ним, то не надо (зачем излишнее мигание?). +То есть, если посетитель именно навёл курсор мыши на элемент и почти остановился -- подсказку показать, а если быстро провёл над ним, то не надо, зачем излишнее мигание? Технически -- можно измерять скорость движения мыши над элементом, если она маленькая, то считаем, что это "наведение на элемент" (показать подсказку), если большая -- "быстрый проход мимо элемента" (не показывать). -Задача -- сделать универсальный код, который отслеживает "наведение на элемент". - -Пусть это будет объект `new HoverIntent(options)`, который при создании принимает `options`: +Реализуйте это через универсальный объект `new HoverIntent(options)`, с параметрами `options`: - -

Спасибо Марату Шагиеву за помощь в выкладке русскоязычного варианта этой главы.

diff --git a/3-more/5-frames-and-windows/6-clickjacking/article.md b/3-more/5-frames-and-windows/6-clickjacking/article.md new file mode 100644 index 00000000..0154d7f1 --- /dev/null +++ b/3-more/5-frames-and-windows/6-clickjacking/article.md @@ -0,0 +1,203 @@ +# Атака Clickjacking и защита от неё + +Атака "кликджекинг" (англ. Clickjacking) позволяет хакеру выполнить клик на сайте-жертве *от имени посетителя*. + +В русском языке встречается дословный перевод термина clickjacking: "угон клика". Так же применительно к clickjacking-атаке можно встретить термины "перекрытие iframe" и "подмена пользовательского интерфейса". + +Кликджекингу подверглись в своё время Twitter, Facebook , PayPal, YouTube и многие другие сайты. Сейчас, конечно, они уже защищены. +[cut] +## Идея атаки + +В целом идея очень проста. + +Вот как выглядел "угон клика" пользователя, который зарегистрирован на Facebook: + +
    +
  1. На вредоносной странице пользователю подсовывается безобидная ссылка (скажем, что-то скачать, "разбогатеть сейчас", посмотреть ролик или просто перейти по ссылке на интересный ресурс).
  2. +
  3. Поверх этой заманчивой ссылки помещен прозрачный iframe со страницей facebook.com, так что кнопка "Like" находится чётко над ней.
  4. +
  5. Кликая на ссылку, посетитель на самом деле нажимает на эту кнопку.
  6. +
+ +## Демо + +Вот пример вредоносной страницы (для наглядности `iframe` -- полупрозрачный): + +```html + + + +
Нажмите, чтобы разбогатеть сейчас:
+ + +*!* + + + + */!* + +
..И всё получится (хе-хе, у меня, злого хакера, получится)!
+``` + +В действии: + +[codetabs src="clickjacking-visible" height=200] + +Так как ` +``` + +Есть и другие приёмы для обхода этой простейшей защиты. + +Firefox и старый IE могут активировать designMode на исходной странице, это также предотвращает framebusting, у IE есть нестандартный атрибут [security](https://msdn.microsoft.com/en-us/library/ie/ms534622.aspx) для ифреймов, который можно использовать с той же целью. + +Как мы видим, эта защита не только не выдерживает реальной атаки, но и может скомпрометировать сайт (программист-то думает, что защитил его). + +## Заголовок X-Frame-Options + +Все современные браузеры поддерживают заголовок `X-Frame-Options`. + +Он разрешает или запрещает отображение страницы, если она открыта во фрейме. + +Браузеры игнорируют заголовок, если он определен в МЕТА тег. Таким образом, `` будет проигнорирован. + +У заголовка может быть три значения: + +
+
SAMEORIGIN
+
Рендеринг документа, при открытии во фрейме, производится только в том случае, когда верхний (top) документ -- с того же домена.
+
DENY
+
Рендеринг документа внутри фрейма запрещён.
+
ALLOW-FROM domain
+
Разрешает рендеринг, если внешний документ с данного домена (не поддерживается в Safari, Firefox).
+
+ +К примеру, Twitter использует `X-Frame-Options: SAMEORIGIN`. Результат: + +```html + +``` + + + +В зависимости от браузера, `iframe` выше либо пустой, либо в нём находится сообщение о невозможности отобразить его (IE). + +## Показ с отключённым функционалом + +Заголовок `X-Frame-Options` имеет неприятный побочный эффект. Иногда поисковики, анонимайзеры или другие сайты хотели бы отобразить страницу в `iframe`, по вполне "легальным" причинам, но не могут. + +Хорошо бы показывать их посетителям не пустой `iframe`, а нечто, что может быть более интересно. + +Например, можно изначально "накрывать" документ `div` с `height:100%;width:100%`, который будет перехватывать все клики. И поставить на нём ссылку, ведующую на страницу в новом окне. + +```html + + +
+ Перейти на сайт +
+ + +``` + +Если страница -- не во фрейме или домен совпадает, то посетитель не увидит его. + +## Заключение + +Атаку "Clickjacking" легко осуществить, если на сайте есть действие, активируемое с помощью одного клика. + +Злоумышленник может осуществить атаку через целенаправленно на посетителей ресурса -- опубликовав ссылку на форуме, или "счастливой рассылкой". Существует масса вариантов. + +С первого взгляда, она "неглубокая": всё, что можно сделать -- это один клик. С другой стороны, если хакер знает, что после клика появляется какой-то другой управляющий элемент, то он, хитрыми сообщениями, может заставить посетителя кликнуть и по нему. А это уже не один, а два клика. + +Атака особенно опасна, поскольку, проектируя интерфейс сайта, обычно никто и не задумывается о том, что клик от имени юзера может сделать хакер. Точки уязвимости могут быть в совершенно непредсказуемых местах. + + + diff --git a/3-more/5-frames-and-windows/6-clickjacking/clickjacking-visible.view/facebook.html b/3-more/5-frames-and-windows/6-clickjacking/clickjacking-visible.view/facebook.html new file mode 100644 index 00000000..f002436f --- /dev/null +++ b/3-more/5-frames-and-windows/6-clickjacking/clickjacking-visible.view/facebook.html @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/3-more/5-frames-and-windows/6-clickjacking/clickjacking-visible.view/index.html b/3-more/5-frames-and-windows/6-clickjacking/clickjacking-visible.view/index.html new file mode 100644 index 00000000..a58014ab --- /dev/null +++ b/3-more/5-frames-and-windows/6-clickjacking/clickjacking-visible.view/index.html @@ -0,0 +1,29 @@ + + + + + + + + + +
Нажмите, чтобы разбогатеть сейчас:
+ + + + + + +
..И всё получится (хе-хе, у меня, злого хакера, получится)!
+ + + \ No newline at end of file diff --git a/3-more/5-frames-and-windows/6-clickjacking/clickjacking.view/facebook.html b/3-more/5-frames-and-windows/6-clickjacking/clickjacking.view/facebook.html new file mode 100644 index 00000000..f002436f --- /dev/null +++ b/3-more/5-frames-and-windows/6-clickjacking/clickjacking.view/facebook.html @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/3-more/5-frames-and-windows/6-clickjacking/clickjacking.view/index.html b/3-more/5-frames-and-windows/6-clickjacking/clickjacking.view/index.html new file mode 100644 index 00000000..edb7a287 --- /dev/null +++ b/3-more/5-frames-and-windows/6-clickjacking/clickjacking.view/index.html @@ -0,0 +1,29 @@ + + + + + + + + + +
Нажмите, чтобы разбогатеть сейчас:
+ + + + + + +
..И всё получится (хе-хе, у меня, злого хакера, получится)!
+ + + \ No newline at end of file diff --git a/3-more/5-frames-and-windows/6-clickjacking/top-location.view/iframe.html b/3-more/5-frames-and-windows/6-clickjacking/top-location.view/iframe.html new file mode 100644 index 00000000..0f485f8d --- /dev/null +++ b/3-more/5-frames-and-windows/6-clickjacking/top-location.view/iframe.html @@ -0,0 +1,15 @@ + + + + + + + +
Меняет top.location на javascript.ru
+ + + + + \ No newline at end of file diff --git a/3-more/5-frames-and-windows/6-clickjacking/top-location.view/index.html b/3-more/5-frames-and-windows/6-clickjacking/top-location.view/index.html new file mode 100644 index 00000000..80e21f26 --- /dev/null +++ b/3-more/5-frames-and-windows/6-clickjacking/top-location.view/index.html @@ -0,0 +1,38 @@ + + + + + + + + + + + +

При нажатии на кнопку посетитель получит "странный" вопрос о том, не хочет ли уйти со страницы.

+ +

Наверно, он ответит "хочу остаться" и защита ифрейма будет провалена.

+ + + + + \ No newline at end of file diff --git a/3-more/7-frames-and-windows/index.md b/3-more/5-frames-and-windows/index.md similarity index 100% rename from 3-more/7-frames-and-windows/index.md rename to 3-more/5-frames-and-windows/index.md diff --git a/3-more/7-frames-and-windows/2-window-properties-and-methods/article.md b/3-more/7-frames-and-windows/2-window-properties-and-methods/article.md deleted file mode 100644 index 7fc6a53a..00000000 --- a/3-more/7-frames-and-windows/2-window-properties-and-methods/article.md +++ /dev/null @@ -1,114 +0,0 @@ -# Окно браузера: свойства и методы - -Объект `window` выполняет две функции (или играет две роли): -
    -
  1. Является глобальным объектом Javascript.
  2. -
  3. Предоставляет интерфейс для работы с окном браузера.
  4. -
- -О глобальном объекте мы говорили в главе [](/closures). А здесь -- обратим внимание на то, что касается браузера. - -[cut] - -## События - -Наиболее важные события при работе с окном браузера: - - -## Методы и свойства - -
-
`window.closed` -
Свойство `window.closed` равно `true`, если окно закрыто. Может быть использовано, чтобы проверить, закрыл ли посетитель попап.
-
`window.close()`
-
Закрывает попап без предупреждений и уведомлений. Вообще, метод `close()` можно вызвать для любого окна, в том числе, текущего. Но если окно открыто не с помощью `window.open()`, то браузер может проигнорировать вызов `close` или запросить подтверждение. - -Нажмите кнопку ниже, для закрытия текущего окна. - - - -Попытайтесь это сделать в разных браузерах. На момент написания статьи, Firefox, Opera и Safari проигнорируют вызов `close()`, а IE запросит подтверждение. -
-
`window.title`
-
Заголовок окна соостветствует содержимому элемента `TITLE` в `HEAD`. - -**Забавно, но для *изменения* заголовка нужно использовать не это свойство, а `document.title`.** - -Код, расположенный ниже, каждую секунду обновляет заголовок окна на текущее время: - -```js -//+ run -setInterval(function() { - document.title = new Date(); -}, 1000); -``` - -
-
- -## Перемещение и изменение размеров окна - -Существует несколько методов для перемещения/изменения размеров окна. - -
-
`win.moveBy(x,y)`
-
Перемещает окно относительно текущего положения на `x` пикселей вправо и `y` пикселей вниз. Допускаются отрицательные значения.
-
`win.moveTo(x,y)`
-
Передвигает окно в заданную координатами `x` и `y` точку экрана монитора.
-
`win.resizeBy(width,height)`
-
Изменяет размер окна на заданную величину `width/height` (ширина/высота). Допускаются отрицательные значения.
-
`win.resizeTo(width,height)`
-
Изменяет размер окна на заданное значение.
-
- -Чтобы предотвратить использование этих методов с плохими целями, браузеры часто блокируют их выполнение. Как правило, они работают, если окно `win` открыто вызовом [window.open](https://developer.mozilla.org/en-US/docs/Web/API/window.open) из JavaScript текущей страницы и в нём нет дополнительных вкладок. - -**JavaScript не может свернуть или максимизировать окно.** - -Эти функции операционной системы от Frontend-разработчиков скрыты. Вызовы, описанные выше, в случае свёрнутого или максимизированного окна не работают. - -## Прокрутка окна - -Прокрутка окна требуется, пожалуй, чаще всего. Мы уже говорили о ней в главе [](/metrics-window): - -
-
`win.scrollBy(x,y)` -Прокрутка окна на заданное число пикселей вперед или назад. Допускаются отрицательные значения.
-
`win.scrollTo(x,y)`
-
Прокручивает окно к заданным координатам.
-
`elem.scrollIntoView(top)`
-
Этот метод прокрутки вызывается на элементе. При этом окно прокручивается так, чтобы элемент был полностью видим. - -Если параметр `top` равен `true` или не задан, то верх элемента совпадает с верхом окна. Если он равен `false`, то окно прокручивается так, чтобы нижний край элемента совпал с нижним краем окна. -
-
- -## Итого - -Что можно сделать с окном браузера: - - - -Управление размером, положением, прокруткой окна: - - - -

Спасибо Марату Шагиеву за помощь в выкладке русскоязычного варианта этой главы.

\ No newline at end of file diff --git a/3-more/7-frames-and-windows/4-iframes/article.md b/3-more/7-frames-and-windows/4-iframes/article.md deleted file mode 100644 index 67495798..00000000 --- a/3-more/7-frames-and-windows/4-iframes/article.md +++ /dev/null @@ -1,250 +0,0 @@ -# Общение с окном в ифрейме - -Здесь предполагается, что мы прекрасно знаем, что такое ифрейм, и как подключить внешний документ с его использованием. Иначе говоря, HTML для нас не нов. - -В этой главе мы рассмотрим способы работы с ними из JavaScript. - -[cut] - -## Ифрейм: тонкости с атрибутами - -Хоть мы и знаем, что такое ифрейм, но позвольте заострить внимание на нескольких моментах, касающихся атрибутов. - -
-
Рамка: `frameborder="0"`
-
Если хочется, чтобы в IE8- вокруг ифреймов не было рамок, то поставьте атрибут `frameborder="0"`. - -В IE8- все ифреймы в примере ниже, кроме последнего, будут с рамкой: - -```html - - -
    -
  1. -
  2. -*!* -
  3. -*/!* -
-``` - -
-
Пустой `src`
-
Атрибут `src` может использовать протокол `javascript:...`. При этом код выполняется и его результат будет содержимым ифрейма. Этот способ описан в стандарте и поддерживается всеми браузерами. - -Атрибут `src` является обязательным, и его отсутствие может привести к проблемам, вплоть до игнорирования ифрейма браузером. - -**Чтобы ничего не загружать в ифрейм, укажите `src="javascript:false"`.** -
-
Атрибут `name` и создание ифрейма в IE7-
-
В старых IE нельзя менять атрибут `name` после создания ифрейма: - -```js -var iframe = document.createElement('iframe'); -iframe.name = 'iName'; // в IE7- не сработает -``` - -Поэтому, если нужна совместимость, создавайте ифреймы через `innerHTML`: - -```js -var tmp = document.createElement('div'); -tmp.innerHTML = ''; - -var iframe = tmp.firstChild; -``` - -
-
- -## Ифрейм: доступ к document и window - -Элемент `iframe` является обычным узлом DOM, как и любой другой. Существенное отличие -- в том, что с ним связан объект `window` внутреннего окна. Он доступен по ссылке `iframe.contentWindow`. - -Таким образом, `iframe.contentWindow.document` будет внутренним документом. - -[smart header="Когда-то..."] -В старых браузерах использовались дополнительные свойства, такие как `iframe.contentDocument` и даже `iframe.document`, но они давно не нужны. -[/smart] - -В примере ниже JavaScript получает документ внутри ифрейма и модифицирует его: - -```html - - - - -``` - -[smart] -Обратите внимание, HTML `'тест'` в примере выше -- невалидный, там нет `BODY`. Поэтому ифрейм будет отображаться в режиме совместимости. - -Но браузер исправляет структуру и гарантирует, что после загрузки документа у него всегда есть `document.body` и ровно одно. -[/smart] - -В целях безопасности возможность доступа к документу в ифрейме ограничена. Если он с другого домена, на другом порту или протоколе, то доступ запрещён. Подробнее об этом ограничении и как его можно обойти -- далее, в главе [](/same-origin-policy). - -## Иерархия window.frames - -Альтернативный способ доступа к окну ифрейма -- это получить его из коллекции `window.frames`. - -Есть два способа доступа: -
    -
  1. `window.frames[0]` -- доступ по номеру.
  2. -
  3. `window.frames.iframeName` -- доступ по `name` ифрейма.
  4. -
- -В коллекции хранится именно окно (`contentWindow`), а не тег. - -Например: - -```html - - - - -``` - -Внутри ифрейма могут быть свои вложенные ифреймы. Всё это вместе образует иерархию. - -Ссылки для навигации по ней: - - - -**Свойство `top` позволяет легко проверить, во фрейме ли находится текущий документ:** - -```js -//+ run -if (window == top) { - alert('Этот скрипт является окном верхнего уровня в браузере'); -} else { - alert('Этот скрипт исполняется во фрейме!'); -} -``` - -## Событие onload - -У ифрейма есть своё событие `onload`, которое не связано с `onload` основного окна. - -Иными словами, `onload` основного окна не ждёт, пока ифрейм догрузится. - -**Событие `onload` есть и на теге `iframe` и на его окне.** - -Это важно, так как обработчик на теге более универсален. - -**В случае, когда документ с другого домена, внешний документ сможет отследить его загрузку только по `onload` на теге.** - -Например, попытаемся отследить загрузку ифрейма с сайта `http://vk.com/`: - -```html - - - - -``` - -Запустите пример выше. Вы увидите, что работает только `iframe.onload`. А если бы ифрейм был с того же домена, то сработали бы оба обработчика. - - -## Атрибуты seamless и sandbox - -В стандарте HTML5 для [iframe](http://www.w3.org/wiki/HTML/Elements/iframe) предусмотрены атрибуты `seamless` и `sandbox`. - -Оба они на момент написания (конец 2012) поддерживаются в Chrome, в других браузерах поддержка тоже не за горами. - -### seamless - -Атрибут `seamless` полностью интегрирует ифрейм в документ, убирая рамку и применяя CSS-стили внешнего окна к содержимому ифрейма, как будто это обычный элемент. - -То есть, если в основном документе есть стиль `p { font-weight: bold }`, то он повлияет и на содержимое ифрейма. - -Для JavaScript он не важен. - -### sandbox - -Атрибут `sandbox` позволяет построить "песочницу" вокруг ифрейма, запретив ему выполнять ряд действий. - -Наличие атрибута `sandbox`: - - -Пример ниже загружает в такой ифрейм документ: - -```html - - -``` - -Содержимое файла `sandboxed.html`: - -```html - - -
- -
-``` - -Запустите пример выше для просмотра. Ни форма ни скрипты не сработают. - -**Атрибут `sandbox` может содержать флаги через пробел, которые убирают ограничения:** -
-
allow-same-origin
-
Браузер может не считать документ в ифрейме пришедшим с другого же домена. Если ифрейм *и так* с другого домена, то ничего не меняется.
-
allow-top-navigation
-
Разрешает ифрейму менять `parent.location`.
-
allow-forms
-
Разрешает отправлять формы из `iframe`.
-
allow-scripts
-
Разрешает выполнение скриптов из ифрейма. Но скриптам, всё же, будет запрещено открывать попапы.
-
- -Цель атрибута `sandbox` -- наложить дополнительные ограничения. Он не может снять уже существующие, в частности, убрать ограничения безопасности, если ифрейм с другого домена. \ No newline at end of file diff --git a/3-more/7-frames-and-windows/5-same-origin-policy/article.md b/3-more/7-frames-and-windows/5-same-origin-policy/article.md deleted file mode 100644 index dec4b613..00000000 --- a/3-more/7-frames-and-windows/5-same-origin-policy/article.md +++ /dev/null @@ -1,163 +0,0 @@ -# Ограничение "Same Origin" - -Ограничение "Same Origin" ("тот же источник") ограничивает доступ окон и фреймов друг к другу, а также влияет на AJAX-запросы к серверу. - -Причина, по которой оно существует -- безопасность. Если есть два окна, в одном из которых `vasya-pupkin.com`, а в другом `gmail.com`, то мы бы не хотели, чтобы скрипт из первого мог читать нашу почту. - -Сама концепция проста, но есть много важных исключений и особенностей, которые нужно знать для полного понимания этого правила. -[cut] - -## Same Origin [[#same-origin] - -[summary] -Два URL считаются имеющим один источник ("same origin"), если у них одинаковый протокол, домен и порт. -[/summary] - -Эти URL имеют один источник: - - -А вот эти -- все из других источников: - - -Существует ряд исключений, позволяющих-таки окнам с разных доменов обмениваться информацией, но прямой вызов методов друг друга и чтение свойств запрещены. - -## Пример ограничений - -Если одно окно попытается обратиться к другому, то браузер проверит, из одного ли они источника. Если нет -- доступ будет запрещён. - -Например: - -```html - - - - -``` - -**При запуске примера выше Safari/Chrome могут вместо ошибки вывести `undefined`.** - -Это их способ (некорректный) показать, что "чтение запрещено". Будем надеяться, исправят. - - - -## Исключение: запись в location - -Окно и вложенный в него `iframe` могут менять `location` друг друга, даже если они из разных источников. - -Причём *читать* `location` нельзя, одно окно не имеет право знать, на каком URL пользователь в другом. А вот *запись* браузеры считают безопасной. - -Например, открыв на `javascript.ru` ифрейм с `vk.com`, из этого ифрейма нельзя будет узнать URL, а вот поменять его -- запросто: - -```html - - - - -``` - -## Исключение: поддомен 3го уровня - -Ещё одно важное исключение касается доменов третьего уровня. - -Например, у нас есть окно на `http://site.com` и два ифрейма: первый с источника `http://john.site.com`, а второй -- с `http://peter.site.com`. - -**Если несколько окон присваивают в `document.domain` свой общий поддомен 2го уровня, то все ограничения снимаются.** - -Важно: -
    -
  1. Должен быть общий поддомен второго уровня. - -Можно поставить `document.domain='site.com'` на странице с `my.site.com`, но нельзя это сделать на странице с `vaysa-pupkin.ru`.
  2. -
  3. Свойство `document.domain` должно быть присвоено на всех окнах, участвующих в коммуникации, в том числе на том, которое и так с этого домена. - -Выглядит абсурдно, но на документе с `site.com` нужно вызвать: `document.domain=document.domain`. Тогда будет работать.
  4. -
- - -## Исключение: порт в IE - -В браузере Internet Explorer порт не входит в понятие "источник" (origin). - -Это означает, что окно с `http://site.com` может свободно общаться с `http://site.com:8080`. - -Это иногда используют для общения разных сервисов, использующих один IP-адрес. Но допустимо такое только в IE. - -## Исключение: зона в IE - -Если сайт находится в зоне "Надёжные узлы", то в Internet Explorer ограничения к нему не применяются. - -При этом подразумевается, что для этой зоны в параметрах "Безопасность" включена опция "Доступ к источникам данных за пределами домена". - -## Общение между окнами с разных источников - -Если ни одно из исключений выше не подошло, то есть три основных способа, как окнам общаться между собой: - -
    -
  1. Все современные браузеры, включая IE8+, поддерживают специальный интерфейс `postMessage` для общения между окнами с разных доменов. Мы рассмотрим его в отдельной главе [](/cross-window-messaging-with-postmessage).
  2. -
  3. Одно окно может поменять другому `location.hash` -- часть пути после `#`. При этом не произойдёт смены `URL`, но другое окно, увидев это, может прочитать из хэша информацию и, в свою очередь, ответить. - -Этот способ испольуется там, где требуется поддержка IE7-. -
  4. -
- -В совокупности с этим можно использовать интерфейс `localStorage` для оповещении всех окон и вкладок о событии. При сохранении данных в `localStorage` генерируется событие `onstorage`, причём сразу на всех окнах, фреймах и табах с тем же доменом. - -Кроме того, если вы используете `IFRAME` вместе с AJAX, то, возможно, вам пригодятся способы, описанные в главе [](/ajax-iframe-xdomain). - - - -## Итого - -Ограничение "одного источника" запрещает окнам и фреймам с разных источников вызывать методы друг друга и читать данные друг из друга. - -При этом "из одного источника" означает "совпадают протокол, домен и порт". - -Как ни странно, у этого подхода ряд существенных исключений: - - - -В современных браузерах (IE8+) кросс-доменное общение можно организовать через `location.hash` и [postMessage](/cross-window-messaging-with-postmessage). При этом IE8 не умеет передавать данные между окнами, но, если нужно, `localStorage` передаёт всё и везде :) \ No newline at end of file diff --git a/3-more/7-frames-and-windows/7-clickjacking/article.md b/3-more/7-frames-and-windows/7-clickjacking/article.md deleted file mode 100644 index f32c303d..00000000 --- a/3-more/7-frames-and-windows/7-clickjacking/article.md +++ /dev/null @@ -1,250 +0,0 @@ -# Атака Clickjacking и защита от неё - -Атака "кликджекинг" (англ. Clickjacking) позволяет хакеру выполнить клик на сайте-жертве *от имени посетителя*. - -В русском языке встречается дословный перевод термина clickjacking: "угон клика". Так же применительно к clickjacking-атаке можно встретить термины "перекрытие iframe" и "подмена пользовательского интерфейса". - -Кликджекингу подверглись в своё время Twitter, Facebook , PayPal, YouTube и многие другие сайты. Сейчас, конечно, они уже защищены. -[cut] -## Идея атаки - -В целом идея очень проста. - -Вот как выглядит «угон клика» пользователя, который зарегистрирован на facebook: - -
    -
  1. На вредоносной странице пользователю подсовывается безобидная ссылка -(скажем, что-то скачать, «разбогатеть сейчас», посмотреть ролик или просто перейти по ссылке на интересный ресурс).
  2. -
  3. Поверх этой заманчивой ссылки помещен прозрачный iframe со страницей facebook.com, так что кнопка "Like" находится чётко над ней. - -Кликая на ссылку, посетитель на самом деле нажимает на эту кнопку. -
  4. -
- -## Пример - -Вот пример (для наглядности `iframe` -- полупрозрачный): - -```html - - - -
Нажмите, чтобы разбогатеть сейчас:
- - - - -Нажми тут! - -
..И всё получится (хе-хе, у меня, злого хакера, получится)!
-``` - -**При клике на ссылку на самом деле происходит клик на iframe (на «Like»).** - -Если посетитель авторизован на facebook (а в большинстве случаев так и есть), то facebook.com получает щелчок от имени посетителя. - -На Twitter это была бы кнопка «Follow». - -Тот же самый код, но как это было бы в реальности, с `opacity:0` для iframe (щелкните, чтобы увидеть захваченную кнопку): - -[iframe src="clickjacking" height=120 link edit] - -Итак, все, что нужно для проведения атаки -- это правильно расположить iframe на вредоносной странице. В большинстве случаев это делается средствами HTML/CSS. - -События клавиатуры захватить гораздо труднее, потому что, если `iframe` является невидимым, то текст в поле ввода также будет невидимым. Посетитель начнёт печатать, но, не увидев текст, прекратит свои действия. - -## Защита и способы обхода. - -Самый старый метод защиты -- это код JavaScript, не позволяющий отобразить веб-страницу внутри фрейма (*framebusting*, также его называют *framekilling* и *framebreaking*). - -Добавьте к документу следующий код, если не хотите, чтобы документ загружался в iframe: - - - -То есть, если окно обнаруживает, что оно загружено во фрейме, то оно автоматически делает себя верхним. - -В настоящий момент это уже не является сколько-нибудь надежной защитой. - -Есть несколько способов обхода framebusting. Давайте рассмотрим некоторые из них. - -### Блокировка top-навигации. - -Можно заблокировать переход, инициированный сменой `top.location`, в событии [onbeforeunload](#window.onbeforeunload). - -Обработчик этого события ставится на внешней (хакерской) странице и, при попытке `iframe` поменять `top.location`, спросит посетителя, хочет он покинуть данную страницу. В большинстве браузеров хакер может спросить посетителя, используя своё сообщение. - -Так что, скорее всего, посетитель ответит на такой странный вопрос отрицательно (он же не знает про ифрейм, видит только страницу, причины для ухода нет). - -В приведенном ниже примере представлен "защищенный" `iframe`: - -```html - -``` - -А вот -- хакерская страница с этим `iframe`, которая отменяет перезагрузку верхнего окна при помощи `onbeforeunload` (предполагается, что посетитель нажмёт «отмену»): - -```html - - - -``` - -[Открыть в отдельном окне (сразу спросит)](/files/tutorial/window/cj_location_hack.html). - -### security = "restricted" - -В IE8 есть особый атрибут `security = "restricted"` -- отключающий исполнение скриптов во фрейме. - -Пример использования: - -```html - -``` - -При этом клик во фрейме, если он не требует JavaScript, всё равно сработает, а вот защита -- нет. - -### HTML5 - -Одна из возможностей HTML5 -- атрибут [sandbox](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html#attr-iframe-sandbox) - -Он позволяет разрешить во фрейме скрипты `allow-scripts` и формы `allow-forms`, но запретить top-навигацию (не указать `allow-top-navigation`). - -Выглядеть это будет так: - -```html - -``` - -Сработает в браузерах, которые поддерживают `sandbox`, например -- в Chrome. - -### Ещё приёмы - -Есть и еще приёмы для обхода этой простейшей защиты. - -Firefox и старый IE могут активировать designMode на исходной странице, это также предотвращает framebusting (спасибо за идею owasp.org, страница clickjacking). - -Как мы видим, она не только не выдерживает реальной атаки, но и может скомпрометировать сайт (программист-то думает, что защитил его). - -## Надежная защита от Clickjacking - -### Заголовок X-Frame-Options - -Все современные браузеры поддерживают заголовок `X-Frame-Options`. - -Он разрешает или запрещает отображение страницы, если она открыта во фрейме. - -Браузеры игнорируют заголовок, если он определен в МЕТА тег. Таким образом, `` будет проигнорирован. - -У заголовка может быть три значения: - -
-
SAMEORIGIN
-
Рендеринг документа, при открытии во фрейме, производится только в том случае, когда верхний (top) документ -- с того же домена.
-
DENY
-
Рендеринг документа внутри фрейма запрещён.
-
ALLOW-FROM domain
-
Разрешает рендеринг, если внешний документ с данного домена (не поддерживается в Safari, Firefox).
-
- -К примеру, Twitter использует `X-Frame-Options: SAMEORIGIN`. Результат: - -```html - -``` - - - -В зависимости от браузера, `iframe` выше либо пустой, либо в нём находится сообщение о невозможности отобразить его (IE). - -### Приостановка показа документа - -Если нужно поддерживать старые браузеры (IE7-), то можно и просто отменить показ документа: - -```html - - - - - - -``` - -[warn header="Почему не `document.body`?"] -В приведенном выше примере, мы используем `document.getElementsByTagName`, вместо `document.body`, потому что это способ получения `BODY` работает во всех браузерах, когда документ еще не готов. -[/warn] - -Обратите внимание -- изначально документ скрыт. Мало ли, вдруг JavaScript во фрейме отключен -- защита сработает. - -Он будет показан только в том случае, если заведомо всё в порядке: не отключён JavaScript и страница не во фрейме. - -### Показ с отключённым функционалом - -Заголовок `X-Frame-Options` имеет неприятный побочный эффект. Иногда поисковики, анонимайзеры или другие сайты хотели бы отобразить страницу в `iframe`, по вполне "легальным" причинам, но не могут. - -Хорошо бы показывать их посетителям не пустой `iframe`, а нечто, что может быть более интересно. - -Например, можно изначально "накрывать" документ `div` с `height:100%;width:100%`, который будет перехватывать все клики. И поставить на нём ссылку, ведующую на страницу в новом окне. - -```html - - -
- Перейти на сайт -
- - -``` - -Если страница -- не во фрейме или домен совпадает, то посетитель не увидит его. - -## Заключение - -Атаку "Clickjacking" легко осуществить, если на сайте есть действие, активируемое с помощью одного клика. - -Злоумышленник может осуществить атаку через целенаправленно на посетителей ресурса -- опубликовав ссылку на форуме, или «счастливой рассылкой». Существует масса вариантов. - - - -
При участии Марата Шагиева
\ No newline at end of file diff --git a/3-more/7-frames-and-windows/7-clickjacking/cj_location.html b/3-more/7-frames-and-windows/7-clickjacking/cj_location.html deleted file mode 100755 index 1c2ba89a..00000000 --- a/3-more/7-frames-and-windows/7-clickjacking/cj_location.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - -
Меняет top.location на google.com
- - - - - - - diff --git a/3-more/7-frames-and-windows/7-clickjacking/clickjacking.view/index.html b/3-more/7-frames-and-windows/7-clickjacking/clickjacking.view/index.html deleted file mode 100755 index 430149de..00000000 --- a/3-more/7-frames-and-windows/7-clickjacking/clickjacking.view/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - -
Нажмите, чтобы разбогатеть сейчас:
- - - -Нажми тут! - -
..И ваша жизнь удалась!
- - - diff --git a/3-more/8-regular-expressions-javascript/index.md b/3-more/8-regular-expressions-javascript/index.md index c021f806..6dc875d7 100644 --- a/3-more/8-regular-expressions-javascript/index.md +++ b/3-more/8-regular-expressions-javascript/index.md @@ -1,9 +1,5 @@ # Регулярные выражения [в работе] -Регулярные выражения -- мощный способ поиска и замены строк, который используется в самых разных языках, включая, конечно, JavaScript. +Регулярные выражения -- мощный способ поиска и замены для строк. -У меня здесь для вас две новости. -
    -
  1. Первая плохая -- в JavaScript они на редкость убогие, хуже большинства существующих языков.
  2. -
  3. Вторая хорошая -- зато нам будет проще их изучить.
  4. -
+В JavaScript они поддерживаются в простом варианте, менее мощном, чем в большинстве других языков. Но зато нам будет проще их изучить.