Node.js
Zabezpieczanie aplikacji Node.js
Szukaj…
Zapobieganie fałszowaniu żądań w różnych witrynach (CSRF)
CSRF jest atakiem, który zmusza użytkownika końcowego do wykonania niepożądanych działań w aplikacji internetowej, w której jest on obecnie uwierzytelniony.
Może się tak zdarzyć, ponieważ pliki cookie są wysyłane przy każdym żądaniu do witryny internetowej - nawet jeśli żądania te pochodzą z innej witryny.
Możemy użyć modułu csurf
do tworzenia tokena csrf i sprawdzania go.
Przykład
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')
})
Tak więc, kiedy uzyskamy dostęp do GET /form
, przekaże token csrfToken
do widoku.
Teraz w widoku ustaw wartość csrfToken jako wartość ukrytego pola wejściowego o nazwie _csrf
.
np. dla szablonów 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>
np. dla szablonów 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")
np. dla szablonów 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 w Node.js
Jeśli zdecydujesz się obsługiwać SSL / TLS w aplikacji Node.js, weź pod uwagę, że w tym momencie jesteś również odpowiedzialny za utrzymanie zapobiegania atakom SSL / TLS. W wielu architekturach serwer-klient protokół SSL / TLS kończy się na zwrotnym serwerze proxy, zarówno w celu zmniejszenia złożoności aplikacji, jak i ograniczenia zakresu konfiguracji zabezpieczeń.
Jeśli aplikacja Node.js ma obsługiwać protokół SSL / TLS, można go zabezpieczyć, ładując pliki klucza i certyfikatu.
Jeśli dostawca certyfikatu wymaga łańcucha urzędu certyfikacji (CA), można go dodać w opcji ca
jako tablicę. Łańcuch z wieloma wpisami w jednym pliku musi zostać podzielony na wiele plików i wprowadzony w tej samej kolejności do tablicy, ponieważ Node.js nie obsługuje obecnie wielu wpisów ca w jednym pliku. Przykład podano w poniższym kodzie dla plików 1_ca.crt
i 2_ca.crt
. Jeśli tablica ca
jest wymagana i niepoprawnie ustawiona, przeglądarki klientów mogą wyświetlać komunikaty, że nie mogą zweryfikować autentyczności certyfikatu.
Przykład
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);
Korzystanie z HTTPS
Minimalna konfiguracja serwera HTTPS w Node.js wyglądałaby mniej więcej tak:
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);
Jeśli chcesz również obsługiwać żądania HTTP, musisz wprowadzić tylko małą modyfikację:
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);
Konfigurowanie serwera HTTPS
Po zainstalowaniu node.js w systemie, po prostu wykonaj poniższą procedurę, aby uruchomić podstawowy serwer WWW z obsługą zarówno HTTP, jak i HTTPS!
Krok 1: Zbuduj ośrodek certyfikacji
utwórz folder, w którym chcesz przechowywać swój klucz i certyfikat:
mkdir conf
przejdź do tego katalogu:
cd conf
ca.cnf
ten plikca.cnf
, aby użyć go jako skrótu konfiguracji:wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/ca.cnf
utwórz nowy urząd certyfikacji przy użyciu tej konfiguracji:
openssl req -new -x509 -days 9999 -config ca.cnf -keyout ca-key.pem -out ca-cert.pem
teraz, gdy mamy nasz urząd certyfikacji w
ca-key.pem
ica-cert.pem
, wygenerujmy klucz prywatny dla serwera:openssl genrsa -out key.pem 4096
pobierz ten plik
server.cnf
, aby użyć go jako skrótu konfiguracji:wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/server.cnf
wygeneruj żądanie podpisania certyfikatu przy użyciu tej konfiguracji:
openssl req -new -config server.cnf -key key.pem -out csr.pem
podpisać wniosek:
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
Krok 2: Zainstaluj certyfikat jako certyfikat główny
skopiuj swój certyfikat do folderu głównego certyfikatów:
sudo cp ca-crt.pem /usr/local/share/ca-certificates/ca-crt.pem
zaktualizuj sklep CA:
sudo update-ca-certificates
Bezpieczna aplikacja express.js 3
Konfiguracja zapewniająca bezpieczne połączenie przy użyciu express.js (od wersji 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);
W ten sposób dostarczasz ekspresowe oprogramowanie pośrednie do macierzystego serwera http / https
Jeśli chcesz, aby Twoja aplikacja działała na portach poniżej 1024, musisz użyć polecenia sudo (niezalecane) lub odwrotnego proxy (np. Nginx, haproxy).