Node.js
Protezione delle applicazioni Node.js
Ricerca…
Prevenire la falsificazione di richieste cross-site (CSRF)
CSRF è un attacco che costringe l'utente finale a eseguire azioni indesiderate su un'applicazione web in cui è attualmente autenticato.
Può accadere perché i cookie vengono inviati con ogni richiesta a un sito Web, anche quando tali richieste provengono da un altro sito.
Possiamo usare il modulo csurf
per creare il token csrf e convalidarlo.
Esempio
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')
})
Quindi, quando accediamo a GET /form
, passeremo il token csrfToken
alla vista.
Ora, all'interno della vista, imposta il valore csrfToken come valore di un campo di input nascosto chiamato _csrf
.
ad esempio per handlebar
modelli 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>
ad esempio per i modelli di 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")
ad esempio per i modelli di 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 in Node.js
Se si sceglie di gestire SSL / TLS nell'applicazione Node.js, considerare che si è anche responsabili della gestione della prevenzione degli attacchi SSL / TLS a questo punto. In molte architetture server-client, SSL / TLS termina su un proxy inverso, sia per ridurre la complessità delle applicazioni sia per ridurre l'ambito della configurazione della sicurezza.
Se l'applicazione Node.js deve gestire SSL / TLS, può essere protetta caricando i file key e cert.
Se il proprio fornitore di certificati richiede una catena di autorità di certificazione (CA), può essere aggiunto all'opzione ca
come array. Una catena con più voci in un singolo file deve essere suddivisa in più file e inserita nello stesso ordine nell'array poiché Node.js attualmente non supporta più voci ca in un unico file. Un esempio è fornito nel seguente codice per i file 1_ca.crt
e 2_ca.crt
. Se l'array ca
è richiesto e non impostato correttamente, i browser client potrebbero visualizzare messaggi che non potrebbero verificare l'autenticità del certificato.
Esempio
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);
Utilizzando HTTPS
L'installazione minima per un server HTTPS in Node.js sarebbe qualcosa del genere:
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);
Se vuoi anche supportare le richieste http, devi fare solo questa piccola modifica:
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);
Configurare un server HTTPS
Una volta che node.js è installato sul sistema, basta seguire la procedura seguente per ottenere un server Web di base in esecuzione con supporto per HTTP e HTTPS!
Passaggio 1: creare un'autorità di certificazione
creare la cartella in cui si desidera memorizzare la chiave e il certificato:
mkdir conf
vai a quella directory:
cd conf
prendi questo file
ca.cnf
da usare come scorciatoia di configurazione:wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/ca.cnf
creare una nuova autorità di certificazione utilizzando questa configurazione:
openssl req -new -x509 -days 9999 -config ca.cnf -keyout ca-key.pem -out ca-cert.pem
ora che abbiamo la nostra autorità di certificazione in
ca-key.pem
eca-cert.pem
,ca-key.pem
una chiave privata per il server:openssl genrsa -out key.pem 4096
prendi questo file
server.cnf
da usare come scorciatoia di configurazione:wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/server.cnf
generare la richiesta di firma del certificato utilizzando questa configurazione:
openssl req -new -config server.cnf -key key.pem -out csr.pem
firmare la richiesta:
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
Passaggio 2: installa il certificato come certificato di origine
copia il tuo certificato nella cartella dei certificati di root:
sudo cp ca-crt.pem /usr/local/share/ca-certificates/ca-crt.pem
aggiornare l'archivio di CA:
sudo update-ca-certificates
Applicazione Secure express.js 3
La configurazione per creare una connessione sicura usando express.js (Dalla versione 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);
In questo modo fornisci il middleware espresso al server http / https nativo
Se si desidera che l'app venga eseguita su porte inferiori a 1024, sarà necessario utilizzare il comando sudo (non consigliato) o utilizzare un proxy inverso (ad esempio nginx, haproxy).