Node.js
Защита приложений Node.js
Поиск…
Предотвращение подделки подпроса (CSRF)
CSRF - это атака, которая заставляет конечного пользователя выполнять нежелательные действия в веб-приложении, в котором он / она сейчас аутентифицирован.
Это может произойти из-за того, что файлы cookie отправляются с каждым запросом на сайт - даже если эти запросы поступают с другого сайта.
Мы можем использовать модуль csurf
для создания токена csrf и проверки его.
пример
var express = require('express')
var cookieParser = require('cookie-parser') //for cookie parsing
var csrf = require('csurf') //csrf module
var bodyParser = require('body-parser') //for body parsing
// setup route middlewares
var csrfProtection = csrf({ cookie: true })
var parseForm = bodyParser.urlencoded({ extended: false })
// create express app
var app = express()
// parse cookies
app.use(cookieParser())
app.get('/form', csrfProtection, function(req, res) {
// generate and pass the csrfToken to the view
res.render('send', { csrfToken: req.csrfToken() })
})
app.post('/process', parseForm, csrfProtection, function(req, res) {
res.send('data is being processed')
})
Таким образом, когда мы обращаемся к GET /form
, он передает представление csrf csrfToken
в представление.
Теперь в представлении установите значение csrfToken как значение скрытого поля ввода с именем _csrf
.
например, для шаблонов handlebar
<form action="/process" method="POST">
<input type="hidden" name="_csrf" value="{{csrfToken}}">
Name: <input type="text" name="name">
<button type="submit">Submit</button>
</form>
например, для jade
шаблонов
form(action="/process" method="post")
input(type="hidden", name="_csrf", value=csrfToken)
span Name:
input(type="text", name="name", required=true)
br
input(type="submit")
например, для шаблонов ejs
<form action="/process" method="POST">
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
Name: <input type="text" name="name">
<button type="submit">Submit</button>
</form>
SSL / TLS в Node.js
Если вы решите обрабатывать SSL / TLS в приложении Node.js, считайте, что вы также несете ответственность за поддержку предотвращения атак SSL / TLS на этом этапе. Во многих архитектурах сервер-клиент SSL / TLS заканчивается на обратном прокси, как для уменьшения сложности приложений, так и для уменьшения объема конфигурации безопасности.
Если ваше приложение Node.js должно обрабатывать SSL / TLS, его можно защитить, загрузив файлы ключей и сертификатов.
Если вашему поставщику сертификатов требуется цепочка сертификатов (CA), его можно добавить в опцию ca
в качестве массива. Цепочка с несколькими записями в одном файле должна быть разделена на несколько файлов и введена в том же порядке в массив, что и Node.js в настоящее время не поддерживает несколько записей ca в одном файле. Пример приведен в приведенном ниже коде для файлов 1_ca.crt
и 2_ca.crt
. Если массив ca
необходим и не установлен правильно, клиентские браузеры могут отображать сообщения, которые не могут подтвердить подлинность сертификата.
пример
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('privatekey.pem'),
cert: fs.readFileSync('certificate.pem'),
ca: [fs.readFileSync('1_ca.crt'), fs.readFileSync('2_ca.crt')]
};
https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('hello world\n');
}).listen(8000);
Использование HTTPS
Минимальная настройка для HTTPS-сервера в Node.js будет примерно такой:
const https = require('https');
const fs = require('fs');
const httpsOptions = {
key: fs.readFileSync('path/to/server-key.pem'),
cert: fs.readFileSync('path/to/server-crt.pem')
};
const app = function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}
https.createServer(httpsOptions, app).listen(4433);
Если вы также хотите поддерживать HTTP-запросы, вам нужно сделать только эту небольшую модификацию:
const http = require('http');
const https = require('https');
const fs = require('fs');
const httpsOptions = {
key: fs.readFileSync('path/to/server-key.pem'),
cert: fs.readFileSync('path/to/server-crt.pem')
};
const app = function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}
http.createServer(app).listen(8888);
https.createServer(httpsOptions, app).listen(4433);
Настройка сервера HTTPS
После установки в вашей системе узла node.js, просто следуйте приведенной ниже процедуре, чтобы получить базовый веб-сервер с поддержкой как HTTP, так и HTTPS!
Шаг 1. Создание центра сертификации
создайте папку, в которой вы хотите сохранить свой ключ и сертификат:
mkdir conf
перейдите в этот каталог:
cd conf
возьмите этот файл
ca.cnf
для использования в качестве ярлыка конфигурации:wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/ca.cnf
создайте новый центр сертификации, используя эту конфигурацию:
openssl req -new -x509 -days 9999 -config ca.cnf -keyout ca-key.pem -out ca-cert.pem
теперь, когда у нас есть наш
ca-key.pem
сертификации вca-key.pem
иca-cert.pem
, давайте сгенерируем закрытый ключ для сервера:openssl genrsa -out key.pem 4096
захватите этот файл
server.cnf
для использования в качестве ярлыка конфигурации:wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/server.cnf
сгенерировать запрос подписи сертификата с использованием этой конфигурации:
openssl req -new -config server.cnf -key key.pem -out csr.pem
Подпишите запрос:
openssl x509 -req -extfile server.cnf -days 999 -passin "pass:password" -in csr.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem
Шаг 2. Установите сертификат как корневой сертификат.
скопируйте свой сертификат в папку корневых сертификатов:
sudo cp ca-crt.pem /usr/local/share/ca-certificates/ca-crt.pem
обновить магазин CA:
sudo update-ca-certificates
Безопасное приложение express.js 3
Конфигурация для безопасного подключения с помощью express.js (Начиная с версии 3):
var fs = require('fs');
var http = require('http');
var https = require('https');
var privateKey = fs.readFileSync('sslcert/server.key', 'utf8');
var certificate = fs.readFileSync('sslcert/server.crt', 'utf8');
// Define your key and cert
var credentials = {key: privateKey, cert: certificate};
var express = require('express');
var app = express();
// your express configuration here
var httpServer = http.createServer(app);
var httpsServer = https.createServer(credentials, app);
// Using port 8080 for http and 8443 for https
httpServer.listen(8080);
httpsServer.listen(8443);
Таким образом, вы предоставляете прямое промежуточное ПО на собственный сервер http / https
Если вы хотите, чтобы ваше приложение работало на портах ниже 1024, вам нужно будет использовать команду sudo (не рекомендуется) или использовать обратный прокси (например, nginx, haproxy).