LASSIC Media らしくメディア
SQLインジェクションとは|仕組みと基本の対策
システムのセキュリティに関する話題で、「SQLインジェクション対策はできていますか」「脆弱性診断でSQLインジェクションの指摘がありました」といった言葉を耳にしたことはないでしょうか。SQLインジェクションは、Webシステムに対する代表的な攻撃手法の一つで、長年にわたり被害が報告され続けている、いわば古くて新しい脅威です。IT事業部でシステムの発注や運用に関わる立場であれば、名前は聞いたことがあっても、それが具体的に何を突く攻撃で、なぜ危険なのか、どう防ぐのかまでは説明しにくいかもしれません。とはいえ、その大まかな仕組みを理解しておくと、ベンダーの提案や脆弱性診断の報告を受けたときに、対策が妥当かどうかを判断する助けになるでしょう。本記事では、攻撃コードの書き方といった実践的な手順ではなく、SQLインジェクションとはそもそも何を突く攻撃なのか、なぜ起こるのか、どんな被害につながり、どう防ぐのかを、発注・運用の視点から順に整理します。専門的な用語をすべて覚える必要はありませんが、「入力を”命令”として実行させない」という対策の勘所をつかんでおくと、セキュリティの会話がぐっと理解しやすくなるはずです。
SQLインジェクションとは何か
SQLインジェクションとは、Webサイトの入力欄などを通じて、データベースへの命令文(SQL)を不正に紛れ込ませ、本来は許されていない操作をデータベースに実行させる攻撃です。「インジェクション(injection)」は「注入」を意味し、攻撃者が悪意ある命令を注入する、というイメージからこの名前が付いています。
もう少しかみ砕いてみましょう。多くのWebシステムは、利用者が入力した情報——たとえば検索キーワードやログインのID——を受け取り、それをもとにデータベースへ問い合わせを行う仕組みです。このとき、入力された文字をそのまま命令文の一部として組み立ててしまうと、攻撃者は入力欄に「ただの文字」ではなく「命令として解釈される文字列」を打ち込むことで、システムが意図していない問い合わせを実行させられます。いわば、受付で記入する用紙の氏名欄に、追加の指示書きを紛れ込ませ、受付係にそのまま実行させてしまうようなものです。
この攻撃が長く問題であり続けているのは、Webシステムとデータベースの組み合わせがごく一般的で、かつ「入力をそのまま命令に混ぜてしまう」という作り方が、気をつけないと生まれやすいためです。情報処理推進機構(IPA)も、届出の多い脆弱性として長年にわたり注意を促しています。次の章では、なぜこうしたことが起きるのかを、もう一歩踏み込んで見ていきましょう。
普段は意識されませんが、ECサイトの商品検索、会員サイトのログイン、問い合わせフォームなど、私たちが日常的に使うWebの機能の裏側では、たいていデータベースへの問い合わせが行われています。SQLインジェクションは、その「裏側への入り口」を突く攻撃だと捉えると、身近さと危うさが同時に見えてくるでしょう。
なぜ起こるのか(攻撃の仕組み)
SQLインジェクションが成立してしまう根っこには、「利用者の入力(データ)」と「データベースへの命令(SQL)」の区別があいまいになる、という問題があります。
Webシステムは、利用者の入力を受け取って命令文を組み立てます。このとき、入力された文字列を単純につなぎ合わせて命令文を作ると、入力の中に命令の切れ目や別の指示を表す記号が含まれていた場合、システムはそれを「データ」ではなく「命令の一部」として解釈してしまいます。すると、本来は「この条件に合うものを探す」だけのはずだった問い合わせが、「すべてを表示する」「この情報を書き換える」といった別の命令に変わってしまうのです。攻撃者は、この解釈のすきを突いて、狙った操作をデータベースに実行させます。次の図は、入力の扱い方によって、攻撃が成立する場合と防げる場合が分かれる様子を単純化して示したものです。
分かりやすい例が、ログイン画面です。通常は「入力されたIDとパスワードに一致する利用者がいるか」を問い合わせますが、パスワード欄に命令として解釈される文字列を入れられると、「パスワードが一致しなくても、条件全体が成立する」ように問い合わせをねじ曲げられることがあります。その結果、正しいパスワードを知らない相手が、正規の利用者としてログインできてしまう——これがなりすましの典型的な入り口です。誰でも触れられるログイン画面のような入力欄は、攻撃者にとって格好の狙い目になります。
ここで大切なのは、SQLインジェクションは特別に高度な技術というより、「入力の扱い方の不備」から生まれるという点です。逆にいえば、入力を最初から「命令ではなく、ただの値」として扱う仕組みにしておけば、多くの場合は根本から防げます。この考え方が、次章以降で触れる対策の中心になります。
この記事のポイント
- SQLインジェクションは、入力欄などから不正な命令を紛れ込ませ、データベースに意図しない操作をさせる攻撃です。
- 原因は、利用者の「入力(データ)」と「命令(SQL)」の区別があいまいになることにあります。
- プレースホルダなどで入力を「値」として扱えば、多くは根本から防げます。
どんな被害につながるのか
SQLインジェクションが成立すると、データベースが本来守るべき情報や機能が、攻撃者の手にさらされてしまいます。代表的な被害を挙げておきましょう。
一つ目は情報の漏えいです。データベースに保存された個人情報や取引情報などが、まとめて抜き取られてしまうおそれがあります。二つ目はデータの改ざん・削除です。保存されている内容を書き換えられたり、消されたりして、業務が成り立たなくなることがあります。三つ目は認証の回避(なりすまし)です。ログインの仕組みを突かれると、正しいパスワードを知らなくても、他人になりすまして侵入されるおそれがあります。さらに、これらを足がかりに、システムのより深い部分へ侵入を広げられる場合もあります。
共通しているのは、いずれも「情報を預かる立場としての信頼」を大きく損なう点です。個人情報の漏えいが起きれば、利用者への影響はもちろん、報告や対応、社会的な信用の低下など、事業への打撃は広範囲に及びます。SQLインジェクションが軽視できないのは、攻撃の入り口が「よくある入力欄」でありながら、被害が事業全体に波及しうるという、その落差の大きさにあるといえるでしょう。
とりわけ個人情報の漏えいは、影響が社内にとどまりません。個人情報保護法では、一定の要件に当てはまる漏えいが起きた場合、個人情報保護委員会への報告や、本人への通知が求められます。対応にかかる労力や費用、公表による信用への影響まで含めると、事後の負担は大きくなりがちです。だからこそ、入り口の一つであるSQLインジェクションを作り込まないことが、めぐりめぐって事業を守り、余計なコストを抑えることにつながります。
基本の対策
幸い、SQLインジェクションには有効性が広く知られた対策があります。要点を整理しておきましょう。
| 対策 | 考え方 |
|---|---|
| プレースホルダ(バインド機構) | 最も基本かつ効果の高い対策。命令文の「型」を先に決め、入力は後から「値」としてはめ込むことで、入力が命令として解釈されないようにします。IPAも根本的対策として推奨しています。 |
| 入力値の検証 | 想定する形式(数字だけ、文字数の上限など)に沿っているかを確認し、外れた入力をはじきます。プレースホルダを補う位置づけで、単独に頼り切るものではありません。 |
| エラー表示の抑制 | データベースのエラー内容を利用者にそのまま見せないようにします。エラーは攻撃者に内部構造のヒントを与えるため、外向けには簡潔なメッセージにとどめます。 |
| 権限の最小化 | システムがデータベースへ接続する際の権限を、必要な範囲に絞ります。万一侵入されても、できる操作を限定し、被害を抑える考え方です。 |
| WAFの活用 | 不審な通信を入り口で検知・遮断する仕組み。根本対策を補う多層防御の一枚で、これだけに頼るのではなく、プログラム側の対策と組み合わせます。 |
中心になるのは、あくまでプレースホルダによって入力を「値」として扱うという根本対策です。ほかの対策は、それを補い、被害を広げないための多層的な守りと位置づけると整理しやすくなります。「WAFを入れたから大丈夫」「入力チェックをしているから問題ない」といった単独の対策への過信は、かえって危ういものです。複数の対策を重ね、根本の作り込みを土台に据える——この考え方が、SQLインジェクションへの向き合い方の基本になります。
発注・運用で意識したい観点
SQLインジェクションは、開発の作り込みに関わる問題ですが、発注や運用の立場でも押さえておきたい観点があります。
第一に、対策方針の確認です。開発を委託する際に、SQLインジェクションを含む代表的な脆弱性への対策方針を、提案や仕様の中で確認しておくと後がスムーズになります。とりわけ「入力を値として扱う作り(プレースホルダ)を基本にしているか」は、素朴ながら核心を突く問いです。第二に、脆弱性診断の活用です。リリース前や定期的なタイミングで、専門的な脆弱性診断を受けると、作り込みの不備を早い段階で見つけられます。診断で指摘が出た場合は、どの対策で、いつまでに直すのかを、あわせて確認しておくと落ち着いて運用できます。
第三に、既存システムの棚卸しです。古くから稼働しているシステムほど、当時の作り方のまま対策が手薄になっている場合があります。すでに動いているシステムについても、対策状況を一度確認しておくと、思わぬリスクの早期発見につながります。第四に、設計・実装への一貫した組み込みです。対策は後から付け足すより、要件定義や設計の段階から前提として組み込むほうが、確実で費用も抑えやすくなります。なお本記事は攻撃手法の実践的な手順ではなく、SQLインジェクションという脅威の考え方と、発注・運用で押さえたい観点に焦点を当てているものです。個別の対策の実装や診断は、実績のあるベンダーや専門機関への相談が別途必要になります。
まとめ
- SQLインジェクションは、入力欄などから不正な命令を紛れ込ませ、データベースに意図しない操作をさせる代表的な攻撃です。
- 原因は、利用者の「入力(データ)」と「命令(SQL)」の区別があいまいになることにあります。
- 被害は、情報漏えい・データ改ざん・なりすましなど、事業全体に波及しうる重大なものです。
- 根本対策は、プレースホルダで入力を「値」として扱うことで、これを土台に据えます。
- 入力値の検証・エラー抑制・権限の最小化・WAFは、根本対策を補う多層的な守りです。
- 発注・運用では、対策方針の確認・脆弱性診断・既存システムの棚卸し・設計段階からの組み込みを意識すると安定します。
- 本記事は攻撃手法の手順ではなく、脅威の考え方と発注・運用の観点の整理を狙いとしています。
よくある質問
WAFを導入すればSQLインジェクション対策は十分ですか。
WAFは有効な備えの一つですが、それだけで十分とはいえません。WAFは不審な通信を入り口で検知・遮断する多層防御の一枚であり、巧妙な攻撃をすり抜ける可能性も残ります。根本的な対策は、プログラム側で入力を「値」として扱うプレースホルダの利用です。WAFはこの根本対策を補う位置づけと考え、プログラム側の作り込みと組み合わせて多層で守るのが基本になります。「WAFを入れたから大丈夫」という単独の対策への過信は避けるのが望ましいでしょう。
プレースホルダとは何ですか。なぜ有効なのですか。
プレースホルダ(バインド機構)とは、データベースへの命令文の「型」を先に決めておき、利用者の入力は後から「値」としてはめ込む作り方です。入力が命令の一部としてではなく、あくまで値として扱われるため、入力に命令のような文字列が含まれていても、SQLの構造が書き換わりません。これにより、SQLインジェクションの多くを根本から防げるのです。多くの開発言語やデータベースに標準的な仕組みとして備わっており、情報処理推進機構(IPA)も根本的対策として推奨しています。
入力値のチェックだけでは対策になりませんか。
入力値の検証は有用ですが、それだけに頼り切るのは避けるのが無難です。想定する形式に沿わない入力をはじくことは、余計なデータの流入を防ぐうえで役立ちます。ただし、あらゆる攻撃パターンを入力チェックだけで漏れなく防ぐのは難しく、抜け道が残りがちになります。あくまで根本対策であるプレースホルダを土台に据え、入力値の検証はそれを補う一枚として組み合わせる、という位置づけが適切でしょう。守りは一つの手段に頼らず、重ねることが大切です。
古くから動いているシステムも心配すべきですか。
確認しておくことをおすすめします。長く稼働しているシステムほど、開発当時の作り方のまま、現在の観点では対策が手薄になりがちです。稼働中で目立った不具合がないと後回しにされがちですが、SQLインジェクションは表面上は正常に見えても内部に弱点が潜むことがあります。すでに動いているシステムについても、対策状況を一度棚卸しし、必要に応じて脆弱性診断を受けておくと、思わぬリスクの早期発見につながります。
著者:テレリモ総研編集部 鈴木 亮佑
LASSICでは、国内ニアショア開発体制を活かし、SQLインジェクションをはじめとする脆弱性を作り込まないための設計・実装から、プレースホルダを基本とした作り込み、既存システムの対策状況の確認、脆弱性診断を踏まえた改修までを一貫して支援する体制です。診断で指摘を受けたが対応の優先順位に迷う、古いシステムのリスクが気になるといった課題の見直しについてもご相談いただけます。要件定義の段階から実装、テスト、リリース後の運用・保守まで、工程を分けずに任せられる点も強みでしょう。セキュリティの作り込みに不安がある段階からでも、ご相談ください。
ご不明な点はお問い合わせフォームからもご連絡いただけます。