掲示板、コメント欄、プロフィール入力、レビュー投稿。ユーザーが文字を入力して、それが他の人にも表示されるサイトは身の回りにたくさんあります。こうした「誰でも書き込める場所」には、作り手が気をつけないと成立してしまう代表的な穴が潜んでいます。

その一つが、個人開発で見るべきセキュリティ・非機能要件でも名前だけ挙げたXSS(クロスサイトスクリプティング)です。名前は長くて難しそうですが、仕組みを分解すると「なるほど、だから危ないのか」と腑に落ちます。この記事では、XSSとは何か、なぜ起こるのか、何が危ないのか、そしてどう防ぐのかを、順番にやさしくたどっていきます。

結論:XSSは他人のブラウザで悪意あるプログラムを動かされる穴

先に結論をお伝えします。XSS(クロスサイトスクリプティング)とは、攻撃者が用意した悪意のあるプログラムを、そのサイトを見た別のユーザーのブラウザ上で動かしてしまう脆弱性のことです。

ここでのプログラムとは、ブラウザの中で動く小さな命令(スクリプトと呼びます)のことです。本来このスクリプトは、サイトを作った人が意図して置くものです。ところがXSSでは、攻撃者が仕込んだスクリプトが、まるでそのサイトが正規に用意したものであるかのように、閲覧者の画面で動いてしまいます。動く場所が「他人のブラウザ」だという点が、この穴のこわいところです。

なぜ起こるのか:入力をそのまま画面に出してしまう

XSSが成立する原因は、ほとんどの場合たった一つです。ユーザーが入力した内容を、無害化せずにそのままページに表示してしまうこと。これに尽きます。

たとえば掲示板を思い浮かべてください。ふつうの人は「はじめまして」といった文章を書き込みます。ところが悪意のある人は、そこに文章ではなく、ブラウザへの命令であるスクリプトのタグを書き込みます。サイト側がその書き込みを「ただの文字」として扱わず、命令として画面に組み込んでしまうと、書かれた命令がコードとして動き出してしまうのです。

ムチオ
ムチオ
えっ、コメント欄に書いた文字が、命令として動いちゃうことがあるの?
ルミナ
ルミナ
はい。ブラウザは受け取った内容を、文章なのか命令なのか、見た目だけでは区別できません。サイト側が「これは表示するだけの文字ですよ」と伝えないと、命令として解釈してしまう場合があるのです。

つまり問題は、攻撃者が賢いというより、サイトが入力を無防備なまま画面に流し込んでいることにあります。だから守り方も、この「そのまま出す」をやめることに向かいます。

何が危ないのか:Cookieやセッションを盗まれる

では、他人のブラウザでスクリプトが動くと、具体的に何が起きるのでしょうか。代表的な被害を挙げます。

  • Cookieやセッション情報を盗まれる。ログイン状態を保つために使われる情報が抜き取られ、攻撃者があなたになりすましてログインできてしまうことがあります。Cookieやセッションが何なのかは、Cookieとはログイン機能の仕組みで噛み砕いています。
  • 偽の入力フォームを表示される。本物そっくりの偽ログイン欄を画面に差し込み、入力したパスワードを盗む、といった使われ方もあります。
  • 意図しない操作をさせられる。閲覧者のブラウザを操って、本人が押したつもりのない操作を裏で実行させることもあります。
ムチオ
ムチオ
なりすましでログインされるって…見てただけの人が被害にあうの?こわいよ。
ルミナ
ルミナ
そこがXSSの重い点です。穴があるのはサイト側なのに、被害を受けるのはそのサイトを信じて見に来た利用者です。だから作り手が防ぐしかないのです。

種類をざっくり:反射型と格納型

XSSにはいくつか型があります。用語として軽く知っておくと、対策の話が入りやすくなります。

  • 反射型。攻撃者が仕込んだ内容が、その場で画面に跳ね返って表示される形です。細工したリンクを踏ませて、その人だけを狙うイメージです。
  • 格納型。書き込んだ内容がサイトに保存され、あとからそのページを見た人みんなに表示される形です。掲示板やコメント欄がまさにこれで、一度仕込まれると被害が広がりやすい傾向があります。

細かい違いを覚える必要はありません。共通しているのは、どちらも「入力をそのまま出してしまう」ことが引き金だという点です。

基本的な防ぎ方:エスケープ・入力の検証・CSP

守り方の中心は、入力を命令として動かさせないことです。主な手立てを、やさしい言葉で並べます。

  1. 出力時にエスケープする。エスケープとは、命令として解釈されうる記号を、無害な「ただの文字」に置き換える処理のことです。これをしておくと、スクリプトのタグが書き込まれても、命令ではなく画面に表示されるだけの文字として扱われます。XSS対策の土台がこれです。
  2. 入力を検証する。フォームで受け取る内容に、想定の形(文字数や種類)のチェックをかけ、明らかにおかしなものは受け付けない、あるいは無害な形に整えます。
  3. CSPという仕組みを使う。CSP(コンテンツセキュリティポリシー)は、このサイトで動かしてよいスクリプトはここまで、とブラウザに宣言しておく仕組みです。仮にスクリプトが紛れ込んでも、許可していないものは動かさない、という二段目の防御になります。
ムチオ
ムチオ
やること多い…全部自分で書かないといけないの?
ルミナ
ルミナ
安心してください。最近のフレームワークの多くは、画面に文字を出すとき自動でエスケープしてくれます。標準の書き方をしている限り、基本的なXSSはかなり防げるようになっています。

裏を返すと、フレームワークの安全な仕組みをわざわざ回避して、入力をそのまま埋め込むような書き方をすると、この保護が外れてしまうことがあります。標準から外れる場面こそ、注意したいところです。

AI開発での注意:表示部分が無害化されているか確認する

生成AIに画面を作ってもらう場面が増えました。ここで気をつけたいのが、ユーザーの入力を画面に表示する部分です。

AIは動くコードを手早く出してくれますが、その表示部分がエスケープを通しているか、安全な仕組みに乗っているかまでは、こちらが意図を伝えないと保証されません。とくに「入力された内容をそのまま埋め込む」ような書き方を提案してきたときは、立ち止まる合図です。動いて見えても、無害化を飛ばしていれば穴になります。動くかどうかと、安全かどうかは別だという視点は、個人開発で見るべきセキュリティ・非機能要件でも通底しています。

次の一歩

XSSは、盗まれる情報の理解とセットにすると腑に落ちます。Cookieやセッションの役割を押さえたい方はCookieとはログイン機能の仕組みを、AIで作ったアプリ全体の守りを見たい方はAIで作ったアプリのサーバは安全かを、あわせて読むと視界が広がります。

まとめ

  • XSS(クロスサイトスクリプティング)は、攻撃者のスクリプトを他人のブラウザで動かしてしまう脆弱性。
  • 原因は、ユーザーの入力を無害化せずそのまま画面に表示してしまうこと。
  • 危険は、Cookieやセッションの盗難によるなりすまし、偽フォームの表示など。被害を受けるのは閲覧者。
  • 防ぎ方の土台は、出力時のエスケープ・入力の検証・CSP。フレームワークの標準機能でかなり防げる。

独学でつまずきやすいのは、知識そのものよりも「何をどの順番で学ぶか」です。セキュリティの用語はどれも入り組んで見えますが、あなたの作りたいものから逆算すれば、いま押さえるべき範囲は意外とはっきりします。その線引きを、1対1で一緒に整理することもできます。