# Client side security - Practice К решению прикладывайте скриншоты и код, который добавили в `client-side-playground`. Можете оставить комментарии к результатам, например, почему произошла ошибка. ## 1. SOP ### 1.1 `iframe` / window Вместо `iframe` можно открывать новое окно. - [ ] Открыть `iframe` со страницей на **том же** `Origin`. ![](https://i.imgur.com/9ZkStBH.png) - [ ] Прочитать содержимое `iframe` из Javascript. ![](https://i.imgur.com/rDdB1mE.png) удалось прочитать содержимое из iframe - [ ] Открыть `iframe` со страницей на **другом** `Origin`. ![](https://i.imgur.com/VQPQu3b.png) - [ ] Прочитать содержимое `iframe` из Javascript. ![](https://i.imgur.com/2sG6sBp.png) не удалось прочитать содержимое iframe из другого origin ### 1.2 inherited origins - [ ] С основной страницы открыть окно `about:blank` и посмотреть `Origin` (`document.domain`). ![](https://i.imgur.com/y8qrqrM.png) about:blank наследует origin родителя - [ ] С основной страницы открыть окно со схемой `data:` и посмотреть `Origin`. ![](https://i.imgur.com/EoNNRpl.png) data: не наследует origin ### 1.3 changing origin - [ ] Открыть страницу с одного поддомена (`a.hu.io`). - [ ] С первой страницы открыть другую со второго домена (`b.hu.io`). - [ ] Проверить взаимную доступность DOM через `Window` объект и `window.opener` соответственно. ![](https://i.imgur.com/brPjvYQ.png) ![](https://i.imgur.com/dAmWIcQ.png) доступ для страниц из разных origin-ов отсудствует - [ ] Провести смену домена (`document.domain = 'hu.io'`) и повторитть проверку. ![](https://i.imgur.com/qBaAXuQ.png) ![](https://i.imgur.com/WEaR5hv.png) при помощи document.domain удалось сменить origin-контекст и получить доступ к документам - [ ] Открыть страницу с `Feature-Policy: document-domain 'none';` и попробовать сменить домен. ![](https://i.imgur.com/Gl5nUeB.png) ![](https://i.imgur.com/1jeic9Z.png) в firefox можно сменить домен на родительский, но нельзя на сторонний. ![](https://i.imgur.com/gLz7fHj.png) в chrome нельзя сменить origin (даже на родительский) ### 1.4 interpage communication - [ ] Сделать страницу, которая слушает сообщения и возвращает их обратно через `postMessage`. - [ ] Обеспечить, чтобы обратное сообщение получила страница с тем же `Origin`. ![](https://i.imgur.com/AowRjlY.png) ![](https://i.imgur.com/jlKY3nZ.png) на скрине видно, что принимающий скрипт на origin-e b.hu.io не пересылает сообщение обратно отправителю a.hu.io; а если origin отправителя и получателя совпадают - то отправитель получит свое сообщение обратно ### 1.5 Cross-Origin-Opener-Policy - [ ] Сделать страницу, которая возвращает заголовок `Cross-Origin-Opener-Policy: same-origin`. ![](https://i.imgur.com/ZYicI0Z.png) - [ ] Открыть эту страницу с другой страницы с **таким же** `Origin` и отличающимся. - [ ] В обоих случаях посмотреть на `Window` объект и значение `window.opener`. без заголовка `Cross-Origin-Opener-Policy: same-origin` мы можем получить доступ к `window.opener` ![](https://i.imgur.com/dLZkQ8P.png) ![](https://i.imgur.com/HW2Psdf.png) после установки заголовка `Cross-Origin-Opener-Policy: same-origin` в `window.opener` уже содержится null ![](https://i.imgur.com/U4pZuX7.png) ![](https://i.imgur.com/lrvKlDq.png) ## 2. CORS ### 2.1 forms - [ ] Сделать форму, которая отправляет POST запрос на другой `Origin`. - [ ] Посмотреть на предаваемые в запросе заголовки. ![](https://i.imgur.com/tRDbCjV.png) Успешно сливаются данные на другой origin ### 2.2 simple - [ ] Выставить куки на домене `b.hu.io`. ![](https://i.imgur.com/hmHhVWD.png) - [ ] Реализовать эндпоинт-обработчик POST запроса, который возвращает: - `Access-Control-Allow-Origin: <request_origin>` - [ ] Сделать запрос с `a.hu.io` на этот эндпоинт. - [ ] Посмотреть, были ли присланы куки. ![](https://i.imgur.com/dhSWPtd.png) cookies не отправлялись т.к. мы не установили флаг withCredentials - [ ] Реализовать эндпоинт-обработчик POST запроса, который возвращает: - `Access-Control-Allow-Origin: *` - `Access-Control-Allow-Credentials: true` - [ ] Сделать запрос с `a.hu.io` на этот эндпоинт. - [ ] Описать ошибку из консоли. ![](https://i.imgur.com/FdhCjpX.png) запрос успешно был принят сервером и обработан браузером. ошибки в консоли не было скорее всего упущен пункт о том,что надо установить флаг withCredentials. Если выполнять с ним - то мы получим ошибку о том, что для запроса с credentials мы не можем определять `Access-Control-Allow-Origin: *` звездочкой, необходимо указать конкретный origin. ![](https://i.imgur.com/EkRqxyf.png) ### 2.3 preflight - [ ] Реализовать эндпоинт, отвечающий на методы `OPTIONS` и `POST`. На `POST` **только с кукой**. - [ ] Настроить хедеры в ответах так, чтобы запрос с другого `Origin` успешно отрабатывал и получал JSON-значение в ответ. (Разрешение кросс-сайт авторизованных запросов) по постановке задачи есть простая реализация без preflight, в ответе отдается json и куки тоже нормально отправляются ![](https://i.imgur.com/umrrILU.png) поскольку тут нужно именно preflight - то решение будет следующим ![](https://i.imgur.com/9UkYNb5.png) ![](https://i.imgur.com/N5EFfZw.png) ![](https://i.imgur.com/vWeltQq.png) ![](https://i.imgur.com/8bP8EDa.png) ## 3. CSP ### 3.1 default - [ ] Реализовать страницу, на которую можно загружать ресурсы только с того же `Origin`, а картинки из любого места. - [ ] Предъявить CSP. ![](https://i.imgur.com/z0R6vzP.png) ![](https://i.imgur.com/n4qtWW8.png) при помощи CSP для картинок разрешили загрузку со всех доменов, а для всех остальных ресурсов разрешили загрузку ресурсов только с текущего origin ### 3.2 unsafe-inline - [ ] Реализовать страницу, на которую нельзя ничего загружать, но можно использовать inline стили и скрипты. - [ ] Предъявить CSP. ![](https://i.imgur.com/rP8qfGA.png) ![](https://i.imgur.com/OQ2dXs1.png) видим, что встроеный JS и стили применились, в то время как сторонний ресурс был заблокирован ### 3.3 connect-src - [ ] Разрешить обращения через `Fetch API` только на **другой** `Origin`. - [ ] Предъявить CSP. если в этом задании под другим ресурсом подразумевается один другой конкретный (например, b.hu.io) - то решение имеет вид: ![](https://i.imgur.com/WN2Jx2L.png) ![](https://i.imgur.com/ojpPege.png) ![](https://i.imgur.com/S6PkkIy.png) мы видим, что загрузился и выполнился только 1 js - с origin b.hu.ui Если же по заданию нужно запретить загрузку из текущего origin и разрешить все остальные - то это невозможно (политики подразумевают работу по белым спискам, а все сайты мы перечислить не можем) https://stackoverflow.com/questions/46831368/content-security-policy-as-a-blacklist ### 3.4 framing - [ ] Сделать вложенную структуру из фреймов следующего вида: 1. Главная страница - origin='a.hu.io'. 2. Фрейм 1 на главной странице - origin='b.hu.io', защиты нет. 3. Фрейм 2 внутри фрейма 1 - origin='b.hu.io', защита `Same-Origin`. - [ ] Для фрейма 2 разрешить `Same-Origin` фрейминг сначала с помощью `X-Frame-Options`, а потом с помощью `frame-ancestors`. Сравнить результаты. ![](https://i.imgur.com/YDHR6jA.png) ![](https://i.imgur.com/cpOHmAN.png) для firefox 86.0 результат эксперимента показал одинаковый результат ### 3.5 subresource integrity - [ ] Вставить скрипт с CDN jquery с `integrity` и `crossorigin` аттрибутами. Проверить, что работает. ![](https://i.imgur.com/wGtpeBN.png) ![](https://i.imgur.com/HmZCs5S.png) - [ ] Испортить хеш и посмотреть на ошибки. ![](https://i.imgur.com/fvHyX90.png) браузер не стал загружать 'битую' библиотеку - [ ] Убрать атрибуты `integrity` и `crossorigin` и разрешить эту библиотеку через CSP. не понятна суть проверок т.к. в данном блоке CSP мы не настраивали и вставка без аттрибутов `integrity` и `crossorigin` приведет к класическому способу подключения js-библиотек. ## 4. Cookies ### 4.1 cookies identity - [ ] Проверить пример из секции `Cookies identity`. Показать, какие куки прилетают. ![](https://i.imgur.com/jhKJGXp.png) ![](https://i.imgur.com/yYBkWke.png) ![](https://i.imgur.com/Nwf5sz6.png) отправляются все установленные cookies ### 4.2 same-site - [ ] Выставить разные по значению куки на поддоменах `a.hu.io` и `b.hu.io`, на корень, с `SameSite=Strict`. - [ ] Сделать запросы на оба поддомена. Посмотреть какие куки прилетают. ![](https://i.imgur.com/rgD08im.png) ![](https://i.imgur.com/98FhhK1.png) ![](https://i.imgur.com/SPufhWd.png) ![](https://i.imgur.com/Yx2yFld.png) установлены cookies на 4 домена hu.io, .hu.io, a.hu.io, b.hu.io ![](https://i.imgur.com/AfogrhV.png) ![](https://i.imgur.com/N1sBa92.png) при выполнении запросов на домены a.hu.io и b.hu.io отправляются cookies для доменов a.hu.io,.hu.io; b.hu.io,.hu.io соответственно. ### 4.3 history API - [ ] Выставить разные куки на разные пути. ![](https://i.imgur.com/OJdzJGu.png) ![](https://i.imgur.com/savzHZR.png) - [ ] Поменять путь документа с помощью History API. - [ ] Отправить запрос на сервер. Посмотреть для какого пути прилетают куки. ![](https://i.imgur.com/dDI9j4i.png) поменял location для страницы с page1 на path2, сделал запрос на path2 и вижу что cookies отправляются для path2, хотя ожидалось что будут отправлены для path1 Вывод: Firefox 86.0 меняет контекст для cookies при использовании History Api, к запросу добавляется та cookies, которая соответствует path в для текущего запроса Повторный эксперимент для статической картинки с относительным путем: ![](https://i.imgur.com/a2Jf12l.png) ![](https://i.imgur.com/VoSaC2Z.png) ## 5. Other ### 5.1 mixed content - [ ] Сделать страницу, которая включает как HTTPS ресурсы, так и HTTP. - [ ] Посмотреть ошибки в консоли. ![](https://i.imgur.com/ZgeOEQN.png) браузер не блокирует mixed insecure content ### 5.2 nosniff - [ ] Сделать страницу, которая включает в качестве скрипта текстовый файл с расширением `.txt`. ![](https://i.imgur.com/kOYUVYV.png) - [ ] Посмотреть, выполнится ли скрипт. ![](https://i.imgur.com/IqlrFW6.png) ![](https://i.imgur.com/EIWGZN3.png) скрипт выполняется, наблюдаем warning - [ ] Добавить в ответ сервера исходной страницы `X-Content-Type-Options: nosniff`. - [ ] Посмотреть, выполнится ли скрипт. Посмотреть на ошибки в консоли. ![](https://i.imgur.com/P6dYK2H.png) После включения заголовка `X-Content-Type-Options: nosniff` браузер перестал выполнять скрипт ### 5.3 referer - [ ] Сделать `Same-Origin` и `Cross-Origin` запросы со страницы. Посмотреть в каком виде летит `Referer`. ![](https://i.imgur.com/YFv2hKE.png) ![](https://i.imgur.com/iCjiroZ.png) Referer приходит в виде полного URI - [ ] Запретить отправку `Referer` с этой страницы через `Referer-Policy`. Проверить на запросах из первого пункта. ![](https://i.imgur.com/1HVXuuj.png) ![](https://i.imgur.com/tmoLPLY.png) ![](https://i.imgur.com/FoCD13S.png) после запрета передачи Referer у нас заголовок Referer перестал передаваться вообще Referer ### 5.4 spying service worker - [ ] Установить шпионящего `Service Worker` на поддомен `a.hu.io`, который отправляет пути и параметры запросов на домен `b.hu.io`. ![](https://i.imgur.com/L0McGCw.png) ![](https://i.imgur.com/AXuuRpD.png) ![](https://i.imgur.com/w6wM9wZ.png) реализован `Service Worker`-шпион, который сливает всю информацию по запросам на сторонний домен `b.hu.io`