Node.js
Sécurisation des applications Node.js
Recherche…
Prévention de la contrefaçon de requêtes inter-sites (CSRF)
CSRF est une attaque qui oblige l'utilisateur final à exécuter des actions indésirables sur une application Web dans laquelle il est actuellement authentifié.
Cela peut se produire parce que les cookies sont envoyés avec chaque demande à un site Web - même lorsque ces demandes proviennent d'un autre site.
Nous pouvons utiliser le module csurf
pour créer un jeton csrf et le valider.
Exemple
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')
})
Ainsi, lorsque nous csrfToken
à GET /form
, il transmettra le jeton csrfToken
à la vue.
Maintenant, dans la vue, définissez la valeur csrfToken comme valeur d'un champ d'entrée masqué nommé _csrf
.
par exemple pour les modèles de 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>
par exemple pour les modèles de 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")
par exemple pour les modèles 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 dans Node.js
Si vous choisissez de gérer SSL / TLS dans votre application Node.js, considérez que vous êtes également responsable du maintien de la prévention des attaques SSL / TLS à ce stade. Dans de nombreuses architectures serveur-client, SSL / TLS se termine sur un proxy inverse, à la fois pour réduire la complexité des applications et pour réduire la portée de la configuration de la sécurité.
Si votre application Node.js doit gérer SSL / TLS, elle peut être sécurisée en chargeant les fichiers clé et cert.
Si votre fournisseur de certificats requiert une chaîne d'autorité de certification, il peut être ajouté dans l'option ca
tant que tableau. Une chaîne avec plusieurs entrées dans un seul fichier doit être divisée en plusieurs fichiers et saisie dans le même ordre dans le tableau car Node.js ne prend actuellement pas en charge plusieurs entrées dans un fichier. Un exemple est fourni dans le code ci-dessous pour les fichiers 1_ca.crt
et 2_ca.crt
. Si le tableau ca
est requis et n'est pas défini correctement, les navigateurs clients peuvent afficher des messages qu'ils n'ont pas pu vérifier l'authenticité du certificat.
Exemple
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);
Utiliser HTTPS
La configuration minimale pour un serveur HTTPS dans Node.js serait la suivante:
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);
Si vous souhaitez également prendre en charge les requêtes http, vous devez apporter cette petite modification:
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);
Configuration d'un serveur HTTPS
Une fois que node.js est installé sur votre système, suivez la procédure ci-dessous pour obtenir un serveur Web de base compatible avec HTTP et HTTPS!
Étape 1: créer une autorité de certification
Créez le dossier dans lequel vous souhaitez stocker votre clé et votre certificat:
mkdir conf
allez dans ce répertoire:
cd conf
récupérer ce fichier
ca.cnf
à utiliser comme raccourci de configuration:wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/ca.cnf
créer une nouvelle autorité de certification en utilisant cette configuration:
openssl req -new -x509 -days 9999 -config ca.cnf -keyout ca-key.pem -out ca-cert.pem
Maintenant que nous avons notre autorité de certification dans
ca-key.pem
etca-cert.pem
, générons une clé privée pour le serveur:openssl genrsa -out key.pem 4096
récupérer ce fichier
server.cnf
à utiliser comme raccourci de configuration:wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/server.cnf
générer la demande de signature de certificat en utilisant cette configuration:
openssl req -new -config server.cnf -key key.pem -out csr.pem
signer la demande:
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
Étape 2: installez votre certificat en tant que certificat racine
copiez votre certificat dans le dossier de vos certificats racine:
sudo cp ca-crt.pem /usr/local/share/ca-certificates/ca-crt.pem
mettre à jour le magasin CA:
sudo update-ca-certificates
Application express.js sécurisée 3
La configuration pour établir une connexion sécurisée avec express.js (depuis la version 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);
De cette manière, vous fournissez un middleware express au serveur natif http / https
Si vous souhaitez que votre application s'exécute sur des ports inférieurs à 1024, vous devrez utiliser la commande sudo (non recommandée) ou utiliser un proxy inverse (par exemple, nginx, haproxy).