JavaScript Tips | セキュリティ:DOM Injectionを防止する

JavaScript JavaScript
スポンサーリンク
スポンサーリンク
  1. DOM Injectionを防止することは「画面を書き換える“権限”を外部入力に渡さない設計」です
  2. DOM Injectionが起きる典型的なパターンをまず知る
    1. 危険な例1:innerHTML にユーザー入力をそのまま入れる
    2. 危険な例2:URLパラメータをそのままHTMLに差し込む
  3. ステップ1:「外部から来た文字列はそのままHTMLにしない」という原則を持つ
  4. ステップ2:テキストは「HTMLエスケープ」してからDOMに入れる
    1. 安全なHTMLエスケープ関数
    2. 使用例
  5. ステップ3:可能な限り「textContent」を使う(最も簡単で安全な方法)
    1. 危険な書き方
    2. 安全な書き方
  6. ステップ4:「どうしてもHTMLを扱いたい場合」はサニタイズを挟む
    1. 使用例
  7. ステップ5:DOM Injectionを防ぐための「危険なAPIリスト」を頭に入れておく
    1. 特に注意すべきAPI
    2. 例:危険な書き方
    3. 安全な方針
  8. ステップ6:業務で使える「DOM Injection防止ユーティリティ」(まとめ版)
    1. 使用例
  9. ステップ7:DOMベースのフレームワークでも「危険な抜け道」を意識する
    1. Reactの dangerouslySetInnerHTML
    2. Vueの v-html
  10. ステップ8:DOM InjectionとXSSの関係を理解しておく(重要な深掘り)
  11. ステップ9:チームで共有するための「DOM操作ルール」をコードとドキュメントに刻む
    1. コードコメントで明示する
    2. レビュー時のチェックポイント
  12. まとめ:DOM Injectionを防止することは「画面を書き換える権限を、信頼できるコードだけに限定する設計」です

DOM Injectionを防止することは「画面を書き換える“権限”を外部入力に渡さない設計」です

業務システムでは、JavaScriptでDOM(画面の要素)を書き換える処理が日常的に使われます。

  • ユーザー名を画面に表示する
  • 検索結果を一覧として描画する
  • エラーメッセージを表示する
  • コメントやチャットメッセージを追加する

このとき、外部から来た文字列をそのままDOMに差し込むと、 「DOM Injection(DOMインジェクション)」という危険な状態になります。

DOM Injectionは、 「ユーザー入力やURLパラメータなどを通じて、攻撃者が任意のHTMLやJavaScriptを画面に注入できてしまう状態」です。

ここでは、初心者向けに、 「何が危険なのか」→「どこで起きるのか」→「どう防ぐのか」→「実務で使えるユーティリティ」 という流れでステップバイステップで解説していきます。

DOM Injectionが起きる典型的なパターンをまず知る

危険な例1:innerHTML にユーザー入力をそのまま入れる

const name = getUserInputName(); // ユーザー入力
document.getElementById("user-name").innerHTML = name; // 危険
JavaScript

攻撃者が次のような文字列を入力するとします。

<script>alert('XSS');</script>

すると、画面には文字列としてではなく、 実際の <script> タグとして挿入され、JavaScriptが実行されてしまいます。

危険な例2:URLパラメータをそのままHTMLに差し込む

const params = new URLSearchParams(location.search);
const message = params.get("msg");
document.getElementById("message").innerHTML = message; // 危険
JavaScript

攻撃者は次のようなURLを作れます。

https://example.com/page?msg=<img src=x onerror=alert('XSS')>

これを開くと、 <img src=x onerror=...> がそのままDOMに注入され、 onerror に書かれたJavaScriptが実行されます。

これがDOM Injectionです。

タイトルとURLをコピーしました