Web security

Есть множество причин изучать веб-безопасность, например:

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

и так далее.

Что ж, этот пост раскроет некоторые распространённые аббревиатуры, простым языком, но достаточно точно.

Перед тем как начать, давайте убедимся в понимании, двух важных концепций безопасности.

Две основные концепции безопасности

Никто на 100% не защищён. Никогда.

Нет такого понятия, как быть защищенным от взлома на 100%. Если вам скажут обратное, то это не правда.

Одного слоя защиты недостаточно.

Нельзя просто сказать…

Я в безопасности, потому что внедрил CSP. Теперь можно вычеркнуть межсайтовый скриптинг из списка уязвимостей, потому что этого не может произойти.

Одна из причин, которая подталкивает программистов к мысли о защищенности — это бинарное мышление. Чёрное или белое, 1 или 0, истина или ложь. Однако с безопасностью всё не так просто.

Начнём с того, с чем сталкивается каждый, в самом начале пути веб-разработчика. А потом, на StackOverflow находит кучу советов, как это можно обойти.

Совместное использование ресурсов между разными источниками (CORS).

Получали когда-нибудь такую ошибку?

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

Вы не одиноки. И когда вы начинаете гуглить — кто-нибудь обязательно посоветует вам установить расширение, которое избавит вас от всех проблем.

Здорово, правда?

CORS — для того чтобы защитить вас, а не навредить!

Чтобы объяснить, как CORS помогает вам, сначала поговорим о cookie, в частности об аутентификации. Файлы cookie используются, чтобы сообщить серверу, что вы вошли в систему, и они будут автоматически отправляться с любым запросом на этот сервер.

Допустим вы залогинились в Facebook, и они используют cookies для аутентификации. Вы кликаете по bit.ly/r43nugi и переходите наSuperEvilWebsite.rocks. Скрипт на superevilwebsite.rocks делает клиентский запрос к facebook.com,который отправляет ваши cookies для проверки на подлинность.

Без CORS, они могли бы внести изменения в ваш аккаунт. Вы бы даже не узнали об этом. До тех пор, конечно, пока они не запостят bit.ly/r43nugi в вашей ленте, и все ваши друзья кликнут по ссылке. После чего они запостятbit.ly/r43nugi в ленте ваших друзей, и этот порочный круг захватит всех пользователей Facebook, и superevilwebsite.rocks захватит весь мир. 😆

Благодаря CORS, для редактирования данных на сервере, Facebook допускает запросы только от источника facebook.com. Другими словами: они ограничивают совместное использование ресурсов из разных источников. Возникает вопрос…

Может ли superevilwebsite.rocks изменить заголовок источника в запросе, так, как будто он исходит от facebook.com?

Они могут попытаться, но это не сработает, потому что браузер проигнорирует запрос и использует подлинный источник.

Хорошо, но что если superevilwebsite.rocks создаст запрос на стороне сервера?

В этом случае они могут обойти CORS, но безуспешно, потому что не смогут отправить ваши cookies с подтверждением аутентификации. Чтобы получить доступ к cookies со стороны клиента, скрипт необходимо выполнить на машине пользователя.

Политика защиты контента (CSP)

Чтобы понять CSP, нам сначала нужно поговорить об одной из самых распространенных уязвимостей в интернете. XSS — межсайтовый скриптинг.

XSS — это когда злоумышленник внедряет JavaScript в клиентский код. Вы можете подумать…

Что они собираются сделать? Изменить цвет с красного на синий?

Предположим, что кто-то успешно внедрил JavaScript в клиентский код веб-сайта, который вы посетили.

Что плохого они могут сделать?

    • Они могут отправлять HTTP-запросы на другой сайт, притворяясь вами.
    • Они могут добавить якорный тег, чтобы направить вас на вредоносный сайт, который выглядит в точности как тот, который вы посетили.
    • Они могут добавить скриптовый тег со встроенным JavaScript.
    • Они могут добавить тег со скриптом, который извлекает удаленный файл JavaScript.
  • Они могут добавить iframe поверх страницы, который выглядит как часть сайта, предлагающая ввести пароль.

Возможности безграничны.

CSP пытается предотвратить подобное, ограничивая:

    • что можно открыть в iframe
    • какие стили можно загружать
  • где можно делать запросы и т.д.

Итак, как же это работает?

Когда вы кликаете по ссылке или вводите 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;

Это политика защиты контента (CSP) 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;

Подробнее разберём эти директивы.

    • default-src ограничивает все директивы CSP, которые явно не указаны в списке.
    • script-src ограничивает скрипты, которые могут быть загружены.
    • style-src ограничивает таблицы стилей, которые могут быть загружены.
  • connect-src ограничивает URL, которые могут быть загружены с помощью скрипта, fetch, XHR, ajax и т.д.

Обратите внимание, что существует гораздо больше директив CSP, кроме тех, что показанны выше. Браузер прочитает заголовок CSP и применит эти директивы ко всему в HTML-файле, который был получен. Если директивы заданы надлежащим образом, они допускают только то, что необходимо.

Если CSP заголовок отсутствует, то допускается всё, без ограничений. Везде, где вы видите * можно мысленно представить что угодно, и это будет разрешено.

HTTPS

Наверняка, вы слышали о HTTPS. Может быть, вы слышали, как некоторые говорят…

Зачем мне заботится об использовании HTTPS, если я просто играю в игру на сайте?

Или может вы слышали нечто такое…

Вы безумец, если ваш сайт не использует HTTPS. На дворе 2018 год! Не верьте тем, кто говорит обратное.

Вероятно, вы слышали, что Chrome пометит ваш сайт как небезопасный, если он без HTTPS.

По сути, HTTPS довольно понятен. HTTPS зашифрован, а HTTP нет.

Так почему же это имеет значение, если вы не отправляете конфиденциальные данные?

Приготовьтесь к очередной аббревиатуре… MITM (Man in the Middle), что означает «человек посередине».

Если вы используете публичный Wi-Fi в кафе, без пароля, для кого-то будет довольно легко действовать как ваш маршрутизатор, так что все запросы и ответы будут проходить через него. Если ваши данные не зашифрованы, они могут делать с ними все, что угодно. Можно редактировать HTML, CSS или JavaScript еще до того, как они попадут в ваш браузер. Учитывая то, что мы знаем о XSS, можно себе представить, насколько это плохо.

Хорошо, но как получилось, что мой компьютер и сервер знают, как зашифровать/дешифровать, а этот MITM нет?

Вот тут в дело вступает SSL (уровень защищённых cокетов) и более новый TLS (защита транспортного уровня). TLS пришёл на смену SSL в 1999 году как технология шифрования используемая с HTTPS. То, как работает TLS, выходит за рамки данной статьи.

HTTP Strict-Transport-Security (HSTS)

Это довольно просто. Давайте снова возьмём заголовок Facebook в качестве примера:

strict-transport-security: max-age=15552000; preload
    • max-ageопределяет как долго браузер должен помнить, что данный сайт должен посещаться исключительно по HTTPS.
  • preloadне имеет значения в нашем случае. Это сервис Google и он не входит в спецификацию HSTS.

Этот заголовок применяется только при доступе к сайту по протоколу HTTPS. При доступе к сайту по HTTP, заголовок игнорируется. Причина в том, что, HTTP настолько небезопасен, что ему нельзя доверять.

Используем пример Facebook, чтобы еще раз продемонстрировать, как это полезно на практике. Вы заходите на facebook.com впервые, и вы знаете, что HTTPS безопаснее чем HTTP, поэтому вы заходите через HTTPS: https://facebook.com. Ваш браузер принимает HTML с заголовком, который указывает вашему браузеру, принудительно перенаправлять вас на HTTPS для будущих запросов. Месяц спустя, кто-то присылает вам HTTP ссылку на Facebook http://facebook.com и вы кликаете по ней. Так как в одном месяце меньше 15552000 секунд, указанных в директиве max-age ваш браузер, отправит запрос по HTTPS, предотвратив потенциальную MITM атаку.

Заключение

Веб-безопасность важна независимо от того, каковы ваши задачи в веб-разработке. Чем больше вы уделяете этому внимания, тем лучше для вас. Безопасность — это то, что должно быть важно для всех, а не только для людей, у которых это явно указано в названии должности! 👮