サーチ…


クロスサイトリクエスト偽造(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:認証局を構築する

  1. キーと証明書を保存するフォルダを作成します。

    mkdir conf


  1. そのディレクトリに移動します:

    cd conf


  1. このca.cnfファイルを取得して設定ショートカットとして使用する:

    wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/ca.cnf


  1. この構成を使用して新しい認証局を作成します。

    openssl req -new -x509 -days 9999 -config ca.cnf -keyout ca-key.pem -out ca-cert.pem


  1. ca-key.pemca-cert.pemに認証局があるので、サーバーの秘密鍵を生成しましょう:

    openssl genrsa -out key.pem 4096


  1. このserver.cnfファイルを取得して設定ショートカットとして使用します。

    wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/server.cnf


  1. 次の設定を使用して証明書署名要求を生成します。

    openssl req -new -config server.cnf -key key.pem -out csr.pem


  1. リクエストに署名してください:

    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:証明書をルート証明書としてインストールする

  1. 証明書をルート証明書のフォルダにコピーします。

    sudo cp ca-crt.pem /usr/local/share/ca-certificates/ca-crt.pem


  1. 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など)を使用する必要があります。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow