Защита веб-приложений #
Васильев Андрей Михайлович, 2023
Версии презентации
Виды информации #
В рамках веб-приложений приходится работать с разными видами информации:
- Публичная: описание товаров, статьи и т.д.
- Конфиденциальная: ФИО пользователей, пароли, банковские данные
Конфиденциальную информацию необходимо защищать:
- Компании-конкуренты могут неправомерно использовать эту информацию
- Вредители могут перехватить управление веб-приложением, причинив финансовый вред как владельцу сайта, так и его пользователям
- Вредители могут воспользоваться этой информацией для вреда клиентам сайта
Веб-браузеры включают в себя множество средств защиты информации, на стороне веб-приложения разработчику тоже необходимо поддерживать должный уровень безопасности
Безопасность и конфиденциальность #
Данные концепции являются различными, но сильно связными
- Безопасность — это процесс защиты личных данных и систем от несанкционированного доступа
- Конфиденциальность — это предоставление пользователю возможность контролировать как его данные собираются, хранятся, используются и не используются безответственно
Хорошая безопасность является необходимой для обеспечения конфиденциальности. Обеспечение исключительно конфиденциальности может привести к краже или порче данных системы
Функции безопасности веб-браузера #
Рассмотрим базовые возможности по обеспечению безопасности в веб-браузерах
- Шифрование канала передачи данных
- Контроль источника запроса, CORS
- Контексты безопасности (важно для подключения JavaScript-документов)
- . . .
Шифрование канала передачи данных #
Корректно зашифрованный поток передачи данных обеспечивает безопасную передачу данных между веб-браузером и сервером: если данные будут перехвачены третьей стороной, то они не смогут их проанализировать
На настоящий момент безопасным считается шифрование с помощью TLS, лежащего в основе протокола HTTPS
Для реализации шифрования необходимо:
- Зафиксировать доменное имя сервера (получить доступ или приобрести)
- Получить подписанный сертификат, являющийся основой для шифрования данных
- Можно заплатить доверенному центру сертификации
- Можно обратиться к сервису автоматизированного управления сертификатами (Automated Certificate Management Environment, ACME), например Let’s Encrypt
- Подключить сертификат к веб-серверу либо внутри веб-приложения, либо на уровне прокси-сервера
Без реализации шифрования обеспечить безопасность невозможно
Особенности шифрования #
- Веб-сервер может установить заголовок Strict-Transport-Security, чтобы указать необходимость использования HTTPS
- Прозрачность сертификатов позволяет веб-браузеру отслеживать некорректно используемые сертификаты
- Веб-браузер может отображать смешанное содержимое, т.е. когда часть данных получена по шифрованному каналу, а часть данных по незашифрованному каналу. Даже частичная передача данных по нешифрованному каналу может значительно снизить безопасность. По умолчанию такое поведение блокируется, что хорошо
- Сервер может использовать устаревшие схемы шифрования, что значительно снижает безопасность пользователя, своевременно обновляйте настройки шифрования, которые устанавливает сервер
Контроль источника запроса #
Следующие технологии используются для реализации данной технологии
- Политика одинакового источника определяет как документ или скрипт, загруженный с одного источника может взаимодействовать с ресурсом из другого источника
- Cross-Origin Resource Sharing (CORS) — механизм, использующий дополнительные заголовки, позволяющий агенту получить разрешение на доступ к ресурсам сервера
Первая технология запрещает доступ к ресурсам сервера, если запрос был сделан со страницы, загруженной с другого домена
Особенности работы с CORS #
- При запросе дополнительных данных с того же сервера они всегда допускаются
- При запросе данных с других источников клиент обязуется передать заголовок
Origin
, указывающий с какого домена выполняется запрос - При запросе данных с другого источника клиент должен выполнить предварительный OPTIONS-запрос, для получения политик доступа
- Сервер должен ответить с заголовком
Access-Control-Allow-Origin
, указывающий политику разрешений доступа к ресурсу
Поддержка CORS в http4k #
В библиотеке http4k реализована поддержка CORS для серверных приложений
- ServerFilters.Cors — фильтр, который необходимо настроить для всего приложения
- CorsPolicy — параметры описания CORS-политики приложения
- OriginPolicy — набор подходов для обработки источника: любой из, только, шаблон или разрешить все
Защита веб-сервера #
Доступ к данным должен осуществляться только уполномоченными лицами, чтобы исключить неправомерное использование, изменение, удаление данных или предотвращение работы веб-приложения
Для обеспечения безопасности на стороне сервера необходимо выполнять работу систематически над:
- Исходным кодом веб-приложения (ошибки должны остутствовать)
- Обновлениями безопасности веб-сервера и другой инфраструктуры
- Политикой хранения и обновления паролей (как приложения, так и инфраструктуры)
- Настройки безопасности клиентского кода
Это комплексная задача, корректное решение которой требует детального понимания всех аспектов работы приложения
Типичные проблемы сверверных веб-приложений #
Кратко рассмотрим проблемы, связанные с передачей данных от пользователя
- Межсайтовый скриптинг (XSS)
- SQL-инъекции
- Подделка межсайтовых запросов (CSRF)
- Перехват нажатий мышкой от пользователя (clickjaking)
- Отказ в обслуживании (DoS)
- Раскрытие файловой системы
- Выполнение команд в рамках основной ОС
Список текущих актуальных угроз можно посмотреть на сайте OWASP
SQL-инъекция #
Уязвимости SQL-инъекций позволяют злоумышленникам выполнять произвольный код SQL в базе данных, позволяя получать, изменять или удалять данные независимо от разрешений пользователя
Эта уязвимость присутствует, если пользовательский ввод, который передаётся в базовый оператор SQL, может изменить смысл оператора
Рассмотрим следующий код по подготовке SQL-запроса:
val statement = "SELECT * FROM users WHERE name = '$userName';"
Если переменная userName
передаётся от пользователя (например в параметрах запроса), то пользователь может передать туда следующую строку:
a';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't
В результате выполнится SQL-код:
SELECT * FROM users WHERE name = 'a';DROP TABLE users; SELECT * FROM
userinfo WHERE 't' = 't';
Управление безопасностью #
- Веб-приложения, работающие в сети Интернет, находятся в небезопасном окружении, постоянно открыто для атак извне
- Атакующие постоянно находят новые подходы для обходы средств защиты
- Чем больше функций предоставляет приложение, тем больше возможностей есть у атакующего
- Ввод от пользователя может и будет содержать проблемные данные
- Злоумышленники будут пытаться взломать и защиту базовой ОС, в рамках которой запущено веб-приложение
- Разработчику веб-приложений необходимо постоянно заниматься изучением новых угроз и способов их противодействию
Управление конфиденциальными данными #
После реализации системы безопасности приложения от неправомерного использования зачастую необходимо реализовать разделение полномочий для обеспечения конфиденциальности
Разделение на читателей и администрацию #
- Большинство пользователей может только просматривать информацию
- Администрация может добавлять новые элементы на ресурс
- Если пользователи могут добавлять данные, то администрация имеет возможность модерировать данные, введённые пользователем
Сложные системы разделения полномочий #
- Пользователю может быть доступна только часть функций
- Предоставление функций может определяться динамически приложением
Идентификация, аутентификация и авторизация #
- Идентификация — процедура, в результате выполнения которой для субъекта идентификации выявляется его идентификатор, однозначно определяющий этого субъекта в информационной системе
- Аутентификация — это процедура проверки подлинности субъекта, например путём сравнения введённого им пароля с паролём, сохранённым в базе данных
- Авторизация — предоставление субъекту прав на выполнение определённых действий, разрешение на выполнение действия
Пример процедуры аутентификации #
- Пользователь заходит на сайт и нажимает на кнопку «войти в систему»
- Система показывает экран для входа в систему
- Пользователь вводит имя пользователя, идентифицирует себя
- Пользователь вводит пароль
- Пользователь нажимает на кнопку «Войти», начинает процедуру аутентификации
- Система получает введённые имя пользователя и пароль, выполняет их проверку и завершает аутентификацию
- Аутентификационный токен передаётся пользователю в ответе
- Браузер выполняет запрос к серверу, сервер использует аутентификационный токен для авторизации последующих действий пользователя
Почему так сложно? #
- Аутентификация без идентификации невозможна — нельзя определить субъекта, операцию выполнить невозможно
- Авторизация без аутентификации невозможна — нельзя понять какие действия можно разрешать данному пользователю
- Авторизация без идентификации возможна — публичная информация обычно доступна любому пользователю. Но даже в этом случае авторизация выполняется: любому пользователю доступны данные
Как оно может стать ещё сложнее:
- Вариантов решения задач очень много
- Зачастую требуется реализовать множество вариантов аутентификации в рамках одного приложения
- Простые процедуры выполнения аутентификации могут быть не безопасны, в приложениях следует реализовывать сценарии, проверенные специалистами по безопасности
Варианты аутентификации пользователей #
- Аутентификация согласно встроенным возможностям протокола HTTP
- Аутентификация с сохранением сессии
- Аутентификация с использованием сертификатов
- Аутентификация по одноразовому паролю
- Аутентификация по ключам доступа
- Аутентификация по токенам
- Стандарты аутентификации OAuth и OpenID Connect
Аутентификация по протоколу HTTP #
Задача аутентификации возникла давно и в рамках стандарта HTTP утверждено несколько способов аутентификации: IANA
- Для указания поддерживаемого способа аутентификации сервер передаёт HTTP-заголовок
WWW-Authenticate
- Данные на сервер передаются в заголовке
Authorization
- После успешной авторизации пользователя браузер сохраняет данные в заголовке
Authorization
и передаёт их при каждом запросе серверу
Базовая HTTP-аутентификация, RFC7617 #
Особенности базовой аутентификации #
- Браузер сохраняет введённые данные и добавляет заголовок ко всем последующим запросам серверу
- Для сброса введённых данных необходимо перезапустить браузер
- Данные базовой аутентификации передаются в открытом виде и может быть перехвачена. Необходимо использовать зашифрованное SSL-соединение
- Данные базовой аутентификации можно передать в рамках URL-запроса
https://username:password@example.com/
Имя пользователя и пароль передаются в формате имя:пароль
и отделяются от пути символом @
Аутентификация с сохранением сессии #
HTTP cookie — это небольшой фрагмент данных, отправляемый сервером на браузер пользователя, который может сохранить и отсылать обратно с новым запросом к серверу
Используются в веб-приложениями для:
- Управления сеансами пользователя, аутентификации, корзины
- Персонализации контента
- Мониторинга поведения пользователя
Заголовки Set-Cookie
и Cookie
#
Заголовки Set-Cookie
устанавливаются сервером в рамках своего ответа
Простой заголовок может выглядит так:
Set-Cookie: <имя cookie>=<значение cookie>
Таких заголовков в ответе сервера может быть несколько:
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry
Браузер будет передавать их клиенту в рамках заголовка Cookie
:
Cookie: yummy_cookie=choco; tasty_cookie=strawberry
От клиента на сервер может передаваться несколько куков
Время жизни куков #
- Сессионные cookie удаляются при закрытии клиента, то есть существуют только на протяжении текущего сеанса. Однако сеанс автоматически не завершается, что делает их вечными
- Постоянные cookie удаляются не с закрытием клиента, а при наступлении определённого интервала времени
Set-Cookie: id=5aoeu; Expires=Wed, 20 Nov 2010 10:15:00 GMT;
Безопасность HTTP куков #
- Данные передаются в открытом виде, для защиты нужно использовать SSL-шифрование
- Для защиты данных куки от доступа из JavaScript, необходимо использовать атрибут
HttpOnly
- Можно явно указать домены, с которых будет доступна информация с помощью атрибутов
Domain
иPath
- «Раздражающее» сообщение о куках необходимо по законодательству сообщать пользователю об их использовании веб-приложением и их назначением. Многие JavaScript-библиотеки добавляют свои куки
Аутентификация с сохранением сессии #
Нет строгого стандарта, RFC, который определял бы процедуру авторизации с помощью формы, каждый разработчик может реализовать логику самостоятельно
Ключевая задача — сформировать токен аутентификации и сохранить его в куки
Реализация аутентификации по паролю #
Для упрощения данной задачи в промышленных приложениях лучше всего делегировать задачи идентификации и аутентификации внешним приложениям с использованием протоколов OpenID Connect и OAuth 2.0
Для решения задачи аутентификации своими силами необходимо:
- Корректно сохранять данные для идентификации и аутентификации
- Сохранять средства быстрой проверки аутентификации, токены
Хранение аутентификационных данных #
В рамках приложения необходимо организовать хранилище для зарегистрированных пользователей. Данное хранилище должно включать объекты с полями:
- Имя пользователя
- Зашифрованный пароль пользователя
Пароль пользователя нельзя хранить в открытом виде, т.к. при потере данных (которая точно случится) вся защищённая информация станет доступна
Для защиты пароля рекомендуется использовать схему с добавлением соли
Базы данных обычно предоставляют возможности по выполнению хеширования
Особенности использования соли #
- Соль должна хранится отдельно от хеша пароля, иначе схема теряет смысл
- Соль должна быть достаточно длинная, т.к. небольшую соль достаточно легко подобрать по таблицам
- Соль должна обладать высоким уровнем энтропии
- Соль нельзя хранить в исходном коде приложения, которое устанавливается на многих компьютерах, т.к. она может быть потеряна
- Соль может создаваться динамически, например стандарт PBKDF2
Хранение и проверка сессионных токенов #
Для верификации сессионных токенов необходимо:
- доверять данным, пришедшим от пользователя, т.е. отказаться от проверки данных
- хранить сессионный токен на стороне сервера для сверки
- применять схемы с шифрованием данных или подписью данных в токене
Хранение сессионных токенов на стороне сервера несёт ряд сложностей:
- сколько токенов может быть выдано конкретному пользователю?
- сколько пространства потребуется для хранения всех выданных токенов?
- сколько времени уйдёт на выявление их корректности?
Последняя схема имеет ряд проблем:
- надо корректно реализовать криптографические схемы
- сложно отозвать скомпрометированные токены