Автор материала, перевод которого мы публикуем сегодня, говорит, что существует множество причин изучать веб-безопасность. Например, вопросами безопасности интересуются пользователи веб-сайтов, которых беспокоит возможность кражи их персональных данных. Безопасность заботит веб-разработчиков, которые стремятся к повышению уровня защиты создаваемых ими проектов. То же самое можно сказать и о начинающих программистах, которые ищут работу и готовятся к собеседованиям. Цель этой статьи заключается в том, чтобы понятным языком рассказать о некоторых важных технологиях веб-безопасности. Прежде чем приступить к разговору об этих технологиях, при упоминании которых обычно оперируют сокращениями вроде CORS, CSP и HSTS, рассмотрим пару базовых концепций безопасности.
Две базовых концепции веб-безопасности
▍100% защита — это миф
В мире безопасности нет такого понятия, как «100% защита от взлома». Если кто-нибудь когда-нибудь скажет вам о таком уровне защиты, знайте, что он ошибается.
▍Одного уровня защиты недостаточно
Предположим, некто полагает, что реализовав CSP, он полностью защитил свой проект от XSS-атак. Возможно, кто-то воспринимает то, что абсолютной защиты не существует, как данность, но мысли, подобные вышеописанной, могут посетить кого угодно. Если вести речь о программистах, которые решили разобраться в вопросах безопасности, то, возможно, причиной возникновения таких мыслей является тот факт, что, при написании программного кода, они, в основном, оперируют такими понятиями, как «чёрное» и «белое», 1 и 0, «истинно» и «ложно». Но в безопасности не всё так просто.
Технологии веб-безопасности
Начнём разговор о веб-безопасности с технологии, на которую разработчики обычно обращают внимание очень рано, скажем, в самом начале своего профессионального пути. Кстати, если задаться целью обхода этого метода защиты, на StackOverflow можно найти массу сведений о том, как это сделать. Речь идёт о CORS.
▍CORS
Видели когда-нибудь такую ошибку:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
Встретившись с подобным, вы думаете, что вы, уж точно, не первый, с кем это случилось. Погуглив, вы выясняете, что, для того, чтобы эту проблему решить, достаточно установить некое расширение. Ну не замечательно ли? Однако технология CORS (Cross-Origin Resource Sharing, совместное использование ресурсов между разными источниками) существует не для того, чтобы мешать разработчикам, а для того, чтобы защищать их проекты.
Для того чтобы понять, как CORS позволяет защищать веб-проекты, сначала поговорим о куки-файлах, в частности — о куки, используемых для аутентификации пользователей. Подобные куки используются, при работе с неким веб-ресурсом, для того, чтобы сообщить серверу о том, что пользователь вошёл в систему. Они автоматически отправляются с запросами, выполняемыми к соответствующему серверу.
Предположим, вы вошли в свою учётную запись на Facebook, при этом Facebook использует аутентификационные куки. Работая в интернете, вы щёлкаете по ссылке bit.ly/r43nugi
, вас перенаправляют на некий вредоносный сайт, скажем, на что-то вроде superevilwebsite.rocks
. Скрипт, загруженный вместе со страницей этого сайта, выполняет клиентский запрос к facebook.com
, используя ваш аутентификационный куки-файл.
В мире, где не было бы CORS, скрипт с superevilwebsite.rocks
мог бы скрытно внести изменения в ваш FB-профиль, мог бы украсть какую-то информацию, со всеми вытекающими отсюда последствиями. В таком мире легко могла бы возникнуть «эпидемия superevilwebsite.rocks», когда скрипт, захватывающий управление аккаунтом пользователя, публикует на его странице ссылку, перейдя по которой друзья этого пользователя, «заражаются» сами, а через ссылки, опубликованные на их страницах, эпидемия, в итоге, охватывает весь Facebook.
Однако в мире, где есть CORS, Facebook разрешал бы только запросы на изменение данных учётных записей с источником facebook.com
. Другими словами, администрация сайта ограничила бы совместное использование ресурсов между разными источниками.
Тут у вас может возникнуть следующий вопрос: «Но ведь superevilwebsite.rocks может просто изменить заголовок источника в своих запросах, и они будут выглядеть так, будто идут от facebook.com?».
Мошеннический сайт может попытаться это сделать, но у него ничего не получится, так как браузер будет игнорировать подобный заголовок и использовать реальные данные.
«А что если superevilwebsite.rocks выполнит подобный запрос с сервера?», — спросите вы.
В подобной ситуации CORS можно обойти, но никакого толку от этого не будет, так как, выполняя запрос с сервера, нельзя будет передать Facebook аутентификационный куки-файл. Поэтому скрипту, для успешного выполнения подобного запроса, необходимо выполняться на стороне клиента и иметь доступ к куки-файлам, хранящимся на клиенте.
▍CSP
Для того чтобы разобраться в том, что такое CSP (Content Security Policy, политика защиты контента), сначала надо поговорить об одной из самых распространённых веб-уязвимостей. Речь идёт о XSS (cross-site scripting, межсайтовый скриптинг).
При выполнении XSS-атаки злоумышленник внедряет специальный JavaScript-код в клиентскую часть некоего сайта. Можно подумать: «Ну и что будет делать этот скрипт? Менять цвета элементов страниц?».
Предположим, что некто успешно внедрил свой JS-скрипт в страницы сайта, на который вы зашли. Что опасного может сделать подобный скрипт? На самом деле, много всего:
- Он может выполнять HTTP-запросы к другим сайтам, притворяясь, что делаете их вы.
- Он может перенаправить вас на сайт, который выглядит точно так же как тот, на который вы вошли, но рассчитан, например, на кражу учётных данных.
- Он способен добавлять на страницы теги
<script>
, содержащие некий JavaScript-код или рассчитанные на на загрузку каких-то JS-файлов. - Он может добавить на страницу элемент
<iframe>
, который будет, например, выглядеть в точности так же, как поля для ввода имени и пароля для входа на сайт. При этом настоящие поля для ввода таких данных будут скрыты.
На самом деле, возможности, открывающиеся перед злоумышленником при успешном выполнении XSS-атаки, безграничны.
Политика защиты контента пытается предотвратить подобное, применяя следующие ограничения:
- Ограничения на то, что может быть открыто в
<iframe>
. - Ограничения на то, какие таблицы стилей могут быть загружены.
- Ограничения на то, какие запросы можно выполнять.
Как же работает CSP?
Когда вы щелкаете по ссылке или вводите URL веб-сайта в адресной строке браузера, браузер выполняет GET-запрос. Запрос приходит на сервер, который передаёт браузеру некий HTML-код вместе с HTTP-заголовками. Если вам интересно посмотреть на эти заголовки — откройте, в инструментах разработчика браузера, вкладку Network, и посетите несколько сайтов. Заголовок ответа может выглядеть примерно так:
content-security-policy: default-src * data: blob:;script-src *.facebook.com *.fbcdn.net *.facebook.net *.google-analytics.com *.virtualearth.net *.google.com 127.0.0.1:* *.spotilocal.com:* 'unsafe-inline' 'unsafe-eval' *.atlassolutions.com blob: data: 'self';style-src data: blob: 'unsafe-inline' *;connect-src *.facebook.com facebook.com *.fbcdn.net *.facebook.net *.spotilocal.com:* wss://*.facebook.com:* https://fb.scanandcleanlocal.com:* *.atlassolutions.com attachment.fbsbx.com ws://localhost:* blob: *.cdninstagram.com 'self' chrome-extension://boadgeojelhgndaghljhdicfkmllpafd chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm;
Это — политика безопасности контента facebook.com
. Преобразуем её к более удобному для чтения виду:
content-security-policy:
default-src * data: blob:;
script-src *.facebook.com *.fbcdn.net *.facebook.net *.google-analytics.com *.virtualearth.net *.google.com 127.0.0.1:* *.spotilocal.com:* 'unsafe-inline' 'unsafe-eval' *.atlassolutions.com blob: data: 'self';
style-src data: blob: 'unsafe-inline' *;
connect-src *.facebook.com facebook.com *.fbcdn.net *.facebook.net *.spotilocal.com:* wss://*.facebook.com:* https://fb.scanandcleanlocal.com:* *.atlassolutions.com attachment.fbsbx.com ws://localhost:* blob: *.cdninstagram.com 'self' chrome-extension://boadgeojelhgndaghljhdicfkmllpafd chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm;
Рассмотрим представленные здесь директивы CSP:
default-src
— запрещает всё, что не задано в явном виде.script-src
— вводит ограничения на загружаемые скрипты.style-src
— вводит ограничения на загружаемые таблицы стилей.connect-src
— вводит ограничения на URL, ресурсы с которых которые могут быть загружены с использованием скриптовых интерфейсов, таких, какfetch
,XHR
,ajax
, и так далее.
Обратите внимание на то, что, на самом деле, существует множество таких директив. Браузер читает CSP-заголовок и применяет соответствующие правила в пределах загруженного HTML-файла. Правильно настроенные директивы разрешают выполнение лишь тех действий, которые необходимы для правильной работы страницы.
Если CSP-заголовка у страницы нет, тогда никаких запретов к ней не применяется. Символы * в CSP-заголовке — это подстановочные знаки. Такой знак можно заменить чем угодно, и то, что получится, окажется разрешённым.
▍HTTPS
Наверняка вы слышали об HTTPS (HTTP Secure). Возможно, вам доводилось встречать примерно такие высказывания: «Зачем мне беспокоиться об HTTPS, если я просто играю в игру на сайте?». Или, возможно, вы сталкивались с такой идеей: «Если у вас нет HTTPS — то это просто безумие. На дворе 2018 год! Не верьте никому, кто говорит, что без HTTPS можно обойтись».
Возможно, вы слышали о том, что теперь Chrome маркирует сайт как небезопасный, если он не использует HTTPS.
Основное отличие HTTPS от HTTP заключается в том, что, при передаче данных по HTTPS они зашифровываются, а при передаче по HTTP — нет.
Почему на это стоит обращать внимание при передаче ценных данных? Всё дело в том, что при организации обмена данными по незащищённому каналу связи существует возможность MITM-атаки (Man In The Middle, атака посредника, или атака «человек посередине»).
Если вы, сидя в кафе, выходите в интернет через открытую точку доступа Wi-Fi, кто-то, довольно просто, может прикинуться маршрутизатором, через который идут все ваши запросы и ответы. Если ваши данные не зашифрованы, то посредник может сделать с ними всё, что ему вздумается. Скажем, он сможет редактировать HTML, CSS или JavaScript-код прежде чем он поступит с сервера в ваш браузер. Учитывая то, что мы уже знаем о XSS-атаках, вы можете представить, к каким последствиям это может привести.
«Как же это возможно: мой компьютер и сервер знают, как шифровать и дешифровать данные, которыми мы обмениваемся, а посредник-злоумышленник — нет?», — спросите вы. Это возможно благодаря использованию протокола SSL (Secure Sockets Layer) и более свежего протокола TLS (Transport Layer Security). TLS заменил SSL в 1999 году в качестве технологии шифрования, используемой в HTTPS. Обсуждение особенностей TLS выходит за рамки этого материала.
▍HSTS
Технология HSTS (HTTP Strict-Transport-Security, механизм принудительной активации защищённого соединения через протокол HTTPS) устроена довольно просто. В качестве примера снова рассмотрим соответствующий заголовок Facebook:
strict-transport-security: max-age=15552000; preload
Проанализируем его:
max-age
задаёт время, в течение которого браузер должен принудительно переводить пользователя на работу с веб-сайтом по HTTPS.preload
— для наших целей это не важно.
Этот заголовок применяется только в том случае, если вы получаете доступ к сайту с использованием HTTPS. Если вы работаете с сайтом через HTTP, данный заголовок игнорируется. Причина этого весьма проста: обмен данными по HTTP защищён настолько слабо, что подобному заголовку нельзя доверять.
Снова прибегнем к примеру с Facebook для демонстрации практической полезности механизма HSTS. Предположим, вы в первый раз входите на facebook.com и при этом знаете, что HTTPS безопаснее, чем HTTP, поэтому вы используете такую ссылку: https://facebook.com
. Когда ваш браузер получает HTML-код, он получает и заголовок, который сообщает браузеру о том, что он должен принудительно переводить вас на HTTPS при выполнении будущих запросов. Через месяц кто-то отправляет вам HTTP-ссылку на Facebook, http://facebook.com
, и вы по ней щёлкаете. Так как месяц — это меньше, чем срок в 15552000 секунд, заданный директивой max-age
, браузер отправит запрос по HTTPS, предотвращая потенциальную MITM-атаку.
Итоги
Сегодня мы обсудили некоторые технологии, которые повсеместно применяются для обеспечения безопасности веб-проектов. Полагаем, вопросы безопасности — это очень важно, так как они касаются абсолютно всех, кто связан с интернетом. Тема веб-безопасности огромна, поэтому нельзя говорить о том, что, после прочтения нескольких статей некто станет экспертом в этой области или хотя бы узнает достаточно для того, чтобы эффективно защитить свой веб-проект или свои личные данные. Но, как и в любой другой области, знания в сфере безопасности, при наличии желания их получать, накапливаются и их количество постепенно переходит в качество. Надеемся, этот материал сделал свой вклад в вашу систему знаний о веб-безопасности.
Уважаемые читатели! Сталкивались ли вы со случаями безответственного отношения к безопасности со стороны веб-разработчиков?
Автор: ru_vds