JavaScript/TypeScript で HTML エスケープする方法

HTML エスケープとは、<, >, &, ", ' などの特殊文字を文字実体参照に変換し、XSS(クロスサイトスクリプティング)攻撃を防ぐ処理です。

ブラウザ環境での方法

DOM API を利用すると、ブラウザが自動的にエスケープ処理を行います。

function escapeHtml(str) {
  const div = document.createElement('div')
  div.textContent = str
  return div.innerHTML
}

escapeHtml('<script>alert("XSS")</script>')
// → '&lt;script&gt;alert("XSS")&lt;/script&gt;'

textContent に文字列を代入すると、ブラウザはその内容をプレーンテキストとして扱います。innerHTML で取り出すと、エスケープ済みの文字列が得られます。

純粋な文字列置換による方法

Node.js やブラウザ環境の両方で動作する汎用的な方法です。

function escapeHtml(str: string): string {
  return str
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#39;')
}

置換の順序が重要です。& を最初に変換しないと、後から変換した &lt; などの & が二重にエスケープされてしまいます。

ライブラリを使う方法

実務では既存のライブラリを使うのが安全です。

// lodash
import { escape } from 'lodash-es'
escape('<script>')  // → '&lt;script&gt;'

// he(HTML entities)
import he from 'he'
he.encode('<script>')  // → '&#x3C;script&#x3E;'

he は HTML5 仕様に準拠しており、エンコード・デコードの両方に対応しています。