(Основано на https://www.powerdown.io/blog/posts/stories/web-developer-security-checklist.html)
Разрабатывать безопасные, надёжные облачные веб-приложения сложно, очень сложно. Если вам кажется это лёгким делом, вы либо высшая форма материи, либо вас ждёт болезненное осознание в будущем.
Если вы выпили быстрорастворимый MVP и считаете, что можете создать ценный и безопасный продукт за один месяц, подумайте дважды, прежде чем запускать этот «прото-продукт».
После того, как вы посмотрите этот чеклист, примите во внимание, что вы игнорируете многие критические вопросы безопасности. По крайней мере, будьте честными с потенциальными пользователями и сообщите им, что у вас ещё нет полноценного продукта, и что прототип не безопасен на 100%.
Список простой, и его нельзя считать завершённым. Я разрабатываю безопасные веб-приложения уже более 14 лет, и включил в список некоторые из наиболее важных задач, которые я мучительно опробовал на себе за этот период. Надеюсь, при создании веб-приложения вы серьёзно задумаетесь над этими вопросами.
[ ] Используйте шифрование конфиденциальных данных и данных, идентифицирующих пользователей, например токенов доступа, адресов электронной почты или деталей счетов.
[ ] Если ваша база данных поддерживает экономичное шифрование в неактивном режиме (вроде AWS Aurora), включите его для защиты данных на диске. Убедитесь, что все резервные копии хранятся в зашифрованном виде.
[ ] Используйте минимальные привилегии для использования аккаунта пользователя базой данных. Не используйте корневую учётную запись базы данных.
[ ] Храните и группируйте секретные данные, используя хранилище ключей, например Vault или AWS Secret Manager. Не используйте жёстко закодированные секретные данные в своих приложениях и НИКОГДА не загружайте такие данные в репозиторий!
[ ] Полностью избавьтесь от SQL-атак, используя только подготовленные SQL-инструкции. Например, если вы работаете с NPM, пользуйтесь не npm-mysql, а npm-mysql2, который поддерживает подготовленные инструкции.
[ ] Проверьте, что все компоненты вашего софта протестированы на наличие уязвимостей для каждой версии, отправленной в продакшен. Сюда входят продукты с открытым исходным кодом, библиотеки и пакеты. Желательно автоматизировать это через CI-CD процесс.
[ ] Относитесь к безопасности систем разработки приложений так же бдительно, как к безопасности систем в продакшене. Создавайте софт из защищённых, изолированных систем.
[ ] Убедитесь, что в продакшене не попадают служебные/отладочные файлы и скрипты.
[ ] Убедитесь, что все пароли хешируются с использованием соответствующего алгоритма, вроде bcrypt. Никогда не реализуйте собственное шифрование и корректно инициализируйте шифрование из случайных данных.
[ ] Реализуйте простые, но адекватные правила создания паролей, которые побуждают пользователей придумывать длинные случайные пароли.
[ ] Используйте многофакторную аутентификацию для всех своих провайдеров.
[ ] Проверяйте, что DOS-атаки на API не вредят вашему сайту. Как минимум используйте ограничители скорости на более медленных методах API в таких типичных функциях, как вход и генерация токена.
[ ] Создайте лимиты для размеров и структуры запросов для данных, предоставляемых пользователями.
[ ] Снизьте риск хакерской атаки, минимизировав последствия DDoS-атаки (Distributed Denial of Service), используйте для этого глобальный кеширующий прокси-сервер вроде CloudFlare. Его можно включить при активной DDoS-атаке, а в остальных случаях использовать лишь для DNS.
[ ] Используйте TLS для всего сайта, а не только для формы входа и ответов сервера. Никогда не используйте TLS только для формы входа.
[ ] Файлы cookie должны быть с флагом httpOnly, защищены и находиться в области видимости пути и домена.
[ ] Используйте CSP, не допуская небезопасные бэкдоры. Настраивается это через боль, но оно того стоит.
[ ] Используйте заголовки X-Frame-Option и X-XSS-Protection в ответах клиентам.
[ ] Используйте HSTS-ответы, чтобы форсировать доступ только через TLS. Для подстраховки перенаправляйте на сервере все HTTP-запросы на HTTPS.
[ ] Используйте CSRF-токены во всех формах и используйте новый заголовок ответа SameSite Cookie, который раз и навсегда исправляет CSRF для всех новых браузеров.
[ ] Проверьте, что в открытых API нет ресурсов с последовательными численными идентификаторами.
[ ] Проверьте, что пользователи полноценно аутентифицированы и авторизованы, когда используют ваши API.
[ ] Используйте канареечные проверки в API, чтобы обнаруживать незаконные или аномальные запросы, которые указывают на атаку.
[ ] Валидируйте информацию на клиенте, чтобы пользователь получал быструю обратную связь, но всегда делайте повторную валидацию на бэкенде.
[ ] Валидируйте любую (без исключения) информацию на сервере, вводимую пользователем, используя белые списки. Никогда напрямую не вставляйте данные, полученные от пользователя в ответы. Никогда не используйте вводимую пользователем информацию в SQL-инструкциях.
[ ] Проверьте, что у всех служб открыто минимальное количество портов. Хоть безопасность через неясность — это не защита, использование нестандартных портов усложнит задачу взломщикам.
[ ] Храните бэкенд-базу данных и сервисы в приватных VPC (виртуальном частном облаке), которые не видны ни в какой открытой сети. Будьте очень осторожными, когда настраиваете группы безопасности AWS (Амазон) и пирингуете VPC, что может случайно превратить сервисы в открытые.
[ ] Изолируйте логические службы в отдельные VPC и одноранговые VPC для межсервисной связи.
[ ] Проверьте, что все службы принимают данные с минимального набора IP-адресов.
[ ] Ограничьте исходящий IP-трафик и трафик портов для минимизации APT (Advanced Persistent Threat) и бот-атак.
[ ] Всегда используйте AWS IAM (Identity and Access Management) пользователей и роли, а не учётные данные корневого каталога. Изучите, как эффективней пользоваться IAM.
[ ] Используйте минимальную привилегию доступа для всех сотрудников и разработчиков. Давайте IAM пользователям и ролям минимальные возможности, необходимые для выполнения задачи.
[ ] Регулярно чередуйте пароли и ключи доступа�, используйте расписание.
[ ] Удостоверьтесь, что можете делать обновления без простоя. Убедитесь, что можете быстро обновлять приложения целиком автоматически.
[ ] Стройте всю инфраструктуру с помощью инструмента, подобного Terraform, а не через облачную консоль. Инфраструктура должна определяться как «код» и воссоздаваться одним нажатием кнопки. Возьмите за правило никогда не создавать ничего в облаке вручную — Terraform может проверить вашу конфигурацию.
[ ] Используйте централизованную систему логирования для всех сервисов. Вам никогда не должен понадобиться SSH для доступа к логам.
[ ] Не подключайтесь по SSH к сервисам, кроме случаев, когда необходима единоразовая диагностика. Регулярное использование SSH чаще всего означает, что вы не автоматизировали важную задачу.
[ ] Не оставляйте порт 22 постоянно открытым в любых группах служб AWS.
[ ] Создавайте неизменяемые хосты, вместо серверов с длительным сроком службы, которые нужно модифицировать и обновлять. (см. Immutable Infrastructure Can Be More Secure).
[ ] Используйте систему обнаружения вторжений (Intrusion Detection System) для минимизации APT.
[ ] Выключайте неиспользуемые сервисы и серверы. Самый безопасный сервер — отключенный сервер. С помощью инструментов вроде PowerDown такому процессу можно задать расписание.
[ ] Регулярно проверяйте свой дизайн и реализацию.
[ ] Проведите испытание на взлом (penetration testing) — хакните себя, и попросите кого-нибудь хакнуть вас.
[ ] У вас должна быть модель угрозы, описывающая от чего вы защищаетесь. В ней список и приоритеты возможных угроз и злоумышленников.
[ ] Держите опробованный на деле план на случай нарушения безопасности. Однажды он вам понадобится.