「便利だから」で済ませてない?Vue.jsの v-html が招く「招かれざる客」の正体
こんにちは。現場で泥臭いインシデント対応を繰り返していると、ふと思うことがあります。「なぜ、あんなに便利な道具が、時には凶器に変わってしまうんだろう」と。
今回は、Vue.jsを使っている開発者なら一度は目にしたことがあるはずの v-html ディレクティブについてお話しします。「これを使えばHTMLをそのまま表示できる!最高!」と喜んでいるその裏で、実はあなたのWebサイトが「泥棒に玄関の鍵を預けている」ような状態になっているかもしれません。
難しい専門用語はなるべく抜きにして、一緒に紐解いていきましょう。
—
1. v-html は「玄関のドアを全開にする」のと同じ
Vue.jsには、文字列をそのままHTMLとしてブラウザに流し込む v-html という機能があります。一見すると、ブログの本文を表示したり、リッチなテキストを表示したりするのに便利ですよね。
しかし、セキュリティの視点から見ると、これは「見ず知らずの人に、自宅の合鍵を渡して『好きなように家具を配置していいよ』と言っている」のと同じくらい危険な行為なんです。
攻撃のメカニズム:XSS(クロスサイト・スクリプティング)
もし、ユーザーが入力したコメントや名前を、何もチェックせずに v-html に流し込んだらどうなるでしょう? 悪意のある攻撃者は、そこにこんな「罠」を仕込みます。
ブラウザは「おっと、src に失敗したからエラーだ!じゃあ中身のJavaScriptを実行しなきゃ」と勘違いして、攻撃者のコードを勝手に動かしてしまいます。これがXSS(クロスサイト・スクリプティング)の基本です。
あなたのサイトを見ている一般ユーザーの「ログイン情報」や「セッションデータ」が、裏でこっそり攻撃者に送信されてしまう……そんな悪夢のようなシナリオが、たった一行のコードで現実のものになるんです。
—
2. 泥棒を追い出す「優秀な警備員」DOMPurify
では、どうすればいいのか。「じゃあ v-html は絶対に使っちゃダメなの?」というと、そうではありません。要は、「中に入れる前に、持ち物検査をすればいい」のです。
ここで登場するのが、業界標準のサニタイズライブラリ「DOMPurify」です。こいつは、あなたのサイトの警備員として非常に優秀です。
DOMPurifyで持ち物検査をする実装例
まずは、プロジェクトにインストールしましょう。
npm install dompurify
そして、実際の使い方はこんな感じです。
import DOMPurify from ‘dompurify’;
// コンポーネント内のメソッドなどで使用します
export default {
props: [‘rawHtml’],
computed: {
// 汚いHTMLを一度「洗濯」してからVueに渡します
safeHtml() {
// DOMPurify.sanitize が持ち物検査役です
// 悪意のあるスクリプトはここで綺麗に削ぎ落とされます
return DOMPurify.sanitize(this.rawHtml);
}
}
}
テンプレート側はこう書きます。
これだけで、たとえ攻撃者が怪しいタグを送り込んできても、DOMPurifyが「これは危険物ですね、ポイッ」と排除してくれます。まるで、空港のセキュリティチェックゲートを通過させるようなものですね。
—
3. 「防犯」の意識をもう一段階上げるために
最後に、セキュリティのプロとして皆さんに一つだけ意識してほしいことがあります。それは、「ブラウザの防御機能を味方につける」ことです。
たとえプログラムで対策をしても、人間なのでうっかりミスはあります。その時の「最後の砦」として、HTTPレスポンスヘッダーに CSP (Content Security Policy) を設定しましょう。
これは、「このサイトでは、許可していない場所から持ってきたスクリプトは絶対に実行させないぞ!」という強力なルールブックをブラウザに渡す仕組みです。
サーバー設定(例: NginxやApacheなど)で追加するヘッダーのイメージ
Content-Security-Policy: default-src ‘self’; script-src ‘self’;
これを入れておけば、万が一 v-html のチェックをすり抜けるようなコードが紛れ込んでも、ブラウザが「あ、このスクリプトは許可されてないから実行しちゃダメだ」とブロックしてくれるようになります。
—
まとめ:セキュリティは「疑う」ことから始まる
新人のうちは、「動けばOK」という気持ちになりがちです。でも、「動くこと」と「安全であること」は、全く別の次元の話です。
1. ユーザーからの入力は、すべて「毒」かもしれないと疑う。
2. v-html を使うときは、必ず DOMPurify で洗濯する。
3. CSPヘッダーで、最後の防壁を固める。
この3つを心に留めておくだけで、あなたの書くコードは、今日から一段と「信頼できるもの」に変わります。
セキュリティは、一度やって終わりではありません。家の鍵を毎日かけるのと同じように、開発の現場でも日々のルーティンとして取り入れていきましょうね。皆さんが作るサービスが、誰かにとって安全な場所であり続けることを願っています!
コメント