こんにちは!フロントエンドの現場で長年コードと向き合っていると、技術の進化は本当に目まぐるしいものだと感じます。でも、どんなに時代が変わっても変わらない「鉄則」というものがいくつかあるんです。
今日はその中でも、「Webサイトの守りの要」とも言える、文字列のエスケープ処理についてお話しします。
「XSS(クロスサイトスクリプティング)」なんて聞くと、なんだか恐ろしい呪文のように聞こえますよね?でも大丈夫。仕組みさえ分かってしまえば、しっかりとした防御壁を築くことができます。一緒に見ていきましょう。
—
1. なぜ「エスケープ」が必要なの?
皆さんは、海外旅行で現地の言葉が通じないとき、身振り手振りや翻訳アプリを使いますよね。Webの世界でも同じことが起きています。
ユーザーが入力フォームに書いた文字をそのまま画面に表示してしまうと、ブラウザ(ChromeやSafariなど)は、その文字を「あ、これはHTMLの命令だな!」と勝手に勘違いしてしまうことがあるんです。
例えば、誰かが悪意を持って `` なんて入力したとします。これをそのまま画面に出すと、ブラウザは「おっ、命令だ!実行しなきゃ!」とプログラムを動かしてしまいます。これがXSS攻撃です。
悪い魔法を「ただの文字」に変える
エスケープ処理とは、「ブラウザが命令だと勘違いしそうな文字を、ただの記号として扱うための変装術」です。
- `<` を `<` に変える
- `>` を `>` に変える
こうすることで、ブラウザは「あ、これはHTMLの命令じゃなくて、ただの『小さいですよ』っていう記号なんだな」と判断して、安全に表示してくれるようになるんです。
—
2. 現場で使える「魔法の変換関数」を作ろう
JavaScriptには、文字列を操るための便利な道具(メソッド)が揃っています。これらを組み合わせて、最強の防護壁を作ってみましょう。
/
- ユーザー入力を安全な文字列に変換する関数
- これを通せば、悪意のあるプログラムもただの「文字」として表示されます。
/
function escapeHTML(str) {
// 文字列以外が来ても困らないように、まずは空文字にしておく優しさ
if (typeof str !== ‘string’) return ”;
return str
.replace(/&/g, ‘&’) // まず「&」を変換(これが一番重要!)
.replace(//g, ‘>’) // 「>」を変換
.replace(/”/g, ‘"’) // 「”」を変換
.replace(/’/g, ‘'’); // 「’」を変換
}
// 試しに使ってみましょう!
const userInput = ““;
const safeOutput = escapeHTML(userInput);
console.log(safeOutput);
// 出力結果: <script>alert('おめでとう!')</script>
なぜ `replace` を使うの?
`replace` は、まるで「辞書を持って文章をスキャンし、該当する単語を別の言葉に書き換える作業」をしてくれます。`/g` というのは「グローバル」の略で、「文章全体の中から、見つけたもの全部を書き換えてね!」という強力な指示なんです。
—
3. テンプレートリテラルで「守りながら組み立てる」
最近のJavaScriptでは、バッククォート(“ ` “)で囲む「テンプレートリテラル」が主流ですよね。この中に安全に変換した文字を流し込むのが、モダンなWeb制作の基本です。
const userName = ““; // 攻撃的な入力例
const safeName = escapeHTML(userName);
// テンプレートリテラルで安全にHTMLを組み立てる
const html = `
`;
// これを画面に挿入すれば、攻撃コードは実行されず、ただのテキストとして表示されます。
console.log(html);
—
最後に:初心者の方へ伝えたいこと
「こんなに細かく処理しなきゃいけないの?」と不安に思うかもしれません。でも、「ユーザーから受け取ったものは、たとえ友人であっても一度疑え(エスケープせよ)」というのは、世界中のエンジニアが現場で大切にしている格言のようなものです。
最初は難しく感じるかもしれませんが、この `escapeHTML` 関数を一つ作って手元に置いておくだけで、あなたの作るWebサイトはグッと安全でプロフェッショナルなものに変わります。
もし途中でつまずいても大丈夫。コードは何度書き直しても怒られませんから、まずはこのコードをエディタに貼って、コンソールで動きを眺めてみてくださいね。
皆さんのWeb開発が、今日も安全で楽しいものになりますように!応援しています。

コメント