Node.js
Säkra Node.js-applikationer
Sök…
Förebyggande förfalskning på olika ställen (CSRF)
CSRF är en attack som tvingar slutanvändaren att utföra oönskade åtgärder på en webbapplikation där han / hon för närvarande är autentiserad.
Det kan hända eftersom cookies skickas med varje förfrågan till en webbplats - även när dessa förfrågningar kommer från en annan webbplats.
Vi kan använda csurf
modulen för att skapa csrf-token och validera den.
Exempel
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')
})
Så när vi öppnar GET /form
kommer det att skicka csrf-token csrfToken
till vyn.
Ställ in csrfToken-värdet inuti vyn som värdet för ett doldt inmatningsfält med namnet _csrf
.
t.ex. för 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>
t.ex. för jade
mallar
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")
t.ex. för ejs
mallar
<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 i Node.js
Om du väljer att hantera SSL / TLS i din Node.js-applikation, tänk på att du också är ansvarig för att upprätthålla SSL / TLS-attackförebyggande vid denna punkt. I många server-klientarkitekturer avslutas SSL / TLS på en omvänd proxy, både för att minska applikationens komplexitet och minska omfattningen av säkerhetskonfiguration.
Om din Node.js-applikation ska hantera SSL / TLS kan det säkras genom att ladda nyckel- och certifikatfilerna.
Om din certifikatleverantör kräver en certifikatutfärdare (CA) -kedja kan den läggas till i ca
alternativet som en matris. En kedja med flera poster i en enda fil måste delas upp i flera filer och anges i samma ordning i arrayen som Node.js för närvarande inte stöder flera ca-poster i en fil. Ett exempel finns i koden nedan för filer 1_ca.crt
och 2_ca.crt
. Om ca
arrayen krävs och inte är korrekt inställd, kan klientläsare visa meddelanden som de inte kunde verifiera certifikatets äkthet.
Exempel
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);
Använda HTTPS
Den minimala inställningen för en HTTPS-server i Node.js skulle vara något liknande:
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);
Om du också vill stödja http-förfrågningar, måste du göra just den här lilla modifieringen:
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);
Ställa in en HTTPS-server
När du har installerat node.js på ditt system, följ bara proceduren nedan för att få en grundläggande webbserver med stöd för både HTTP och HTTPS!
Steg 1: Bygg en certifikatutfärdare
skapa mappen där du vill lagra ditt nyckel & certifikat:
mkdir conf
gå till den katalogen:
cd conf
ta denna
ca.cnf
fil för att använda som en genväg för konfigurering:wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/ca.cnf
skapa en ny certifikatutfärdare med hjälp av denna konfiguration:
openssl req -new -x509 -days 9999 -config ca.cnf -keyout ca-key.pem -out ca-cert.pem
nu när vi har vår certifikatutfärdare i
ca-key.pem
ochca-cert.pem
, låt oss skapa en privat nyckel för servern:openssl genrsa -out key.pem 4096
ta denna
server.cnf
fil för att använda som en genväg för konfigurering:wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/server.cnf
generera certifikatsigneringsbegäran med denna konfiguration:
openssl req -new -config server.cnf -key key.pem -out csr.pem
underteckna begäran:
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
Steg 2: Installera ditt certifikat som ett rotcertifikat
kopiera ditt certifikat till mappen rotcertifikat:
sudo cp ca-crt.pem /usr/local/share/ca-certificates/ca-crt.pem
uppdatera CA-butiken:
sudo update-ca-certificates
Secure express.js 3-applikation
Konfigurationen för att skapa en säker anslutning med express.js (Sedan 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);
På det sättet tillhandahåller du express middleware till den ursprungliga http / https-servern
Om du vill att din app ska köras på portar under 1024 måste du använda sudo-kommando (rekommenderas inte) eller använda en omvänd proxy (t.ex. nginx, haproxy).