Безопасность в веб-разработке: чек-лист
Светлана Шаповалова, редактор «Нетологии», адаптировала статью Michael O’Brien, в которой он составил чек-лист для веб-разработчиков, предпочитающих разрабатывать не только удобные, но и безопасные приложения.
Разработка безопасных и надежных облачных веб-приложений — очень, очень сложное дело. Если вы думаете иначе, вы либо не от мира сего, либо жизнь вас еще не проучила.
Если вы уже заразились идеей «минимально жизнеспособного продукта» (англ. MVP — minimum viable product, прим. перев.) и считаете, что за месяц можно создать одновременно полезный и безопасный продукт — подумайте дважды, прежде чем выпускать его. Просмотрев чек-лист, вы поймете, что оставляете немало уязвимостей.
Самое меньшее, что можно делать в такой ситуации — это честно предупреждать пользователей, что продукт еще на стадии рабочего прототипа и полная безопасность пока не гарантируется.
Чек-лист весьма прост и пока еще не до конца полон. Я занимаюсь разработкой безопасных веб-приложений уже более 14 лет и включил в список самые важные вопросы, с которыми столкнулся за это время. Надеюсь, что создавая свой продукт, вы отнесетесь к ним серьезно.
Базы данных
- Храните данные идентификации пользователей и конфиденциальные данные (токены, адреса электронной почты, платежные реквизиты) в зашифрованном виде.
- Если база данных поддерживает шифрование хранящихся данных (например, AWS Aurora), подключите его для защиты данных на диске. Убедитесь, что все резервные копии также хранятся в зашифрованном виде.
- Используйте наименьший уровень привилегий для доступа к учетным записям пользователей в базе данных. Не используйте корневую учетную запись базы данных.
- Храните и распространяйте секретные данные с помощью keystore, предназначенного для этих целей. Не используйте хардкод в приложениях.
- Предотвращайте SQL-инъекции, используя исключительно подготовленные SQL-запросы. Например: если вы используете NPM, не используйте npm-mysql, используйте npm-mysql2, который поддерживает подготовленные выражения.
Разработка
- Убедитесь, что все компоненты приложения проверены на наличие уязвимостей для каждой версии, переданной в продакшн. Сюда входят O/S, библиотеки и пакеты. Проверка должна быть автоматизирована в процессе CI-CD (CI — continuous integration — непрерывная интеграция, CD — continuous delivery — постоянная поставка, прим. перев.).
- С одинаковой бдительностью относитесь как к безопасности среды разработки, так и к безопасности продакшен-сервера. Создавайте программное обеспечение в защищенной изолированной среде разработки.
Идентификация
- Убедитесь, что все пароли хэшируются с использованием соответствующей криптографической функции, например, bcrypt. Никогда не пишите собственную функцию хеширования и корректно инициализируйте используемую криптографическую библиотеку случайными данными.
- Реализуйте простые, но адекватные правила паролей, которые побуждают пользователей вводить длинные уникальные пароли.
- Во всех сервисах используйте многофакторную аутентификацию для входа в систему.
Защита от DDoS-атак
- Убедитесь, что DDoS-атаки на ваши API не навредят сайту. Как минимум, защитите «узкие» места API, такие как процедуры генерации логина и токена.
- Обеспечьте разумные ограничения по размеру и структуре предоставляемых пользователем данных и запросов.
- Смягчайте DDoS-атаки с помощью глобального сервиса с кэширующим прокси, например, CloudFlare. Он включается, когда вы находитесь под DDOS-атакой, а в обычном режиме функционирует как DNS lookup.
Веб-трафик
- Используйте TLS для всего сайта, а не только для форм входа и ответов. Никогда не используйте TLS только для формы входа.
- Куки должны быть «безопасными» (secure) и httpOnly, а область видимости должна определятся атрибутами path и domain.
- Используйте CSP (Content Security Policy), не допуская небезопасных бэкдоров. Муки с настройками стоят того.
- Используйте заголовки X-Frame-Option, X-XSS-Protection в клиентских ответах.
- Используйте механизм HSTS для принудительного доступа через TLS-протокол. Перенаправьте все HTTP-запросы на HTTPS на сервере для обратной совместимости.
- Используйте токены CSRF во всех формах и новый заголовок ответа Cookie SameSite, который фиксирует CSRF единоразово для всех браузеров.
APIs
- Убедитесь, что в API нет общедоступных ресурсов.
- Убедитесь, что при использовании ваших API пользователи полностью идентифицированы и авторизованы.
Валидация
- Проводите проверку входных данных на стороне клиента для быстрой обратной связи с пользователем, но никогда не доверяйте ей.
- Подтверждайте каждый бит пользовательского ввода, используя белые списки на сервере. Никогда не вводите напрямую пользовательский контент в ответ. Никогда не используйте пользовательский ввод в SQL-запросах.
Облачная конфигурация
- Убедитесь, что все сервисы имеют минимальное количество открытых портов. В то время как принцип «безопасность через неясность» (security through obscurity) не обеспечивает полной защиты, использование нестандартных портов немного усложнит жизнь злоумышленникам.
- Размещайте базу бекэнда на частных VPC, которые не видны в публичной сети. Будьте очень осторожны при настройке групп безопасности AWS и пиринговых VPC — можно непреднамеренно сделать службы публичными.
- Изолируйте логические службы в отдельных VPC и одноранговых VPC для обеспечения межсервисной связи.
- Убедитесь, что все службы принимают данные только с минимального набора IP-адресов.
- Ограничьте исходящий трафик IP и портов, чтобы минимизировать APT и «ботификацию».
- Всегда используйте роли AWS IAM, а не учетные данные root.
- Используйте минимальные права доступа для всех сотрудников и разработчиков.
- Регулярно меняйте пароли и ключи доступа в соответствии с расписанием.
Инфраструктура
- Убедитесь, что апгрейды делаются без простоя, а ПО обновляется автоматически.
- Создавайте инфраструктуру с помощью инструментов вроде Terraform, а не через облачную консоль. Инфраструктура должна определяться как «код» и воссоздаваться одним нажатием кнопки.
- Используйте централизованное логирование для всех служб. Не используйте SSH для доступа или получения логов.
- Не используйте SSH в службах, кроме разве что разовой диагностики. Регулярное использование SSH, как правило, означает, что вы не автоматизировали все как надо.
- Не оставляйте порт 22 постоянно открытым на любых сервисных группах AWS.
- Создайте неизменяемые хосты вместо долгоживущих серверов, которые вы патчите и обновляете.
- Используйте систему обнаружения вторжений для минимизации APT.
Эксплуатация
- Выключите неиспользуемые службы и серверы. Самый безопасный сервер — это выключенный сервер.
Тестирование
- Проводите аудит и проекта, и готовой реализации.
- Проведите тестирование на проникновение — взломайте себя, а также попросите кого-то еще взломать вас.
Главное — планируйте
- Используйте моделирование угроз, чтобы видеть, от чего надо защищаться. В модели должны перечисляться и определяться приоритеты возможных угроз и все возможные действующие лица.
- Создайте план на случай инцидентов. Однажды он вам понадобится.
От редакции
Для тех, кто интересуется веб-разработкой и любит получать знания в систематизированном виде, «Нетология» открыла набор на программу «Профессия веб-разработчик».
Что изучается на курсе:
- Кросс-браузерная верстка HTML и CSS.
- Верстка веб-страниц на основе макета.
- Бекэнд-разработка на PHP.
- MySQL.
- Проектирование структуры базы данных.
- JavaScript.
- AJAX.
- Создание интерактивных веб-страниц.
Длительность обучение — 6 месяцев. Преподают специалисты из Яндекса, Медиа-Шторма, Cond Nast.
Старт занятий 23 июня. Все подробности здесь
Также идет набор на «Профессию frontend-разработчик» — курс, ориентированный на получение навыков frontend-разработки с нуля.
Полный текст статьи читайте на Нетология