SQLインジェクションを理解する

著者名の記号を正しく検索できることと、不正な命令を取り込まないことは、同じ「SQLの構造と値を分ける」設計につながります。具体的な検索例から、根本対策・権限・検証まで学びます。

この単元で学ぶこと

  • 入力が命令として解釈される原因を説明する
  • 処理する場所に合う根本対策を選ぶ
  • 補助対策の効果と限界を区別する
  • 事例から修正と確認の手順を組み立てる

本文解説

SQLと検索値の役割 SQLはデータベースへ検索や更新を依頼する言語です。たとえば著者で本を探す処理では、どの表のどの列を検索するかという命令と、利用者が入力した著者名という値があります。値を命令の文字列へ直接つなぐと、記号などがSQLの構文として扱われる危険が生じます。SQLインジェクションはこの境界の崩れを悪用する問題です。

正常な入力でも見える境界の問題 著者名 O'Neil にはアポストロフィが含まれます。これを独自に引用符で囲んで連結すると、文字列の区切りが崩れる実装があります。正常な人名を一律に禁止することが解決ではありません。著者名は最後まで一つの値として扱い、検索の命令構造とは分けます。

プレースホルダとバインド 検索の雛形を SELECT title FROM books WHERE author = ? とし、?へ著者名をバインドする方法があります。記号はDBライブラリで異なりますが、命令の構造と値を分ける考え方は共通です。教材用の表にAliceとBobだけがあるなら、文字列 Alice OR Bob を完全一致条件へバインドしても2人の検索にはならず、該当は0件です。ORも値の文字です。

値と構造を区別する 値用のプレースホルダは、列名やASC・DESCを任意のSQL構造へ変える機能ではありません。並び替えを許可する場合は、画面の選択値をサーバー上の固定の列名・順序へ対応付け、未知の値は拒否します。hidden項目やURLへ入れた値も利用者は変更できるため、そのままSQL断片として信用しません。

入力検証との役割分担 会員番号が正の整数という仕様なら、サーバー側で型・範囲を確認します。この業務入力検証とSQLの安全なバインドは両立します。HTML用エスケープをSQLへ流用したり、禁止語を少数列挙するだけで安全を保証したりしません。保存済みの取引先名でも別のSQLへ渡すときは値として扱います。

被害と権限 不正な検索は非公開データの読み出し、更新を伴う経路は改ざん等につながり得ます。被害は接続アカウントの権限や実装に依存します。検索だけに必要なアカウントへ不要な更新・削除権限を与えず、最小権限に絞ります。ただし参照権限でも情報漏えいは起こり得るため、権限縮小はバインドの代用ではありません。

補助対策の限界 詳細なSQLエラーは利用者へ返さず、運用に必要な記録は閲覧を制限して残します。WAFは攻撃の検知・遮断を助けますが、SQLの脆弱な組立てを放置する理由にはなりません。HTTPSは転送中の情報を守る仕組みで、受信後の入力がSQLとして解釈される問題は別に直します。

修正を確かめる 検索・更新・バッチ等で入力からSQLへ至る経路を確認します。ORMでも生SQLの連結や構造部分の無検証な取込みがあれば修正が必要です。正常な検索、記号を含む正当な値、仕様外の値を使い、期待結果・拒否処理・権限・エラー出力を確認します。一つの検知規則や画面だけで全経路の安全を断定しません。

図解

SQLの構造と値を分ける
値用のバインドは任意の列名やSQL断片を受け付ける機能ではない。

重要ポイント

  • SQLの命令構造と入力値を分離する。
  • 列名や並び順は許可した固定の構造へ対応付ける。
  • 最小権限・WAF・エラー制御は根本対策に重ねる。

間違えやすい点

  • HTMLエスケープをSQLのバインドの代用にしない。
  • HTTPS・ORM・hiddenという名前だけで安全としない。
  • 保存済みの値や参照専用権限も無条件に信用しない。

用語解説

SQLインジェクション
入力がSQLの構造として取り込まれる不備を悪用し、意図しないDB処理を行わせる攻撃。
プレースホルダ
SQLの雛形に設ける、値を割り当てる位置を示す記号。
バインド
プレースホルダへ実際の値を割り当てる操作。
許可リスト
受け付ける値や構造を明示し、それ以外を許可しない方式。

関連教材

参考資料

教材データに登録された参考リンクです。リンク先の内容や更新日は提供元でご確認ください。

確認問題の出題・採点や学習履歴の保存にはログインが必要です。