「悪意あるスクリプト」を玄関で追い返せ!XSS対策とDOMPurifyの正しい使い方
こんにちは。セキュリティの現場で長年、泥臭いインシデントと戦い続けているエンジニアです。
今日は、Web開発の現場で避けては通れない「クロスサイトスクリプティング(XSS)」についてお話しします。難しそうな名前に聞こえますが、実は「泥棒に家の合鍵を渡してしまわないための防犯対策」と考えれば、グッと身近になりますよ。
一歩ずつ、一緒に学んでいきましょう!
—
そもそもXSSって何? 「偽物の郵便物」に注意!
XSSとは、悪意のある攻撃者がWebサイトの入力欄などを利用して、「不正なプログラム(スクリプト)」を他のユーザーのブラウザで実行させる攻撃のことです。
たとえで考えてみましょう。あなたの家のポスト(Webサイトの入力フォーム)に、泥棒が「この手紙を読んだら、家の鍵を外に出しておいてね」という偽物の指示書(不正なJavaScript)を紛れ込ませたとします。
その手紙を家族(ユーザー)が読み、指示通りに鍵を外に出してしまったら……大変ですよね。これがXSSの正体です。
- 反射型: 泥棒がその場で「鍵を外せ」と書いたメモを、通りかかった人に手渡す(URLに悪意あるコードを仕込む)。
- 格納型: 掲示板などに「この手紙を読め」と大きな看板を立て、全員を罠にかける(DBに悪意あるコードを保存する)。
- DOM型: 郵便物そのものに細工をするのではなく、家の中の仕掛け(JavaScriptの処理)を悪用して、勝手に鍵を開けさせる。
どれも共通しているのは、「信用してはいけないもの(外部からの入力)を、そのまま信用して実行してしまう」という点です。
—
防御の要:サニタイズライブラリ「DOMPurify」の出番
「じゃあ、全部の入力を禁止すればいいの?」というと、そうはいきませんよね。ブログの投稿やチャットのように、HTMLタグを使いたい場面はたくさんあります。
そこで登場するのが、「サニタイズ(消毒)」という考え方です。
郵便物の中に「爆弾」や「脅迫状」が入っていないか、玄関先で徹底的に検査して、安全なものだけを通す「優秀なセキュリティガードマン」を雇うイメージです。
その代表格が、[DOMPurify](https://github.com/cure53/dompurify) です。
なぜDOMPurifyなのか?
自分で「このタグは削除して、あのタグは残して…」とルールを書くと、必ずどこかで「抜け穴」が生まれます。DOMPurifyは、世界中のセキュリティ専門家が検証を重ねた「ホワイトリスト方式(安全と分かっているもの以外は全拒否)」を採用しているため、非常に信頼性が高いのです。
—
実践!DOMPurifyで安全な投稿画面を作る
それでは、実際にコードを書いてみましょう。まずはライブラリをインストールし、設定を行います。
// npm install dompurify
import DOMPurify from ‘dompurify’;
// ユーザーからの入力(危険なものを含む可能性がある!)
const dirtyInput = ‘
こんにちは! ‘;
// DOMPurifyで「消毒」する
// ここでホワイトリストを設定します
const cleanInput = DOMPurify.sanitize(dirtyInput, {
ALLOWED_TAGS: [‘b’, ‘i’, ‘em’, ‘strong’, ‘p’], // 許可するタグはこれだけ!
ALLOWED_ATTR: [] // 属性(onclickなど)は一切許可しない!
});
// 結果を表示
console.log(cleanInput);
// 出力結果:
こんにちは!
// →
コメント