こんにちは。セキュリティの最前線で、日々「どうすればシステムをより堅牢にできるか」を考えているエンジニアです。
今日は、現代のWeb開発で避けては通れない「JavaScriptのテンプレートリテラル」と、そこに潜む「XSS(クロスサイトスクリプティング)」という泥棒についてお話しします。
「テンプレートリテラルって便利だよね!」と使っているその裏側で、実は家の鍵をかけ忘れている可能性があるとしたら……少しヒヤッとしますよね。一緒に一歩ずつ、安全な書き方を学んでいきましょう。
—
1. テンプレートリテラルは「魔法の箱」?
最近のJavaScript(ES6以降)では、バッククォート( )で囲むテンプレートリテラルが非常に人気です。${変数名}と書くだけで、簡単に文字列の中に変数を埋め込めるので、コードがスッキリしますよね。
しかし、この「便利さ」がセキュリティの盲点になることがあります。
泥棒の侵入経路:XSSとは
WebにおけるXSSとは、「悪意のあるプログラム(スクリプト)を、あなたのサイトの一部として実行させる攻撃」のことです。
これを身近な例で例えてみましょう。
あなたは大切なメモ帳(Webページ)に、誰かから預かったメッセージ(ユーザー入力データ)をそのまま書き込んでいるとします。もし、その預かり主が「このメモを読んだ人は、全員私の靴を舐めろ!」という命令をメモに混ぜていたらどうでしょう?
ブラウザ(メモを読み上げる人)は、それが悪意ある命令だとは知らず、忠実にその命令を実行してしまいます。これがXSSの仕組みです。
—
2. テンプレートリテラルが引き起こす「うっかり」
例えば、ユーザーの名前を表示するこんなコードを書いていないでしょうか。
const userName = ““;
// 本来ならユーザー名が入るはずの場所に、悪意のあるタグが混入!
// 危険なテンプレートリテラルの使い方
const welcomeMessage = こんにちは、${userName}さん!;
// 画面にそのまま反映させると…
document.body.innerHTML = welcomeMessage;
このコードを実行すると、ブラウザは「imgタグの画像読み込みに失敗したから、代わりにalertを実行しよう!」と判断し、攻撃が成功してしまいます。テンプレートリテラルは「中身をそのまま文字列として展開する」という性質があるため、「中身が何であるか」を確認せずに実行してしまうのが最大のリスクなのです。
—
3. 「エスケープ処理」という名の防犯対策
では、どうすれば防げるのでしょうか。ここで登場するのが「エスケープ処理」です。
エスケープとは、「特殊な意味を持つ記号を、ただの文字として扱うように変換する」ことです。泥棒が使おうとする「鍵開けツール(< や > や ")」を、「ただの金属の塊(記号)」に変えてしまうイメージですね。
安全な実装例:DOMのプロパティを使い分ける
一番簡単で効果的な対策は、innerHTMLを使わず、textContentを使うことです。
// 良い例:textContentを使うと、中身を「文字列」としてしか扱わない
const userElement = document.createElement('div');
userElement.textContent = userName; // ここでHTMLタグが「ただの文字」に変換される
document.body.appendChild(userElement);
こうすれば、たとえ悪意のあるタグが入力されても、ブラウザはそれを「実行するプログラム」ではなく「画面に表示するだけのただの文字」として扱うため、泥棒は何もできなくなります。
---
4. プロの現場で使う「防犯ヘッダー」
開発者がどれだけ気をつけていても、人間はミスをするものです。そんな時の「最後の砦」が、CSP(コンテンツ・セキュリティ・ポリシー)というHTTPレスポンスヘッダーです。
これは、「このサイトで動かしていいプログラムは、信頼できるものだけだよ!」とブラウザに事前に伝えておく「防犯ルールブック」のようなものです。
サーバーの設定で、以下のように送出します。
信頼できるソース(自サイトなど)からのスクリプト実行のみを許可する設定
Content-Security-Policy: default-src 'self'; script-src 'self';
これを入れておけば、万が一コードのどこかで「うっかり」ミスがあっても、外部から持ち込まれた怪しいスクリプトの実行をブラウザが遮断してくれます。まさに、玄関の鍵を二重ロックにするような安心感ですね。
---
最後に:セキュリティは「疑うこと」から始まる
セキュリティ対策において最も重要なのは、「ユーザーが入力するものすべてを、最初は泥棒かもしれないと疑うこと」です。
1. テンプレートリテラルでHTMLを組み立てない(innerHTMLは極力避ける)。
2. 表示するときは必ずエスケープする(textContentを使う)。
3. CSPでブラウザに守ってもらう。
最初は難しく感じるかもしれませんが、これらを意識するだけで、あなたの作るアプリケーションの安全性は劇的に向上します。まずは、今書いているコードで「ユーザーの入力値がどこに流れているか」を追ってみることから始めてみてください。
安全なコードを書くことは、ユーザーの信頼を守ることそのものです。一緒に、もっと強くて安全なWebを作っていきましょう!
コメント