ノードを保護します.クロスサイトのリクエスト偽造からのJSアプリ


Protect your Node.js app from Cross-Site Request Forgery もともとはTwilio Blog 2018年1月
つの古典的な攻撃時のWebアプリケーションでの作業ですCross Site Request Forgery aka CSRF/XSRF ( c -サーフを読む).彼らは、攻撃者が彼らを気づかないであなたのアプリケーションのユーザーのために要求を実行するのに用いられます.彼らがどのようにこれを引き抜くことができるか、そして、我々がどのようにこれらのタイプの脅威から我々のアプリケーションを保護することができるかについて見ましょう.

話をしましょう

CSRF攻撃を防ぐ前に、彼らがどのように働くかを理解する必要があります.通常、これらの攻撃は、フォームベースの送信を使用するWebアプリケーションの機能で実行されますPOST リクエストとクッキーベースの認証.
攻撃者は隠されたフォームを自動的に実行する悪意のあるページに置きますPOST ページのエンドポイントへのリクエスト.ブラウザは、自動的に要求に沿ってそのページのために格納されたすべてのクッキーを送ります.ユーザーが現在のセッションにログインされるならば、攻撃者はそれらを気づかないでログインされたユーザのためにメッセージをポストすることができました.攻撃者は、これのためにページのクッキーにアクセスする必要はありません.

我々は、CSRFトークンを使用して、この攻撃から自分を守ることができます.ブラウザーがサーバーからページを取得すると、CSRFトークンとしてランダムに生成された文字列がクッキーとして送信されます.後で、あなたのページがポストリクエストを実行するとき、それはCSRFトークンをクッキーとして、また、ボディーのパラメタのような別の方法で、またはHTTPヘッダーを通してHTTPヘッダーを通して送りますX-CSRF-Token .

攻撃者は彼らの隠れた形で同じ振舞いを再現することができません.そして、彼らが値を取り戻すためにクッキーにアクセスすることができないので、攻撃者は彼らの悪意あるポスト要求とともにそれを送ります.
この概念は非常に多くのWebアプリケーションで実装することができますが、どのように我々はExpress アプリケーション.

ボードの準備

まず最初に我々は、CSFの脆弱性はどのように現実に動作し、どのように我々はそれから自分自身を守ることができるかを確認するアプリケーションが必要です.既に存在するならばExpress アプリケーションは、次の手順を実行する自由を感じる.代わりに、我々のデモアプリケーションを設定するには、次の手順に従ってください.
始める前に[ node . js ]を確認してくださいhttps://nodejs.org ] and npm または別のパッケージマネージャがインストールされます.次のコマンドを端末で実行して、新しいプロジェクトを起動します
mkdir csrf-demo
cd csrf-demo
npm init -y
npm install express body-parser --save
次に新しいファイルを作成しますindex.js に以下のコードを入れます:
const express = require('express');
const bodyParser = require('body-parser');

const PORT = process.env.PORT || 3000;
const app = express();

app.use(bodyParser.urlencoded({
  extended: true
}));

app.get('/', (req, res) => {
  res.send(`
    <h1>Hello World</h1>
    <form action="/entry" method="POST">
      <div>
        <label for="message">Enter a message</label>
        <input id="message" name="message" type="text" />
      </div>
      <input type="submit" value="Submit" />
    </form>
  `);
});

app.post('/entry', (req, res) => {
  console.log(`Message received: ${req.body.message}`);
  res.send(`Message received: ${req.body.message}`);
});

app.listen(PORT, () => {
  console.log(`Listening on http://localhost:${PORT}`);
});
実行してアプリケーションを起動します.
node .
訪問http://localhost:3000 そして、あなたはHello World そしてその下の小さな形.


危険な水
現在のサーバには2つのエンドポイントがあります.つは私たちのメインページは、あなたが行くときに提供されてhttp://localhost:3000/ . もう一つはPOST エンドポイントhttp://localhost:3000/entry . 我々がフォームを記入して、提出を押すとき、我々はAを作りますPOST このエンドポイントへのリクエスト.
フォーム内のいくつかのテキストを入力して送信を送信してください.あなたは、メッセージが戻るのを見なければなりません、そして、それもあなたの実行中のサーバーのコンソールに記録されるべきです.

残念ながら、攻撃者は自分のページに同じリクエストを行うことができます.我々が同じ形を実装したとシミュレーションするためにpage on Glitch . 訪問csrf-attack.glitch.me , メッセージを入力して送信を送信します.この動作は、localhost ページ.メッセージを転送し、設定されているクッキーをそのまま渡します.
この場合、私たちは、ユーザーが自分で提出できるフォームを作成しましたが、それは、自動車が悪意のある内容で提出する隠された形であったかもしれません.どのように我々がこれから我々のページを保護するかについて見ましょう.

行くcsurf ing
アプリケーションでCSRFトークンを実装するのに役立つ複数のモジュールがあります.そのうちの一つはcsurf . このモジュールをcookie-parser 実行時の依存関係:
npm install cookie-parser csurf --save
これらのモジュールの両方は、Expressで要求の動作を変更できるミドルウェアです.既に使用中ですbody-parser パースするPOST メッセージを取得する本文.また、それをチェックするために使用します_csrf トークン.The cookie-parser ミドルウェアは、トークンがクッキーとcsurf 任意の自動ガードになりますPOST , PUT , PATCH or DELETE をチェックする_csrf トークンはクッキーとリクエスト本体の両方に存在し、マッチします.
次のコードを追加しますindex.js ミドルウェアを設定するファイル
const express = require('express');
const bodyParser = require('body-parser');
const csurf = require('csurf');
const cookieParser = require('cookie-parser');

const PORT = process.env.PORT || 3000;
const app = express();

const csrfMiddleware = csurf({
  cookie: true
});

app.use(bodyParser.urlencoded({
  extended: true
}));
app.use(cookieParser());
app.use(csrfMiddleware);

app.get('/', (req, res) => {
  res.send(`
    <h1>Hello World</h1>
    <form action="/entry" method="POST">
      <div>
        <label for="message">Enter a message</label>
        <input id="message" name="message" type="text" />
      </div>
      <input type="submit" value="Submit" />
      <input type="hidden" name="_csrf" value="${req.csrfToken()}" />
    </form>
  `);
});

app.post('/entry', (req, res) => {
  console.log(`Message received: ${req.body.message}`);
  res.send(`CSRF token used: ${req.body._csrf}, Message received: ${req.body.message}`);
});

app.listen(PORT, () => {
  console.log(`Listening on http://localhost:${PORT}`);
});
サーバーを再起動してhttp://localhost:3000 . 入力ボックスにいくつかのテキストを入力し、ヒットSubmit . コンソールにメッセージが表示され、ブラウザの下に次のようなメッセージが表示されます.

今すぐスイッチをバックアップしますdemo page on Glitch メッセージを入力します.送信すると、要求が失敗し、メッセージがコンソールに表示されないことがわかります.The _csrf クッキーは、しかし、ページが同じ値を送信しない転送されますPOST ボディ_csrf 値.その結果、要求はcsurf ミドルウェアと我々はCSRF攻撃から身を守った.

次は何ですか.
我々は簡単にノードにCCRFトークンを統合する方法を見ました.サーバー側レンダリングコードとJSベースのアプリケーション.しかし、フロントエンドのフレームワークやライブラリとCSRFトークンを使用するだけで簡単です.私たちはクッキーとしてトークンを送信しているので、簡単にそれを読むことができますし、後であなたのAsyncリクエストでヘッダーとして送信します.事実上Angular’s HttpClient has this feature already built-in .
ノードを安全にする方法についてもっと学びましょう.JSのアプリケーションは、私のブログのポストをチェックアウトしてくださいSecuring your Express app . また、チェックアウトする必要がありますOWASP page セキュリティ関連のトピックの広い範囲をカバーする.
あなたのノードのセキュリティを改善するための質問やその他の便利なツールがある場合.JS Webアプリケーションは、私のpingを自由に感じる:
  • 🐦 Twitter
  • 📧 メール[email protected]
  • 🐙🐱 ギタブ:Dkundel
  • Protect your Node.js app from Cross-Site Request Forgery もともとはTwilio Blog 2018年1月