Node.js、そして Express でリダイレクトを実装する際は、サーバーサイドで入力検証を行うことが重要です。 もし攻撃者が、外部のユーザーから与えられた入力を検証していないことを発見した場合、特別に作成されたリンクをフォーラムやソーシャルメディア、その他のパブリックな場所に投稿してユーザーにクリックさせることで、この脆弱性を悪用する恐れがあります。
例: ユーザー入力を利用した、安全でない express リダイレクト
const express = require('express');
const app = express();
app.get('/login', (req, res, next) => {
if (req.session.isAuthenticated()) {
res.redirect(req.query.url);
}
});
安全でないリダイレクトを避けるために推奨される改善方法は、ユーザー入力を信頼しないということです。ユーザー入力を利用する必要がある場合には、脆弱性を晒すことを避けるために、安全なリダイレクトホワイトリストを利用することができます。
例: 安全なリダイレクトホワイトリスト
const whitelist = {
'https://google.com': 1
};
function getValidRedirect(url) {
// url がシングルスラッシュで始めっているかチェックする
if (url.match(/^\/(?!\/)/)) {
// 正しくドメインを付加する
return 'https://example.com' + url;
}
// または、ホワイトリストでチェックする
return whitelist[url] ? url : '/';
}
app.get('/login', (req, res, next) => {
if (req.session.isAuthenticated()) {
res.redirect(getValidRedirect(req.query.url));
}
});
NodeSwat のブログより:
幸いなことに、この脆弱性に対する緩和策は非常にシンプルです - 検証されていないユーザー入力を、リダイレクトのための基準として扱わないことです。
Hailstone のブログより:
しかし、もしサーバーサイドのリダイレクトロジックが url パラメータを入力するデータを検証しない場合、ユーザーはまるであなたのサイトのように見える(examp1e.com)にたどり着き、犯罪者ハッカーの要求を満たす結果となりかねません。