SQLインジェクションとは?初心者でも簡単にわかる対策方法

セキュリティ

SQLインジェクションとは?

SQLインジェクションとは、ウェブアプリケーションがデータベースとやり取りする際に、悪意のあるデータを入力されることで不正なSQL文が実行される攻撃手法です。これにより、攻撃者はデータベース内のデータを閲覧・改ざんしたり、アプリケーションを正常に動作させなくしたりします。

なぜSQLインジェクションが発生するのか?

SQLインジェクションが起きる主な原因は、入力値を適切に処理せずにSQL文としてそのまま使用することです。たとえば、以下のようなコードがあるとします

Python
query = f"SELECT * FROM users WHERE username = '{username}' AND password = '{password}'"

このコードでは、usernamepasswordにユーザーが入力した値がそのまま埋め込まれます。通常の入力であれば問題ありませんが、攻撃者が以下のような値を入力すると、問題が発生します。

攻撃の具体例

正常な入力の場合

  • ユーザー名: user123
  • パスワード: password123

生成されるSQL文は以下の通りです:

SQL
SELECT * FROM users WHERE username = 'user123' AND password = 'password123'

データベースはこの文を受け取り、正しいユーザー情報を返します。

SQLインジェクションの例

攻撃者が次のような値を入力した場合:

  • ユーザー名: admin' --
  • パスワード: (空欄)

生成されるSQL文は以下のようになります

SQL
SELECT * FROM users WHERE username = 'admin' --' AND password = ''

--はSQLでコメントを意味するため、それ以降の文は無視されます。この結果、以下のように解釈されます:

SQL
SELECT * FROM users WHERE username = 'admin'

これにより、パスワードの検証がスキップされ、攻撃者が「admin」としてログインできる状態になります。

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

SQLインジェクションを成功させた攻撃者は、さまざまな悪事を働くことが可能です。

  • 不正ログイン
    • 攻撃者は認証をバイパスして管理者としてログインできます。
  • データの漏洩
    • データベース内のすべてのデータを取得するSQL文を実行可能。
SQL
SELECT * FROM users
  • データの改ざん
    • データを削除したり、改ざんするSQL文を送信可能。
SQL
DELETE FROM users
  • システムの破壊
    • システムを正常に動作させなくするSQL文を埋め込むことも可能です。

SQLインジェクションを防ぐ方法

SQLインジェクションを防ぐためには、以下のような対策を講じる必要があります。

プリペアドステートメント(Prepared Statement)の使用

プリペアドステートメントは、SQL文とデータを分離することで、SQLインジェクションを防ぎます。たとえば、Pythonで以下のように記述します

SQL
query = "SELECT * FROM users WHERE username = %s AND password = %s"
cursor.execute(query, (username, password))

この方法では、ユーザー入力がデータとして扱われるため、攻撃者がどんな悪意のある値を入力してもSQL文として実行されません。

入力値のバリデーション

ユーザーが入力した値に問題がないかを確認します。たとえば、次のようなチェックを行います:

  • 許可された文字のみを使用する(例:正規表現)。
  • 特殊文字(', ", --, ;など)を除去またはエスケープする。

最低限の権限でデータベースを操作する

アプリケーションがデータベースを操作する際に使用するアカウントには、最低限の権限のみを与えます。たとえば、データの読み取り専用権限に制限すれば、データ削除やテーブルのドロップを防ぐことができます。

エラーメッセージの非公開

SQLエラーが画面に表示されると、攻撃者にとって有益な情報を与える可能性があります。以下のようなエラーメッセージをユーザーに見せないようにしましょう

SQL
You have an error in your SQL syntax...

代わりに、一般的なエラーメッセージ(例:「システムエラーが発生しました」)を表示します。

まとめ

SQLインジェクションは、システムの脆弱性を突いてデータベースを不正に操作する攻撃です。しかし、プリペアドステートメントの使用や入力値の適切な処理を行うことで、十分に防ぐことが可能です。

重要なのは、「ユーザーの入力を信じない」という基本方針を徹底することです。少しの注意で大きな被害を防ぐことができます。開発者として、このリスクを軽視せず、適切な対策を実施しましょう。

コメント

タイトルとURLをコピーしました