Этот перевод обеспечивается StrongLoop / IBM.
Этот документ может быть устаревшим по отношению к документации на английском языке. Последние обновления содержатся в документации на английском языке.Термин “рабочий режим” означает тот этап жизненного цикла программного обеспечения, на котором приложение или API является в целом доступным для конечных пользователей или потребителей. Напротив, на этапе “разработки” происходит активное создание и тестирование кода, и приложение не является открытым для внешнего доступа. Соответствующие системные среды называются, соответственно, рабочей средой и средой разработки.
Настройки среды разработки и рабочей среды при установке, как правило, являются различными, и к этим средам предъявляются абсолютно разные требования. То, что идеально для разработки, не всегда приемлемо в рабочем режиме. Например, в среде разработки можно задать подробное протоколирование ошибок для отладки, тогда как в рабочей среде такая особенность настройки может привести к уязвимости защиты. Во время разработки можно не беспокоиться о масштабируемости, надежности и производительности, тогда как в рабочем режиме все эти вопросы играют решающую роль.
В настоящей статье речь пойдет о лучших практических методах в области защиты приложений Express, развернутых в рабочей среде.
Версии Express 2.x и 3.x больше не поддерживаются. Проблемы, связанные с защитой и производительностью в этих версиях, не будут подлежать решению. Не используйте эти версии! Если вы еще не перешли к работе с версией 4, выполните инструкции, приведенные в руководстве по миграции.
Кроме того, убедитесь в том, что уязвимые версии Express, перечисленные на странице Обновления системы защиты, вами не используются. В противном случае, выполните обновление до одного из стабильных выпусков, предпочтительно, до последнего.
Если ваше приложение предназначено для работы с чувствительными данными или для их передачи, для защиты соединения и данных необходимо использовать криптографический протокол Transport Layer Security (TLS). Данная технология позволяет шифровать данные до передачи с клиента на сервер, тем самым обеспечивая защиту от многих распространенных (и простых) способов несанкционированного доступа. Хотя запросы Ajax и POST могут казаться неочевидными и “скрытыми” в браузерах, инициируемая ими передача данных в сети является уязвимой для незаконного сбора и анализа пакетов иатак посредника (атак “человек посередине”).
Возможно, вам знаком криптографический протокол Secure Socket Layer (SSL). SSL является предшественником TLS. Другими словами, если раньше вы пользовались SSL, пора переходить к TLS. В целом, для работы с TLS мы рекомендуем использовать сервер Nginx. Подробные инструкции по настройке TLS на Nginx (и на других серверах) можно найти в разделе Рекомендуемые конфигурации серверов (Mozilla Wiki).
Кроме того, удобным инструментом для получения бесплатного сертификата TLS является Let’s Encrypt - бесплатная, автоматическая и открытая сертификатная компания (CA), предоставленная корпорацией Internet Security Research Group (ISRG).
Helmet помогает защитить приложение от некоторых широко известных веб-уязвимостей путем соответствующей настройки заголовков HTTP.
Helmet, по сути, представляет собой набор из девяти более мелких функций промежуточной обработки, обеспечивающих настройку заголовков HTTP, связанную с защитой:
Content-Security-Policy
для предотвращения атак межсайтового скриптинга и прочих межсайтовых вмешательств.X-Powered-By
.Strict-Transport-Security
, принудительно активирующий защиту соединений с сервером (по протоколу HTTP с использованием SSL/TLS).X-Download-Options
для IE8+.Cache-Control
и заголовки Pragma для отключения кеширования на стороне клиента.X-Content-Type-Options
для защиты браузеров от прослушивания (сниффинга) MIME ответов с отличным от объявленного типом содержимого (content-type).X-Frame-Options
для защиты от кликджекинга.X-XSS-Protection
для активации фильтра XSS (фильтра межсайтового скриптинга) в большинстве современных веб-браузеров.Установите Helmet, как обычный модуль:
$ npm install --save helmet
Затем используйте его в своем коде:
...
var helmet = require('helmet');
app.use(helmet());
...
Если использовать Helmet не нужно, как минимум, отключите заголовок X-Powered-By
. Злоумышленники могут использовать этот заголовок (включенный по умолчанию) для выявления приложений на базе Express и активации целенаправленных атак.
Поэтому рекомендуется отключить данный заголовок с помощью метода app.disable()
.
app.disable('x-powered-by');
Если вы используете helmet.js
, это будет сделано автоматически.
Для того чтобы файлы cookie не подвергали опасности ваши приложения, не используйте стандартные имена сеансовых cookie и соответствующим образом настройте опции защиты файлов cookie.
Существует два основных сеансовых модуля cookie для промежуточной обработки:
express.session
, встроенный в Express 3.x.express.cookieSession
, встроенный в Express 3.x.Основное различие между этими двумя модулями состоит в способе сохранения сеансовых данных cookie. Промежуточный обработчик express-session сохраняет данные о сеансе на сервере; в самом файле cookie сохраняется только ИД сеанса, но не данные сеанса. По умолчанию, используется хранилище в оперативной памяти, но данный способ не предназначен для рабочей среды. В рабочей среде необходимо настроить масштабируемое хранилище сеансов; см. список совместимых хранилищ сеансов.
Промежуточный обработчик cookie-session, в отличие от описанного выше, реализует хранение на основе файлов cookie: выполняется полная сериализация сеанса в файл cookie, вместо того, чтобы сохранять только ключ сеанса. Этот способ следует использовать только при условии, что данные сеанса имеют относительно небольшой объем и легко могут быть преобразованы в элементарные значения (а не объекты). Хотя браузеры должны поддерживать не менее 4096 байт на каждый файл cookie, позаботьтесь о том, чтобы не допустить превышения данного ограничения. Размер не должен превышать 4093 байт на каждый домен. Кроме того, помните о том, что данные cookie являются видимыми для клиента, поэтому, если по какой-либо причине их следует защитить или скрыть, остановите свой выбор на модуле express-session как на более подходящем.
Использование имен сеансовых cookie, предлагаемых по умолчанию, может сделать ваше приложение уязвимым для разного рода атак. В данном случае возникает та же проблема с безопасностью, что и при использовании заголовка X-Powered-By
: потенциальный злоумышленник может воспользоваться им для идентификации на сервере и организации целенаправленных атак.
Для того чтобы избежать такой проблемы, используйте обобщенные имена cookie; например, при использовании промежуточного обработчика express-session:
var session = require('express-session');
app.set('trust proxy', 1) // trust first proxy
app.use( session({
secret : 's3Cur3',
name : 'sessionId',
})
);
Для обеспечения защиты необходимо настроить следующие опции защиты файлов cookie:
secure
- обеспечивает отправку файлов cookie браузером только с использованием протокола HTTPS.httpOnly
- обеспечивает отправку cookie только с использованием протокола HTTP(S), а не клиентского JavaScript, что способствует защите от атак межсайтового скриптинга.domain
- указывает домен cookie; используется для сравнения с доменом сервера, на котором запрашивается данный URL. В случае совпадения выполняется проверка следующего атрибута - пути.path
- указывает путь cookie; используется для сравнения с путем запроса. Если путь и домен совпадают, выполняется отправка cookie в запросе.expires
- используется для настройки даты окончания срока хранения для постоянных cookie.Ниже приведен пример с использованием промежуточного обработчика cookie-session:
var session = require('cookie-session');
var express = require('express');
var app = express();
var expiryDate = new Date( Date.now() + 60 * 60 * 1000 ); // 1 hour
app.use(session({
name: 'session',
keys: ['key1', 'key2'],
cookie: { secure: true,
httpOnly: true,
domain: 'example.com',
path: 'foo/bar',
expires: expiryDate
}
})
);
Для управления зависимостями приложения удобно использовать многофункциональный инструмент npm. Но пакеты, с которыми вы работаете, могут обладать критическими уязвимостями защиты, которые также могут повлиять на ваше приложение. Надежность защиты вашего приложения определяется именно надежностью “самого слабого звена” среди зависимостей.
Для того чтобы обеспечить защиту используемых вами сторонних пакетов, используйте один или оба инструмента: nsp и requireSafe. Эти два инструмента выполняют, в основном, одни и те же функции.
nsp - это инструмент командной строки, выполняющий проверку согласно базе данных уязвимостей Node Security Project и определяющий, используются ли вашим приложением пакеты с известными уязвимостями. Установите данный инструмент следующим образом:
$ npm i nsp -g
Воспользуйтесь этой командой, чтобы передать файл npm-shrinkwrap.json
на проверку в nodesecurity.io:
$ nsp audit-shrinkwrap
Воспользуйтесь этой командой, чтобы передать файл package.json
на проверку в nodesecurity.io:
$ nsp audit-package
Ниже показано, как используется requireSafe для проверки модулей Node:
$ npm install -g requiresafe
$ cd your-app
$ requiresafe check
Ниже приводится несколько дополнительных рекомендаций, взятых из исчерпывающего Контрольного списка требований к защите Node.js. В этой публикации можно найти дополнительную информацию по всем приведенным ниже рекомендациям:
Следите за рекомендациями Node Security Project, касающимися Express или других модулей, используемых вашим приложением. В целом, Node Security Project - это непревзойденный ресурс, предоставляющий ценные знания и инструменты, связанные с безопасностью Node.
И наконец, приложения Express - как и любые другие приложения - могут быть уязвимы к разнообразным веб-атакам. Ознакомьтесь с описаниями известных веб-уязвимостей и примите соответствующие меры предосторожности, чтобы их избежать.