Node.js широко используется в веб- и мобильных клиент-серверных приложениях. К сожалению, востребованность Node.js заставила злоумышленников искать новые лазейки к неправильным конфигурациям и уязвимостям.
На нас, разработчиках, лежит большая ответственность за безопасность приложений, их надежную защищенность от хакерских атак. Поэтому стоит узнать о проверенных практиках повышения безопасности приложений Node.js.
1. Проверка вводимых пользователем данных
Инъекционные атаки на протяжении многих лет то и дело попадали в OWASP (Проект по обеспечению безопасности открытых веб-приложений) и ТОП-25 SANS CWE (Общий каталог уязвимостей).
Инъекционные атаки могут принимать различные формы, например:
- XSS (межсайтовый скриптинг);
- SQL-инъекции;
- инъекции в заголовки хостов;
- инъекции команд ОС.
Чтобы предотвратить вредоносные атаки, необходимо проверять все вводимые данные до того, как приложение обработает их.
Например, поле номера телефона должно принимать только приемлемый формат с определенными цифровыми и специальными символами.
2. Обратный прокси-сервер для повышения уровня безопасности
Разрешение доступа к веб-приложению через обратный прокси-сервер обеспечивает дополнительный уровень фильтрации запросов до того, как они достигнут веб-приложения. Однако можно настроить этот уровень так, чтобы разрешить прием определенного количества запросов. Благодаря этому сервер не будет переполнен ими.
В качестве обратного прокси-сервера можно использовать, например, веб-сервер NGINX с открытым исходным кодом. Следующий пример показывает, как установить ограничение скорости на конфигурации прокси-сервера NGINX:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
server {
location /login/ {
limit_req zone=mylimit;
proxy_pass http://my_upstream;
}
}
С помощью обратного прокси-сервера можно реализовать тайм-аут соединения. Тогда ни одно соединение не будет поддерживаться веб-сервером дольше, чем требуется.
3. Управление секретными данными приложения
Управление конфиденциальными секретными данными, такими как строки подключения к базе данных, ключи API и учетные данные, является обязательным в любом приложении. Поэтому нужно любой ценой обеспечить сохранность этих секретных данных в кодовой базе, используя стандартные методы их хранения.
Например, переменные окружения в операционной системе могут хранить эту конфиденциальную информацию, и вы можете использовать Node.js для вызова этих переменных окружения.
Однако бывают случаи, когда приложению потребуется более одной инстанцированной переменной. На данный момент лучшим способом управления секретной информацией является использование пакета dotenv.
Библиотека dotenv имеет более 22 миллионов еженедельных загрузок NPM и легко устанавливается с помощью npm или Yarn следующим образом:
# NPM
npm install dotenv
# Yarn
yarn add dotenv
Затем создайте файл .env
в корне проекта и определите в нем все секретные данные:
host=awdoij3225kjbasd
USERNAME=topsecret
PASSWORD=definitelynotasecret
Можете запросить и использовать эти секретные данные в приложении, как показано ниже:
require('dotenv').config(); db.connect({ host: process.env.DB_HOST, username: process.env.DB_USER, password: process.env.DB_PASS })
Не забывайте включать файлы .env
в файл .gitignore
, чтобы предотвратить их появление в репозитории Git.
4. HTTP-заголовки ответа
HTTP-заголовок состоит из нечувствительного к регистру имени, за которым следует двоеточие (:), а затем его значение.
strict-transport-security:max-age=63072000
x-frame-options:DENY
Веб-серверы используют HTTP-заголовки ответа для передачи дополнительной информации об ответе. Но эти заголовки не связаны с содержанием сообщения. Они только предписывают браузерам выполнять определенные операции или обрабатывать ответ в определенных режимах.
Посмотрим, как можно использовать эти HTTP-заголовки для повышения безопасности приложений.
HTTP Strict Transport Security
С заголовком HTTP Strict Transport Security можно быть уверенным в том, что браузер гарантирует строгую безопасность соединения HTTPS для взаимодействия с приложением. Этот HTTP-заголовок ответа помогает защититься от таких атак, как перехват файлов куки и понижение версии протокола.
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options
Заголовок X-Frame-Options предотвращает кликджекинг, заставляя браузер отображать содержимое во фреймах. С этим специфическим HTTP-заголовком ответа доступны следующие опции:
X-Frame-Options: deny
X-Frame-Options: sameorigin
X-Frame-Options: allow-from: CUSTOM_DOMAIN
X-Content-Type-Options
Заголовок X-Content-Type-Options предотвращает изменение браузерами MIME-типов, объявленных в заголовках Content-Type. Этот заголовок позволяет избежать отслеживания MIME-типов, отвечая за продуманную их конфигурацию.
X-Content-Type-Options: nosniff
5. Протоколирование и мониторинг на стороне сервера
Хорошая библиотека протоколирования даст разработчику больше возможностей для устранения неполадок и мониторинга. С другой стороны, запись ненужной или слишком объемной информации может повлиять на производительность приложения и потребовать больше ресурсов. Поэтому при развертывании приложения в производственной среде следует использовать разумный уровень протоколирования.
При структурировании протокольных записей важно форматировать их так, чтобы людям и машинам было легко читать и понимать информацию. Наличие в протоколе нечетких сведений приведет к недопониманию между разработчиками.
Следующий пример показывает, как правильно оформить описательное сообщение протокола:
Неправильное описание: Service Failed, Not Working (Служба отказала, не работает)
Правильное описание: Application worker service failed due to insufficient disk space, ensure that adequate disk space is available and restart the Application worker service.
(Рабочая служба приложения не работает из-за недостаточного дискового пространства, убедитесь в наличии достаточного дискового пространства и перезапустите рабочую службу приложения.)
Кроме того, важно убедиться в том, что механизм протоколирования фиксирует всю необходимую информацию, включая IP-адрес, имя пользователя, выполненные действия и т. д.
Сбор или хранение конфиденциальной информации в протоколах приложений не рекомендуется. Это является нарушением основных требований соответствия приложений, таких как PCI, GDPR и т. д. Тем не менее, бывают случаи, когда необходимо регистрировать такую информацию. Тогда рекомендуется маскировать конфиденциальную информацию до того, как она будет собрана и занесена в протокол.
6. Инструменты контроля качества кода, фиксирующих уязвимости в коде
Инструменты контроля качества кода помогают разработчикам выявлять различные проблемы в коде до компиляции. Они позволяют обнаружить наиболее распространенные проблемы и заставляют разработчиков следовать лучшим практикам.
Инструменты контроля качества кода поставляются с собственными правилами, которые разработчики могут настраивать в зависимости от конкретных требований. Поэтому перед использованием такого инструмента необходимо настроить в его конфигурации правила, связанные с обнаружением уязвимостей безопасности.
Заключение
Теперь вы знаете 6 надежных практик, позволяющих повысить безопасность приложений Node.js. Эти меры безопасности помогут защитить ваши приложения от основных рисков, таких как DOS-атаки, SQL-инъекции, кликджекинг, перехват куки и прочих кибератак.
Читайте также:
- Отладка Node.js с помощью Google Chrome
- Делаем Node.js быстрым: инструменты, техники и советы для создания эффективных серверов на Node.js Часть вторая
- Веб-скрапинг с помощью Node.js — Часть 2
Читайте нас в Telegram, VK и Яндекс.Дзен
Перевод статьи Lahiru Hewawasam, 6 Best Practices to Improve Node.js Security