Безопасность в веб-разработке
Разработка надежных, и при этом полностью безопасных облачных веб-приложений — довольно сложная работа. И тот, кто уже горит идеей «минимально жизнеспособного продукта», полагая, что можно сделать за месяц и полезный, и безопасный продукт, должен хорошо подумать, прежде чем выпускать этот продукт на рынок – ведь можно оставить много уязвимостей.
Самое меньшее, что стоит сделать в данной ситуации — честно предупредить пользователей, что ваш продукт на данный момент еще находится в категории рабочего прототипа и что вы пока не можете гарантировать полной безопасности.
Ниже вы найдете чек-лист рекомендаций, которым нужно следовать при создании безопасных облачных приложений.
— данные идентификации пользователей и их конфиденциальные данные (такие как токены, платежные реквизиты, e-mail) должны храниться зашифрованными;
— если база данных обладает поддержкой шифрования хранимых в ней данных (к примеру, 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-запросах.
Облачная конфигурация:
— необходимо удостовериться, что абсолютно все сервисы обладают минимумом открытых портов. Принцип «безопасность через неясность» не может обеспечить полной защиты, применение нестандартных портов позволит несколько усложнить злоумышленникам жизнь.
— размещать базу бекэнда нужно на частных VPC, которые не будут заметны в публичной сети. нужно быть очень внимательными во время настройки групп безопасности AWS и настройки пиринговых VPC — потому что можно случайно сделать такие службы публичными;
— необходимо изолировать логические службы в отдельных VPC и в одноранговых VPC для того, чтобы обеспечить связь между сервисами;
— убедиться, службы принимают информацию исключительно с минимального набора IP-адресов;
— также необходимо ограничить исходящий трафик IP и портов, это позволит минимизировать APT и «ботификацию»;
— всегда нужно задействовать роли AWS IAM, вместо учетных данных root.
— применять нужно минимальные права доступа абсолютно для всех разработчиков и сотрудников;
— регулярно стоит менять пароли и ключи доступа, ориентируясь на расписание.
Инфраструктура:
— нужно удостовериться, что апгрейды делают без простоя, тогда как ПО обновляется в автоматическом режиме;
— создавать инфраструктуру необходимо при помощи таких инструментов, как Terraform, а не используя облачную консоль, инфраструктура должна определяться в виде «кода» и воссоздаваться только лишь нажатием кнопки;
— необходимо применять централизованное логирование для абсолютно всех служб. Не нужно применять SSH для обеспечения доступа или для получения логов;
— не нужно использовать SSH в службах, за исключением разовой диагностики. Регулярное применение SSH значит обычно то, что все как надо не автоматизировано;
— не стоит оставлять порт 22 постоянно открытым в любых сервисных группах AWS;
— нужно создавать неизменяемые хосты, заменяющие собой долгоживущие серверы, которые патчатся и обновляются;
— необходимо использовать систему обнаружения вторжений для того, чтобы минимизировать APT.
Использование:
— нужно выключить не применяемые серверы и службы;
Тестирование:
— необходимо провести аудит как проекта, так и готовой реализации;
— также нужно провести тест на проникновение — взломать себя или попросить кого-то взломать вас;
Самое главное – планирование:
— нужно моделировать угрозы, чтобы представлять, от чего нужна защита. В модели нужно перечислять и определять приоритеты потенциальных угроз и возможные действующие лица;
— также нужен план на случай инцидентов.