- Оригинальный адрес:
- Оригинальный автор:Dominik Kundel
- Перевод с:Программа перевода самородков
- Постоянная ссылка на эту статью:GitHub.com/rare earth/gold-no…
- Переводчик:lsvih
- Корректор:swants
Expressна основеNode.js, Это хорошая среда для создания веб-сервисов. Он очень прост в использовании, а благодаря концепции промежуточного программного обеспечения его легко настраивать и расширять. Хотя тамРазличные фреймворки для создания веб-приложений, но мой первый выбор всегда Express. Однако прямое использование Express не полностью соответствует рекомендациям по безопасности. Итак, нам нужно использовать что-то вродеhelmet
модули для повышения безопасности приложений.
развертывать
Прежде чем начать, убедитесь, что у вас установлены Node.js и npm (или yarn). Ты сможешьЗагрузите и просмотрите руководство по установке на официальном сайте Node.js..
В качестве примера мы будем использовать новый проект, но вы также можете применить эти функции к существующему проекту.
Запустите следующую команду в командной строке, чтобы создать новый проект:
mkdir secure-express-demo
cd secure-express-demo
npm init -y
Выполните следующую команду, чтобы установить модуль Express:
npm install express --save
существуетsecure-express-demo
Создайте каталог с именемindex.js
файл, добавьте следующий код:
const express = require('express');
const PORT = process.env.PORT || 3000;
const app = express();
app.get('/', (req, res) => {
res.send(`<h1>Hello World</h1>`);
});
app.listen(PORT, () => {
console.log(`Listening on http://localhost:${PORT}`);
});
Сохраните файл и попробуйте его, чтобы убедиться, что он работает. Выполните следующую команду, чтобы запустить службу:
node index.js
доступhttp://localhost:3000, вы должны увидетьHello World
.
Проверить заголовки
Теперь давайте улучшим безопасность приложения, добавив и удалив некоторые заголовки HTTP. Вы можете проверить его заголовки с помощью некоторых инструментов, например, с помощьюcurl
Выполните следующие команды:
curl http://localhost:3000 --include
--include
Отметьте, чтобы он выводил заголовки HTTP ответа. если он у вас не установленcurl
, Вы можете использовать вашу сетевую панель вместо наиболее часто используемых инструментов разработчика браузера.
Вы можете увидеть следующие заголовки HTTP, включенные в полученный ответ:
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 20
ETag: W/"14-SsoazAISF4H46953FT6rSL7/tvU"
Date: Wed, 01 Nov 2017 13:36:10 GMT
Connection: keep-alive
Вообще говоря, поX-
Заголовок в начале является нестандартным заголовком. пожалуйста, обратите внимание на этоX-Powered-By
заголовок, который раскрывает структуру, которую вы используете. Для злоумышленников это снижает стоимость атаки, поскольку они сосредотачиваются только на известных уязвимостях фреймворка.
надеть шлем
Посмотрим, будем ли мы использоватьhelmet
Что случится.运行以下命令安装helmet
:
npm install helmet --save
Будуhelmet
Добавьте промежуточное ПО в свое приложение. правильноindex.js
Внесите следующие изменения:
const express = require('express');
const helmet = require('helmet');
const PORT = process.env.PORT || 3000;
const app = express();
app.use(helmet());
app.get('/', (req, res) => {
res.send(`<h1>Hello World</h1>`);
});
app.listen(PORT, () => {
console.log(`Listening on http://localhost:${PORT}`);
});
Это используетсяhelmet
конфигурация по умолчанию. Далее посмотрите, что он делает. Перезапустите службу и снова проверьте заголовки HTTP с помощью следующей команды:
curl http://localhost:3000 --inspect
Новые заголовки будут похожи на следующие:
HTTP/1.1 200 OK
X-DNS-Prefetch-Control: off
X-Frame-Options: SAMEORIGIN
Strict-Transport-Security: max-age=15552000; includeSubDomains
X-Download-Options: noopen
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Content-Type: text/html; charset=utf-8
Content-Length: 20
ETag: W/"14-SsoazAISF4H46953FT6rSL7/tvU"
Date: Wed, 01 Nov 2017 13:50:42 GMT
Connection: keep-alive
Первое, что нужно отпраздноватьX-Powered-By
заголовок отсутствует. Но сейчас появилось много новых заголовков, что они делают?
X-DNS-Prefetch-Control
Этот заголовок мало что делает для повышения безопасности. Его значениеoff
, предварительная загрузка браузером DNS URL-адресов на странице отключена. Предварительная выборка DNS может повысить производительность вашего веб-сайта, согласно MDN, она можетУвеличьте скорость загрузки изображений на 5% и более. Однако включение этой функции также может вызвать проблемы с кэшем, когда пользователи посещают одну и ту же страницу несколько раз.
Аннотация: Проблема с кешем не обнаружена, если вы это понимаете, пожалуйста, оставьте сообщение
Его значение по умолчаниюoff
, если вы хотите повысить производительность с его помощью, вы можете вызватьhelmet()
входящий{ dnsPrefetchControl: { allow: true }}
Включите предварительную загрузку DNS.
X-Frame-Options
X-Frame-Options
Позволяет контролировать, может ли страница<frame/>
,<iframe/>
или<object/>
например, загрузка фрейма страницы. Если вам действительно не нужно открывать страницу таким образом, полностью отключите ее со следующей конфигурацией:
app.use(helmet({
frameguard: {
action: 'deny'
}
}));
Все современные браузеры поддерживаютX-Frame-Options
. Вы также можете управлять им с помощью Content Security Policy, о которой речь пойдет позже.
Strict-Transport-Security
Также известный как HSTS (строго безопасный HTTP-транспорт), он используется для обеспечения того, чтобы при посещении веб-сайтов HTTPS не происходило понижение версии протокола (возврат к HTTP). Если пользователь посещает HTTPS-сайт с этим заголовком один раз, браузер гарантирует, что будущим посещениям вторичного сайта не будет разрешено использовать HTTP. Эта функция помогает защититься от атак типа «человек посередине».
Иногда вы можете увидеть это в действии, когда пытаетесь получить доступ к порталу, такому как https://google.com, находясь в общедоступном WiFi. WiFi пытается перенаправить вас на их портал, но вы зашли через HTTPSgoogle.com
, и у него естьStrict-Transport-Security
заголовок, поэтому браузер заблокирует перенаправление.
вы можете посетитьMDNилиOWASP wikiПодробнее об этом см.
X-Download-Options
Этот заголовок используется только для защиты вашего приложения от старых ошибок IE. Как правило, если вы развертываете ненадежные HTTP-файлы для загрузки, пользователи могут открывать эти файлы напрямую (без предварительного сохранения их на диск) и выполнять их непосредственно в контексте вашего приложения. Этот заголовок гарантирует, что пользователи должны загружать такие файлы локально, прежде чем получить к ним доступ, тем самым предотвращая выполнение этих файлов в контексте вашего приложения.
вы можете посетитьдокументация по шлемуа такжеСообщение в блоге MSDNПодробнее об этом см.
X-Content-Type-Options
Некоторые браузеры не используют отправку с сервера.Content-Type
чтобы определить тип файла, и используйте «обнюхивание MIME», чтобы определить тип содержимого на основе содержимого файла и выполнить файл на основе этого.
Предположим, вы предоставляете способ загрузки изображений на веб-страницу, но злоумышленник загружает некоторые файлы изображений, содержимое которых представляет собой код HTML. Если браузер использует анализ MIME, он будет выполнен как код HTML, и злоумышленник может выполнить его успешно.Атака XSS .
Установив заголовок вnosniff
Этот анализ MIME можно отключить.
X-XSS-Protection
Этот заголовок включает базовую защиту XSS в браузере пользователя. Он не может предотвратить все атаки XSS, но может защитить от основных атак XSS. Например, если браузер обнаружит, что строка запроса содержит что-то вроде<script>
теги и т. д. предотвратят выполнение кода предполагаемой атаки XSS. Для этого заголовка можно установить три разных значения:0
,1
а также1; mode=block
. Если вы хотите узнать больше о том, как выбрать режим, ознакомьтесь сX-XSS-Protection
и его потенциальные опасностиодна статья.
Обновите свой шлем
Вышеупомянутое толькоhelmet
Приведены настройки по умолчанию. Кроме того, он позволяет установитьExpect-CT
,Public-Key-Pins
,Cache-Control
а такжеReferrer-Policy
такие как заголовки. ты сможешьhelmet
ДокументацияНайдите больше связанных конфигураций в .
Защитите содержимое своей веб-страницы от непреднамеренного нарушения
Межсайтовый скриптинг представляет собой неумолимую угрозу для веб-приложений. Если злоумышленник сможет внедрить и запустить код в вашем приложении, последствия могут стать кошмаром для вас и ваших пользователей. Существует решение, которое может попытаться предотвратить запуск непреднамеренного кода на вашей странице:CSP
(Политика безопасности контента).
CSP позволяет вам установить набор правил, определяющих источники, из которых ваши страницы могут загружать ресурсы. Любой ресурс, нарушающий правила, будет автоматически заблокирован браузером.
вы можете изменитьContent-Security-Policy
Заголовок HTTP, чтобы указать правила, или вы также можете использовать метатег, чтобы установить, когда вы не можете изменить заголовок.
Этот заголовок выглядит так:
Content-Security-Policy: default-src 'none';
script-src 'nonce-XQY ZwBUm/WV9iQ3PwARLw==';
style-src 'nonce-XQY ZwBUm/WV9iQ3PwARLw==';
img-src 'self';
font-src 'nonce-XQY ZwBUm/WV9iQ3PwARLw==' fonts.gstatic.com;
object-src 'none';
block-all-mixed-content;
frame-ancestors 'none';
В этом примере вы можете видеть, что мы разрешаем получать шрифты только из нашего собственного доменного имени или fonts.gstatic.com из Google Fonts; разрешена загрузка только изображений под этим доменным именем; разрешена загрузка только неуказанных источников , но должен содержать указанныйnonce
Файлы сценариев и стилей для значений. Значение nonce должно быть указано следующим образом:
<script src="myscript.js" nonce="XQY ZwBUm/WV9iQ3PwARLw=="></script>
<link rel="stylesheet" href="mystyles.css" nonce="XQY ZwBUm/WV9iQ3PwARLw==" />
Когда браузер получает HTML, он на всякий случай очищает все значения nonce, а другие скрипты не могут получить это значение и не могут добавить его на веб-страницу.
Вы также можете заблокировать весь смешанный HTTP-контент, содержащийся на HTTPS-страницах, и все<object />
элементы, а путем установкиdefault-src
дляnone
чтобы отключить все, кроме изображений, таблиц стилей и скриптов. Кроме того, вы также можетеframe-ancestors
чтобы отключить фреймы.
Вы можете вручную написать эти заголовки самостоятельно, но, к счастью, в Express есть много готовых решений CSP.helmet
Поддержка CSP,ноnonce
Вам нужно сгенерировать его самостоятельно. Я лично использую файл под названиемexpress-csp-header
модуль.
Установите и запуститеexpress-csp-header
:
npm install express-csp-header --save
для тебяindex.js
Добавьте и измените следующее, чтобы включить CSP:
const express = require('express');
const helmet = require('helmet');
const csp = require('express-csp-header');
const PORT = process.env.PORT || 3000;
const app = express();
const cspMiddleware = csp({
policies: {
'default-src': [csp.NONE],
'script-src': [csp.NONCE],
'style-src': [csp.NONCE],
'img-src': [csp.SELF],
'font-src': [csp.NONCE, 'fonts.gstatic.com'],
'object-src': [csp.NONE],
'block-all-mixed-content': true,
'frame-ancestors': [csp.NONE]
}
});
app.use(helmet());
app.use(cspMiddleware);
app.get('/', (req, res) => {
res.send(`
<h1>Hello World</h1>
<style nonce=${req.nonce}>
.blue { background: cornflowerblue; color: white; }
</style>
<p class="blue">This should have a blue background because of the loaded styles</p>
<style>
.red { background: maroon; color: white; }
</style>
<p class="red">This should not have a red background, the styles are not loaded because of the missing nonce.</p>
`);
});
app.listen(PORT, () => {
console.log(`Listening on http://localhost:${PORT}`);
});
Перезапустите службу, посетитеhttp://localhost:3000, вы можете увидеть абзац с синим фоном, потому что соответствующие стили были успешно загружены. А у другого абзаца нет стиля, потому что в его стиле отсутствует значение nonce.
Заголовок CSP также может установить URL-адрес для сообщения о нарушениях, и вы также можете включить только режим отчетов для сбора соответствующих данных, прежде чем строго включать CSP.
ты сможешьВведение в MDN CSPПросмотрите дополнительную информацию и просмотритеВеб-сайт «Могу ли я использовать» для совместимости с CSP. Большинство основных браузеров поддерживают эту функцию.
Суммировать
К сожалению, универсального решения с точки зрения безопасности не существует, и новые уязвимости появляются одна за другой. Однако вы можете легко установить эти заголовки HTTP в своем веб-приложении и значительно повысить безопасность своего приложения, почему бы и нет? Если вы хотите узнать больше о передовых методах повышения безопасности заголовков HTTP, посетите страницуsecurityheaders.io.
Если вы хотите узнать больше о передовых методах веб-безопасности, посетитеОткрытый проект безопасности веб-приложений (OWASP), который охватывает широкий спектр тем и полезных ресурсов.
Если у вас есть какие-либо вопросы или у вас есть другие инструменты для улучшения веб-приложений Node.js, свяжитесь со мной:
- Твиттер:@dkundel
- Эл. адрес:dkundel@twilio.com
- Гитхаб:dkundel
Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из ИнтернетаНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,товар,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.