1. ホーム
  2. 記事一覧
  3. 【必須セキュリティ】SQLインジェクションの仕組みと対策

2022.12.24

【必須セキュリティ】SQLインジェクションの仕組みと対策

こちらの記事では、Webアプリケーションの脆弱性を利用したサイバー攻撃の一つ、SQLインジェクションについて解説します。

SQLインジェクションとは

SQLインジェクションとは、Webアプリケーションの検索フォームや入力フォームなどを通じて、データベースに発行されるSQL文を開発者が意図しない形に変更し、データベース内の情報の不正取得や改ざんなどを行う攻撃、またはその脆弱性のことです。

SQLとはStructured Query Languageの略で、DBMS(データベース管理システム)上でデータやデータベースを制御するための言語のことです。

そしてSQL文とは、SQLを利用してデータベースに登録、読み込み、更新、削除などのCRUD処理を行う命令文のことを表します。

SQLインジェクションは、悪意を持った攻撃者が、このSQL文に本来の意図ではない不正なSQL文を注入(injection)することからSQLインジェクションと呼ばれ、SQLiとも表現されます。

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

ECサイトや会員登録を行うポータルサイトなどの多くは、データベースに顧客情報など様々な重要な情報を管理しています。SQLインジェクションはこのデータベースを標的に攻撃を実行します。

攻撃者は訪問したECサイトなどで、ユーザーIDやパスワードの入力フォーム、検索フォームなどを利用し不正なSQL文を入力します。

この時、入力フォームに不正なSQL文を受け付けてしまう脆弱性があった場合、入力された不正なSQL文がそのまま実行されてしまい、データベースに保存しているユーザーのIDやパスワード、顧客のクレジットカードの情報の漏洩や、認証回避による不正ログイン、場合によっては保管されていた重要な情報の削除など、様々な被害が発生してしまいます。

SQLインジェクションの種類

SQLインジェクションには複数の種類が存在し、それぞれの種類によって、攻撃者が実際に被害をもたらす攻撃を行うのか、それとも攻撃を行うための分析を行うのか、などの違いがあります。以下に代表的な種類をご紹介します。

インバンドSQLインジェクション

インバンドSQLインジェクションは、悪意のあるSQLを含んだリクエストを送信し、レスポンスの情報を元に脆弱性などの分析を行います。インバンドSQLインジェクションには以下の2つの種類が存在します。

  • エラーベースSQLインジェクション

    エラーベースSQLインジェクションは、意図的にWebアプリケーションにエラーメッセージを出力させ、そこから脆弱性やセキュリティの強度などの分析を行う攻撃のことです。直接被害を発生させるというよりは、発見した脆弱性などからどういった攻撃を行うかを考えるための攻撃と言えます。

  • UNIONインジェクション

    UNIONインジェクションは、SQLのUNION演算子を使って攻撃を行う手法です。UNION演算子を使うことで、複数のSELECT文の結果を一つに結合することができるため、攻撃が成立すると一度に大量の情報を取得することが可能になります。

ブラインドSQLインジェクション

ブラインドSQLインジェクションは、不正なSQL文を送信し、返ってきたレスポンスの違いを見ながら、データベースの情報(ユーザーの情報やテーブル名など)を盗み出す手法です。攻撃者はサブクエリなどを利用し、送信したSQL文のレスポンスを少しずつ分析して、攻撃対象のデータベースの情報を盗み出します。

このように、データベースに存在している情報がそのまま攻撃者に渡るわけではなく、徐々に攻撃者の元へ情報が渡っていきデータベースを解析されてしまうため、ブラインドSQLインジェクションと呼ばれています。

SQLインジェクションの被害

ECサイトやWebサイトなどのデータベースには、取り扱っている商品のデータだけではなく、取引を行っている顧客の情報などとても重要な情報が保存されている場合が多くあります。このデータベースをターゲットに攻撃を行うSQLインジェクションでは、どのような被害が考えられるでしょうか?

情報漏えい

SQLインジェクションの攻撃を受けてしまうと、WebサイトやECサイトを利用する特定のユーザーの情報が流出するだけではなく、複数のユーザーの情報が流出してしまう恐れがあります。

また、企業が管理している機密情報や顧客のクレジットカードの情報などが流出してしまうと、企業の信頼を大きく損なう事態に発展してしまうばかりではなく、今後のビジネスにも大きなダメージを受けることになりかねません。

データの改ざん

SQLインジェクションでは、データベースに保存している情報を盗み出すだけではなく、管理しているデータを改ざんされたり、データが破壊されてしまうなどの被害も考えられ、最悪の場合システムを利用できなくなるなどの問題が生じる可能性があります。

不正アクセス、システムの乗っ取り

SQLインジェクションの脆弱性が存在した場合、認証回避によりシステムに不正にログインされてしまい、ログインした利用者に許可されている全ての操作を不正に行われる可能性があります。

万が一サーバー自体が乗っ取られてしまった場合には、サーバーの設定が変更され、次の新たな攻撃への踏み台にされてしまうなどの被害が発生してしまうことも考えられます。

SQLインジェクションの対策

SQLインジェクションの攻撃を受けてしまう原因は、SQL文の一部が悪意ある攻撃者によって変更されてしまうことです。そのため、対策方法としてはSQL文が攻撃者によって変更されないようにする必要があります。

SQLインジェクションに対する対策として、IPA(独立行政法人 情報処理推進機構セキュリティセンター)では、以下にご紹介する内容が推奨されています。

プレースホルダによるSQL文の組み立て

プレースホルダとは日本語で「場所取り」という意味で、SQLでは変数などでユーザーからの入力された値を受け取る、パラメータの部分に埋め込んでおく「?」などの記号のことです。この「?」などのプレースホルダへ実際の値を割り当てることをバインドする、と表現することから、プレースホルダのことを別名「バインド変数」と呼ぶこともあります。

このプレースホルダは、パラメータのバインド処理をデータベースエンジン側で実行するのか、アプリケーション側のライブラリ内で実行するのかによって、静的プレースホルダ(Prepared Statement)動的プレースホルダの2つに分類されます。

  • 静的プレースホルダ(Prepared Statement)

    静的プレースホルダは、バインド処理をデータベースエンジン側で行います。プレースホルダのついたSQL文はそのままデータベースエンジンに送信され、コンパイルなどの実行準備が行われ、この時点でSQL文が確定します。SQL文が確定した後に、受け取った値をプレースホルダへ割り当ててSQL文を実行するため、不正なSQL文へ変更されてしまう可能性がなくなります

    そのため、原理的にSQLインジェクションの脆弱性が生じないとされています。

    参考:徳丸 浩 「体系的に学ぶ 安全なWebアプリケーションの作り方」、SB Creative

  • 動的プレースホルダ

    動的プレースホルダは、バインド処理をデータべースエンジン側ではなく、アプリケーションのライブラリ側で行います。SQLの呼び出しごとにパラメータをバインドしてからデータベースエンジンにSQL文を送信するため、実行効率は静的プレースホルダに劣るとされていますが、パラメータの値の埋め込みがライブラリで機械的に処理されることから、開発者のミスによるエスケープ漏れを防止できるとされています。

    ただし、動的プレースホルダは利用するライブラリに依存するため、ライブラリに脆弱性があるとSQLインジェクションを許してしまう可能性があることを理解しておく必要があります。

    参考:徳丸 浩 「体系的に学ぶ 安全なWebアプリケーションの作り方」、SB Creative

特殊文字のエスケープ処理の実施

エスケープ処理とは、プログラミングで使用される特別な意味を持つ文字や記号を、別の文字に置き換えたり削除するなどし、普通の文字として扱えるようにすることです。

SQLの標準規格では、シングルクォートやバックスラッシュがエスケープ処理の対象となります。例えば、文中で文字列の中にシングルクォートを使用したい場合には、以下のようにシングルクォートを二個並べるというルールがあります。

'O''Reilly' --SQL上のソースコード

O'Reilly --実際の文字列の値

このエスケープ処理が抜けてしまうと、この部分がSQLインジェクション脆弱性となり、本来のSQL文が悪意ある攻撃者によって意図しない形に変更されてしまい、SQLインジェクションの被害を受けてしまいます。

実際にエスケープ処理を行なっていない場合の例を以下に示します。

SELECT uid FROM users WHERE uid='ユーザID' AND pw='パスワード';

このSQL文では、ユーザIDとパスワードを入力パラメータとして受け取り、この2つをusersテーブルから検索します。そして、該当するレコードがあった場合にuidを返し、その後ログイン処理を行う仕組みになっているとします。

上記のSQL文では、シングルクォートのエスケープ処理を行なっていないため、ユーザIDの部分に’ OR 1=1--という文字列が入力された場合、以下のSQL文が組み立てられてしまいます。

SELECT uid FROM users WHERE uid='' OR 1=1--' AND pw='パスワード';

uidが空の場合でも、その後のOR 1=1の部分で必ず検索条件が真となり、そのあとのSQL文はコメントアウトされてしまうため、uidやパスワードを知らなくてもログインが可能となってしまうのです。

エスケープ処理を行う実装方法については、言語ごとに用意されているエスケープ関数を利用する、独自で作成した関数の利用、データベースエンジンから提供されているAPIを利用するなど複数の選択肢が存在するため、それぞれの環境に合わせた実装が必要になります。

SQLインジェクションの保険的対策

ここまでプレースホルダの利用、エスケープ処理についてご説明しました。以下では、加えて実施しておくと良い保険的対策についてご説明します。

保険的対策とは、根本的な対策に抜けがあった場合に攻撃の被害を軽減する対策のことを指します。

  • 詳細なエラーメッセージを表示させない

    SQLインジェクションでは、エラーベースSQLインジェクションのようにエラーメッセージを利用して攻撃を行うものがあることをご説明しました。エラーメッセージにデータベースの種類やエラーの原因、実行エラーを起こしたSQL文等の情報が含まれてしまうと、悪意ある攻撃者に情報を提供してしまうことになります。

    そのため、詳細なエラーメッセージを抑止することで、SQLインジェクションの被害にあいにくくすることができます。

  • データベースの権限設定を適切にする

    データベースユーザの権限を、アプリケーションの機能を実現するために必要最小限の権限に設定しておくことで、万が一SQLインジェクションの被害を受けても最小限にとどめられます。

    必要以上の権限を設定していた場合、データベースの中の全てのデータが漏えいしてしまう危険や、データの改ざん、削除などの被害を受けてしまうことになりかねません。

    データの読み出しの権限のみ必要であれば、読み出しのみの権限を与えるように適切に権限設定を行うことで、万が一SQLインジェクションの脆弱性が存在していても、被害を最小限にとどめることができます。

  • 入力値の検証(バリデーション)の実施

    バリデーションとは、入力された値が仕様に沿っているかを検証することです。入力された値がアプリケーションの要件に沿っているかを検証することで、SQLインジェクションの脆弱性対策に効果を発揮します。

    たとえば、郵便番号欄であれば数値のみを受け付け、それ以外の値の入力を制限することで、不正なSQL文が入力されても受け付けないようにすることができます。

まとめ

今回はSQLインジェクションについて解説しました。SQLインジェクションは、データベースをターゲットに行われる攻撃であり、被害を受けてしまうとデータベースに保存している情報の漏えい、改ざんが行われてしまいます。

アプリケーションを開発する際には、見栄えや使いやすさだけではなく、それぞれの開発環境に合わせてセキュリティについても気を配り、SQLインジェクションなどのサイバー攻撃への対策を行いましょう。

エンベーダー編集部

エンベーダーは、ITスクールRareTECHのインフラ学習教材として誕生しました。 「遊びながらインフラエンジニアへ」をコンセプトに、インフラへの学習ハードルを下げるツールとして運営されています。

RareTECH 無料体験授業開催中! オンラインにて実施中! Top10%のエンジニアになる秘訣を伝授します! RareTECH講師への質疑応答可

関連記事