Node.js
Node.jsアプリケーションのセキュリティ保護
サーチ…
クロスサイトリクエスト偽造(CSRF)の防止
CSRFはエンドユーザーに、現在認証されているWebアプリケーションで不必要なアクションを実行させる攻撃です。
これは、CookieがWebサイトに送信されるたびに(リクエストが別のサイトから送信された場合でも)、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
れます。
さて、ビュー内で、名前の隠し入力フィールドの値として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>
Node.jsのSSL / TLS
Node.jsアプリケーションでSSL / TLSを処理することを選択した場合は、この時点でSSL / TLS攻撃防御を維持する責任もあると考えてください。多くのサーバークライアントアーキテクチャでは、SSL / TLSはリバースプロキシで終了するため、アプリケーションの複雑さが軽減され、セキュリティ構成の範囲が縮小されます。
Node.jsアプリケーションでSSL / TLSを処理する必要がある場合は、キーファイルと証明書ファイルをロードして保護することができます。
証明書プロバイダに認証局(CA)チェーンが必要な場合は、 ca
オプションで配列として追加できます。 1つのファイルに複数のエントリがあるチェーンは複数のファイルに分割され、Node.jsは現在1つのファイル内に複数の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の使用
Node.jsのHTTPSサーバーの最小限の設定は、次のようになります。
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の両方をサポートしている基本Webサーバーを実行してください。
手順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-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
Secure 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など)を使用する必要があります。