ITの教科書検索
入門読了 約12分

SQLインジェクションとXSSの違い ― 仕組みと対策

SQLインジェクションは入力をデータベースが、XSSは利用者のブラウザが命令として実行してしまう攻撃です。防ぎ方の違いをログイン画面の図で試せます。

目次
  1. SQLインジェクションとXSSの違いは、入力が実行される場所
  2. 2つの違いを並べて比べる
  3. ログイン画面で、対策の有無を比べる
  4. SQLインジェクションの仕組み
  5. SQLインジェクションの対策:プレースホルダ
  6. XSSの仕組み
  7. XSSの対策:エスケープ
  8. XSSの追加の対策:HttpOnlyとCSP
  9. WAFでどこまで防げるか
  10. 練習問題
  11. 参考にした資料

SQLインジェクションとXSSの違いは、入力が実行される場所

SQLインジェクションとXSSの違いは、入力欄に入れた文字列を、誰が命令として実行してしまうかです。SQLインジェクションではサーバのデータベースが、XSS(クロスサイトスクリプティング)では利用者のブラウザが実行します。

ログイン画面や検索欄、掲示板のコメント欄のように、利用者の入力を受け取る画面ならどこでも起こりえます。どちらの攻撃も、データのつもりで受け取った入力が命令として読まれることで起きます。入力がSQL文に混ざればSQLインジェクション、Webページに混ざればXSSです。

実行する側が違うので、被害を受ける相手も変わります。SQLインジェクションで狙われるのは、データベースに保存された情報です。XSSで狙われるのは、そのページを見ている利用者です。

2つの違いを並べて比べる

Webアプリは、HTTPの要求で利用者から入力を受け取り、その入力を使ってSQL文やHTMLを作ります。2つの攻撃の違いは、この入力がどこに混ざるかです。

ブラウザ利用者のPCWebアプリサーバ上データベースSQL文を実行入力を送るHTMLに混ぜて返すSQL文に混ぜるここで実行されるXSS利用者が被害を受けるどちらも原因は入力をそのまま混ぜるここで実行されるSQLインジェクション保存データが被害を受ける
Webアプリが入力を混ぜる先で、実行される場所が決まります。SQL文に混ぜると、データベースが実行します。HTMLに混ぜて返すと、利用者のブラウザが実行します。図の中で、右の線はSQLインジェクションだけに、左下の線はXSSだけにあります。

SQL文に混ざった入力は、データベースで実行されます。HTMLに混ざった入力は、ブラウザで実行されます。混ざる先が違うので、対策も違います。

比べる点SQLインジェクションXSS
入力が混ざる先SQL文(データベースへの命令文)HTML(Webページの中身)
実行する側データベース利用者のブラウザ
被害を受けるものデータベースに保存された情報ページを見ている利用者
主な被害情報の閲覧、改ざん、消去、不正ログイン偽のページの表示、Cookieの取得
根本的な対策プレースホルダでSQL文を組み立てる出力するときにエスケープする
追加の対策エラーメッセージを出さない、データベースの権限を絞るHttpOnly属性、CSP

ログイン画面で、対策の有無を比べる

次の図は、ログイン画面を例に、入力が処理されるまでを3段階で示します。題材と実装を切り替えると、同じ段階で、対策の有無による違いを比べられます。

題材
実装
STEP 1 / 3
処理する場所:利用者のブラウザ
ユーザー名 
alice
パスワード 
' OR '1'='1
ステップ1:パスワード欄に、記号を含む文字列を入れる
ログイン画面のパスワード欄に、引用符と OR を含む文字列を入れて送ります。Webアプリは、この文字列をそのまま受け取ります。
入力が、Webアプリに届く

入力した文字列は、対策なしでは命令として読まれ、対策ありでは値や文字として扱われます。パスワードをそのまま照合する、説明用に単純にした例です。

SQLインジェクションの仕組み

Webアプリは、利用者の入力をもとにSQL文を組み立てます。SQL文とは、データベースへの命令文です。この組み立て方に問題があると、入力した文字列が命令の一部として読まれます。

原因は、入力を文字列としてSQL文につなぎ合わせる書き方です。入力に含まれる引用符が、文字列の終わりとして読まれると、その後ろが命令になります。前の図のステップ2がこの状態です。

情報処理推進機構(IPA)は、次のような被害を挙げています。非公開情報の閲覧、情報の改ざんや消去、認証を回避した不正ログインです。個人情報をデータベースに保存するサイトは、特に注意が必要です。

SQLインジェクションの対策:プレースホルダ

根本的な対策は、プレースホルダでSQL文を組み立てることです。SQL文の雛形には、値を入れる場所の記号だけを置きます。実際の値は、あとから機械的に割り当てます。

プレースホルダには、2つの方式があります。静的プレースホルダは、雛形をデータベースに先に渡し、値をデータベース側で割り当てます。動的プレースホルダは、アプリ側のライブラリが値をエスケープして、雛形にはめ込みます。

IPAは、どちらでも脆弱性を解消できると述べています。そのうえで、原理的に脆弱性の可能性がなくなる静的プレースホルダのほうが優れていると説明しています。静的プレースホルダは、SQLの規格では準備された文と呼ばれます。

テーブル名や並び順のように、プレースホルダにできない部分もあります。Webの安全性に取り組む団体OWASPは、この部分を許可した候補から選ばせるよう勧めています。入力は、そのまま使いません。入力の引用符を自分で置き換える方法は、データベースごとに違い、漏れやすくなります。そのため、OWASPは使わないよう強く勧めています。

保険として、被害を小さくする対策もあります。エラーメッセージをブラウザに表示しないこと、データベースのアカウントに必要最小限の権限だけを与えることです。この2つは、プレースホルダの代わりにはなりません。

XSSの仕組み

Webアプリの中には、利用者の入力をWebページに出力するものがあります。例は、検索語の表示や入力内容の確認画面、掲示板です。出力の仕方に問題があると、入力した文字列が、スクリプトとしてページに埋め込まれます。スクリプトとは、ブラウザの中で動くプログラムです。

ブラウザは、埋め込まれたスクリプトを、サイトから届いたページの一部として実行します。IPAの説明のとおり、影響はサイトではなく、ページを見ている利用者に及びます。被害には、本物のサイト上に偽のページが表示されることや、ブラウザに保存されたCookieを取得されることがあります。Cookieにセッションの情報が入っていると、利用者へのなりすましにつながります。Cookieとセッションの関係は、Cookieの記事にあります。

入力が届く経路で、XSSは大きく2種類に分けられます。反射型は、罠のリンクなどで送られた入力を、エラー表示や検索結果にそのまま映し返すものです。格納型は、掲示板のコメント欄のように、入力がサーバに保存されるものです。保存された入力は、そのページを開いた人に表示されます。前の図で扱ったのは、反射型です。

ほかに、ブラウザ内のJavaScriptが入力をページへ書き込むときに起きるDOMベースもあります。次の節からの対策は、サーバが入力を出力する場合に絞ります。スクリプトを動かさずに、ログイン中のブラウザに要求だけを送らせる攻撃はCSRFと呼びます。これは、XSSとは別の攻撃です。

XSSの対策:エスケープ

根本的な対策は、ページに出力する前に、特別な意味を持つ記号を別の表記に置き換えるエスケープです。置き換えた表記は、ブラウザが記号の文字として表示し、タグとしては読みません。

置き換える前の記号置き換えた後の表記
&&
<<
>>
""

これらの表記は、HTMLの本文に出力するときのものです。タグの属性値に出力するときは、属性値をダブルクォートで囲みます。記号を置き換える範囲は、出力する場所で変わります。

リンク先のURLを出力するときは、httpまたはhttpsで始まるものだけを許可します。「javascript:」で始まるURLからは、スクリプトが動く場合があるためです。

多くのWebフレームワークは、テンプレートに値を出力するときに、自動でエスケープします。ただし、エスケープを無効にする機能を使うと、この保護は外れます。

掲示板のように、HTMLの入力を許したいときは、エスケープするとタグまで文字になります。この場合は、危険な部分だけを取り除くサニタイズを使います。OWASPは、DOMPurifyのようなライブラリを勧めています。危険な文字列を自分で探して取り除く方法は、見落としやすく、IPAも単独では勧めていません。

XSSの追加の対策:HttpOnlyとCSP

エスケープを漏らした場合に備えて、被害を小さくする対策があります。

1つ目は、Cookieに付けるHttpOnly属性です。この属性を付けたCookieは、ページ内のスクリプトから読めません。スクリプトが実行されても、そのCookieは盗まれません。ただし、Cookie以外の被害は残ります。

2つ目は、CSP(Content Security Policy)です。サーバがHTTPレスポンスヘッダで、読み込んでよいスクリプトの出どころをブラウザに伝えます。許可していない出どころのスクリプトは、読み込まれません。ページの中に直接書かれたスクリプトも、許可しない設定にできます。

OWASPは、CSPを主な防御にせず、追加の層として使うよう勧めています。設定を誤りやすく、許可の仕方によっては、対策にならないためです。

WAFでどこまで防げるか

WAFは、Webアプリへの通信の中身を検査し、攻撃のパターンを遮断するファイアウォールです。SQLインジェクションやXSSの通信を、アプリの手前で止められます。仕組みはファイアウォールの記事で説明しています。誤検知や置き場所は、WAFの記事を読むと分かります。

ただし、WAFが見つけられるのは、既知の攻撃のパターンです。OWASPによると、新しい回避方法が定期的に見つかるので、WAFは当てになりません。脆弱性の根本原因にも対処しないと述べています。Webに限らず通信の中の攻撃を探す仕組みとの違いは、IDSとIPSの違いの記事で比べています。

そのため、WAFはプレースホルダやエスケープの代わりにはなりません。アプリ側の対策に加える層として使います。リバースプロキシと組み合わせる形は、プロキシの記事にあります。クラウドのWAFの例は、AWS WAFとShieldの記事にあります。

練習問題(全7問)

Q1入力された文字列がSQL文の一部として扱われ、データベースで実行されてしまう攻撃はどれ?
Q2XSSで、埋め込まれたスクリプトが実行される場所はどれ?
Q3SQLインジェクションへの根本的な対策として最も適切なものはどれ?
Q4エスケープ処理で、「<」はどのように置き換える?
Q5Cookieに付けるHttpOnly属性の効果として正しいものはどれ?
Q6WAFを導入したWebサイトについて、正しい説明はどれ?
Q7利用者が入力したURLを、リンク先として出力するサイトがある。XSS対策として適切なものはどれ?

選んでから「採点する」を押すと、解説つきで答え合わせができます。

参考にした資料

関連記事

おすすめの本 PR

セキュリティとデータベースは、基本情報技術者試験の対策本でまとめて学べます。

目的別の本の選び方を見る

セキュリティの記事を続けて読む

セキュリティ 全37本中9本目