Безопасность
Node Hero: Глава 11
Перевод книги Node Hero от RisingStack. Переведено с разрешения правообладателей.
В этой главе, посвящённой безопасности Node.js, вы узнаете, как защитить свои приложения от наиболее распространённых атак.
Node.js и угрозы безопасности
В настоящее время мы почти каждую неделю видим серьёзные нарушения безопасности, например, в случаях LinkedIn или MySpace. Во время этих атак было украдено огромное количество пользовательских данных, а также нанесён вред корпоративной репутации.
Исследования также показывают, что тикеты на ошибки, связанные с безопасностью, остаются открытыми в среднем в течение 18 месяцев в некоторых областях индустрии.
Мы должны исправить это. Если вы разрабатываете программное обеспечение, безопасность является частью вашей работы.
Начало руководства по безопасности Node.js
Давайте начнём и защитим наше приложение Node.js путём правильного отношения к написанию кода, использованию утилит и эксплуатации!
Правило 1: Не используйте eval
Использование eval
может сделать приложение уязвимым для атак с инъекцией кода. Старайтесь не использовать его, но если вам нужно, никогда не отправляйте непровалидированный пользовательский ввод в eval
.
Явный вызов eval
— это не единственное, чего вам следует избегать. В фоновом режиме каждое из следующих выражений использует eval:
setInterval(String, 2)
setTimeout(String, 2)
new Function(String)
Правило 2: Всегда используйте строгий режим
С помощью use strict
вы можете использовать ограниченный «вариант» JavaScript. Он устраняет бесшумность некоторых ошибок и делает их явными.
'use strict'
delete Object.prototype
// TypeError
var obj = {
a: 1,
a: 2
}
// Синтаксическая ошибка
Правило 3: Обращайтесь с ошибками аккуратно
Во время различных ошибочных сценариев ваше приложение может выдавать конфиденциальные сведения о внутренней инфраструктуре, например: X-Powered-By: Express
.
Трассировки стека сами по себе не рассматриваются как уязвимости, но они часто показывают информацию, которая может быть интересна злоумышленнику. Предоставление отладочной информации в результате операций, генерирующих ошибки, считается плохой практикой. Вы должны всегда логировать их, но никогда не показывать пользователям.
Правило 4: Используйте статический анализ вашего кода
Статический анализ кода вашего приложения может поймать много ошибок. Для этого мы предлагаем использовать ESLint с JavaScript Standard Style.
Безопасное использование ваших сервисов в продакшене
Использование правильного стиля кода недостаточно для эффективной защиты Node.js, вы также должны быть осторожны в том, как вы запускаете свои сервисы в продакшене.
Правило 5: Не запускайте свои процессы с правами суперпользователя
К сожалению, мы это встречаем довольно часто: разработчики запускают своё Node.js-приложение с правами суперпользователя, так как они хотят, чтобы приложение слушало порт 80 или 443.
Это просто неправильно. В случае ошибки ваш процесс может привести к сбою всей системы, поскольку вы дали ему права на что угодно.
Вместо этого вы можете настроить HTTP-сервер/прокси для пересылки запросов. Это может быть nginx или Apache. Ознакомьтесь с нашей статьёй об использовании Node.js в продакшене, чтобы узнать больше.
Правило 6: Настройте обязательные HTTP-заголовки
Существуют определённые HTTP-заголовки, связанные с безопасностью, которые должен установить ваш сайт. Эти заголовки:
- Strict-Transport-Security обеспечивает безопасные подключения к серверу (HTTP через SSL/TLS)
- X-Frame-Options обеспечивает защиту от кликджекинга
- X-XSS-Protection включает XSS-фильтр, встроенный в большинство современных веб-браузеров
- X-Content-Type-Options содержит инструкции по определению типа файла по content-type и не допускает MIME-сниффинг контента
- Content-Security-Policy предотвращает широкий спектр атак, включая межсайтовый скриптинг и другие межсайтовые инъекции
В Node.js их легко установить с помощью модуля Helmet:
var express = require('express')
var helmet = require('helmet')var app = express()
app.use(helmet())
Helmet также доступен для Koa: koa-helmet.
Правило 7: Правильное управление сессией
Для каждого cookie-файла должен быть указан следующий список флагов:
- secure — этот атрибут говорит браузеру отправлять cookie, только если запрос отправляется через HTTPS
- HttpOnly — этот атрибут используется для предотвращения атак, таких как межсайтовый скриптинг, поскольку он не позволяет получить доступ к файлу cookie через JavaScript
Правило 8: установка области видимости cookie-файлов
- domain — этот атрибут используется для сравнения с доменом сервера, на котором запрашивается URL; если домен соответствует или является субдоменом, тогда будет проверен атрибут
path
- path — в дополнение к домену может быть указан путь URL, по которому действителен файл cookie; если домен и путь совпадают, cookie будет отправлен в запросе
- expires — этот атрибут используется для установки постоянных файлов cookie, поскольку cookie не истекает, пока не будет превышена установленная дата
В Node.js вы можете легко создать этот файл cookie, используя пакет cookie. Опять же, это довольно низкий уровень, поэтому вы, вероятно, в конечном итоге будете использовать обёртку, например, cookie-session.
var cookieSession = require('cookie-session')
var express = require('express')var app = express()app.use(cookieSession({
name: 'session',
keys: [
process.env.COOKIE_KEY1,
process.env.COOKIE_KEY2
]
}))app.use(function (req, res, next) {
var n = req.session.views || 0
req.session.views = n++
res.end(n + ' views')
})app.listen(3000)
(Этот пример взят из документации модуля cookie-session)
Полезные инструменты
Поздравляю, вы почти закончили! Если вы следовали этому руководству и тщательно выполнили предыдущие шаги, у вас останется только одна область, касающаяся безопасности Node.js. Давайте перейдём к использованию надлежащих инструментов для поиска уязвимостей модулей!
Правило 9: Ищите уязвимости с Retire.js
«Всегда ищите уязвимости в своих модулях Node.js. Вы то, что вы реквайрите.»
Цель Retire.js — помочь вам определить использование версий модулей с известными уязвимостями.
Просто установите:
npm install -g retire
После этого запуск с помощью команды retire
будет искать уязвимости в вашем каталоге node_modules
. Также обратите внимание, что Retire.js работает не только с Node.js-модулями, но и с фронтенд-библиотеками.
Правило 10: Проводите аудит ваших модулей с помощью CLI Node Security Platform
nsp
является основным интерфейсом командной строки для Node Security Platform. Он позволяет производить аудит файлов package.json
или npm-shrinkwrap.json
с помощью API NSP для выявления уязвимых модулей.
npm install nsp --global
# Внутри директории вашего проекта
nsp check
Безопасность Node.js не является большой проблемой после того, как вы это прочитали? Надеюсь, вы нашли, что эти правила будут полезны для защиты ваших Node.js-приложений, и будете следовать им в будущем, поскольку безопасность является частью вашей работы!
Если вы хотите больше узнать о безопасности Node.js, я могу порекомендовать эти статьи:
В следующей главе Node Hero вы узнаете, как развернуть защищённое Node.js-приложение, чтобы люди могли начать его использовать!
Слушайте наш подкаст в iTunes и SoundCloud, читайте нас на Medium, контрибьютьте на GitHub, общайтесь в группе Telegram, следите в Twitter и канале Telegram, рекомендуйте в VK и Facebook.