SQLインジェクション入門:SQLiとは何か、攻撃を防ぐには?
2022年8月06日 • セキュリティ
SQLインジェクションとは
SQLインジェクション(SQLi)は、犯罪者が脆弱なウェブアプリケーションに対して悪意のあるSQL文を実行できる攻撃の一種です。攻撃者は、アプリケーションのセキュリティ対策を回避することで、顧客情報、個人データ、企業秘密などの機密データにアクセスできます。ここでは、SQLインジェクション、その仕組み、および攻撃を防ぐ方法について説明します。.
SQLインジェクション攻撃は、SQLデータベースを使用する任意のウェブサイトで発生する可能性があります。このタイプの攻撃により、攻撃者は重要なデータにアクセスできます。彼らは消費者情報、個人データ、企業秘密、知的財産を見ることができます。これは、OWASPによると、ウェブアプリケーションに対する最も深刻な攻撃の一つです。.
SQLインジェクションの種類

インバンドSQLi
インバンドSQLインジェクションは、攻撃者がクエリを送信し、受信するために同じチャネルを使用する攻撃です。インバンドとは、応答が同じ通信媒体を使用して取得されることを意味します。攻撃者の目的は、可能であれば、ウェブブラウザを使用して手動で攻撃を実行する際に、ウェブブラウザですぐに応答を得ることです。.
インバンドSQLインジェクションの例
攻撃者がインバンドSQLインジェクションを行う最も一般的な方法は、リクエストを変更して現在のユーザーの個人情報を見られるようにすることです。これは、リクエストの一部として送信される値を変更することで行えます。例えば、ステートメントがユーザーの名前を表示することになっていた場合、攻撃者はそれを変更して自分の名前を表示させることができます。.
SELECT * FROM users WHERE user_id LIKE 'current_user'
エラーベースSQLiとユニオンベースSQLiは、インバンドSQLインジェクションの最も頻繁な形態の2つです。.
エラーベースSQLi
エラーベースSQLi技法は、データベースサーバーのエラーメッセージを利用してデータベースの構造を発見するインバンドSQLインジェクションアプローチです。エラーベースSQLインジェクションは、インバンドSQLインジェクションの最も一般的なタイプです。.
エラーベースSQLiの例:
攻撃者が次の資格情報でログインしようとした場合:
ユーザー名: ' OR 'a'='aパスワード: 何でも
ステートメントが文法的に正しくないため、データベースはエラーを返します。エラーメッセージはデータベースに関する情報を明らかにし、攻撃者はそれを利用できます。.
ユニオンベースSQLi:
インバンドSQLインジェクションは、UNION演算子を使用して2つ以上のSELECTステートメントの出力を結合することで、ウェブサイトから情報を取得する方法です。.
ブラインドSQLインジェクション
ブラインドSQLインジェクションは、攻撃者がデータベースからの応答を得るために、真または偽の応答をもたらす質問をする攻撃です。攻撃者はエラーメッセージを使用して、特定のコードが使用されたときにアプリケーションが異なる応答をするかどうかを確認します。.
ハッカーがSQLインジェクションを使用すると、ウェブアプリケーションはSQLクエリの構文が間違っていることを示す重要なデータベース警告メッセージを表示する可能性があります。ブラインドSQLインジェクションは、データベースからデータを取得する方法を除いて、従来のSQLインジェクションと同じように機能します。データベースに攻撃者が利用できる十分な情報がない場合、攻撃者はデータを取得するために一連の質問をする必要があります。.
ブラインドSQLインジェクションは、ブラインドブールベースSQLiとブラインドタイムベースSQLiに分けられます。.
ブールベースブラインドSQLi
ブールベースブラインドSQLインジェクションは、攻撃者がデータベースからの応答を得るために、真または偽の応答をもたらす質問をする攻撃です。攻撃者はエラーメッセージを使用して、特定のコードが使用されたときにアプリケーションが異なる応答をするかどうかを確認します。.
ブールベースブラインドSQLiの例:
攻撃者がデータベースの種類を知りたい場合、次のステートメントを使用します:
SELECT * FROM users WHERE user_id LIKE 'current_user' and database() like '%type%'
データベースがMySQLの場合、出力は次のようになります:
SQL構文にエラーがあります。正しい構文を使用するために、MySQLサーバーバージョンに対応するマニュアルを確認してください。‘and database() like ‘%type%” の近くで
タイムベースブラインドSQLインジェクション
タイムベースブラインド攻撃は、クエリをより遅く実行させるコードを含むSQLコマンドをサーバーに送信する場合です。.
タイムベースブラインド攻撃は、アクセス時間に基づいてデータを抽出することを可能にします。このような攻撃は、ブラインドまたは推論注入攻撃として知られています。これは、攻撃者とデータベースの間でデータが流れないタイプの攻撃ですが、応答がないため、ブラインド注入攻撃とも呼ばれます。.
応答時間は、答えが正しいか間違っているかを示します。応答が否定的である場合、侵入者は別のリクエストを行います。この攻撃手法は、特に大規模なデータベースを攻撃する際に、ハッカーが各文字を個別に確認する必要があるため、遅いです。.
ブラインドSQLiの例
この例では、攻撃者はid=999のユーザーがデータベースに存在するかどうかを判断しようとします。これを行うために、次のステートメントを使用します:
IF(SUBSTRING((SELECT password FROM users WHERE user_id=999),0, LEN('secret'))='secret', SLEEP(30), 'false')
データベースにid 999のユーザーが存在し、そのパスワードがsecretである場合、アプリケーションは30秒間スリープします。ユーザーがデータベースに存在しない場合、アプリケーションはfalseを返します。.
アウトオブバンドSQLi
データを盗むことを望む人は、通常のサーバーと他のコンピュータ間の通信の一部ではない方法でデータベースサーバーにSQLコードを送信することがあります。これは、DNSまたはHTTPリクエストを介してサーバーに情報を送信することで行うことができます。.
アプリの応答は、データが返されるかどうか、データベースに問題があるかどうか、またはクエリの実行にどれくらい時間がかかるかに影響されません。アウトオブバンドは、ネットワークインタラクションでイベントを自由に発生させるために使用できます。注入された条件に応じて、これらは条件付きでアクティブ化され、1ビットずつ知識を得ることができます。.
データはまた、ネットワークインタラクションからのいくつかのネットワークプロトコルを介して漏れることもあります。視覚的には、ウェブアプリケーションからアプリのデータベースに送信されたリクエストを表しています。.
アウトオブバンドSQLiの例
この例では、攻撃者は特定のユーザーがデータベースに存在するかどうかを判断しようとします。これを行うために、次のステートメントを使用します:
SELECT user_id FROM users WHERE username='$username' AND password='$password' LIMIT 0,0 UNION SELECT NULL,'' INTO OUTFILE '/var/opt/databases/$filename.php'; --
ユーザーがデータベースに存在する場合、アプリケーションはそのユーザーIDを返します。ユーザーがデータベースに存在しない場合、アプリケーションはシステムコマンドを実行するために使用できるPHPコードを含むファイルを作成します。攻撃者はそのファイルを使用してサーバー上でコマンドを実行できます。.
SQLインジェクションを防ぐ方法
SQLインジェクション攻撃から保護する最良の方法は、入力検証、準備されたステートメント、およびパラメータ化されたクエリを使用することです。コードはユーザーの入力を直接使用してはなりません。開発者は、ログインフォームなどのウェブフォーム入力だけでなく、すべての入力をサニタイズする必要があります。疑わしいコードコンポーネントからはシングルクォートを排除する必要があります。また、ライブサイトでのデータベースの問題を隠して、誤ってそれらを明らかにしないようにすることも良い考えです。SQLインジェクションは、攻撃者が利用できるデータベースシステムに関する情報を提供する可能性があります。.
ウェブサイトに問題が見つかった場合は、すぐにオフラインにしてホスティングプロバイダーに連絡する必要があります。彼らは、サイトが侵害されているかどうかを判断し、問題を修正するために必要な手順を教えてくれます。その間に、すべてのウェブサイトのユーザーに問題を知らせ、できるだけ早くパスワードを変更するようにしてください。.
SQLインジェクションを回避するための予防策
プログラミング言語とデータベース設定でSQLインジェクションの脆弱性を回避する方法はいくつかあります。これらの技術は、XMLなどのほとんどのデータベースで使用できます。これらの技術を使用して、データベースをより安全にすることができます。.
1) 適切に構築されたストアドプロシージャの使用
初心者は、変数を使用してステートメントを作成する方法を学ぶことから始めるべきです。これは動的クエリを作成するよりも簡単で、理解しやすいです。パラメータ化されたクエリは、開発者がすべてのSQLコードを作成し、後で各パラメータを提供する方法です。この方法により、データベースはソースコードと情報を区別できます。.
準備されたステートメントは、誰かがSQL命令を与えようとしても、クエリの目的が変更されないようにするのに役立ちます。.
2) 許可リスト入力検証
SQLクエリは、データの特定の場所でバインド変数を使用します。例えば、Pythonを使用している場合、%sプレースホルダーを使用します。正規表現を使用して、各バインド変数に許可される文字に対してユーザー入力を許可リストと照合することができます。 JavaScriptを使用している場合、\wを使用して英数字とアンダースコア文字を一致させることができます。 許可リストは、誤検知を避けるためにできるだけ具体的であるべきです。.
例えば、米国の電話番号を探している場合、次の正規表現を使用します: /^\d{11}$/ これは、電話番号である可能性のある11桁の数字の文字列に一致します。誰かが「abcdef」のようなものを送信しようとした場合、それは一致せず、入力は無効になります。.
これにより、データが安全であることを確認できます。ユーザーパラメータではなくコードからの値を使用する必要がある場合でも、それは問題ありません!.
ただし、ユーザーパラメータ値が特定のテーブルおよび列名を対象としている場合、パラメータ値は対応するテーブルおよび列名にマッピングされ、未検証のユーザー入力がクエリに入らないようにする必要があります。
3) ホワイトリストの使用
悪い文字のブラックリストに基づいてユーザー入力をフィルタリングしないでください。特定のフィールドで予想される良い文字の許可リストを使用する方がはるかに効果的です。これにより、SQLインジェクション攻撃が始まる前に防ぐことができます。‘例えば、電話番号を期待している場合、入力フィールドには数字とダッシュのみを許可します。メールアドレスを期待している場合、メールアドレスで有効な文字のみを許可します。‘4) 最新のプラットフォームを使用する.
PHPは古いウェブ開発プラットフォームではSQLi保護を持っていません。利用可能なプログラミング環境、言語、および関連技術の最新のエディションを使用してください。この例では、PHPの代わりにPDOを使用してください。
5) 定期的にウェブアプリケーションをスキャンする.
SQLインジェクションは非常に見つけにくいことがあります。定期的にウェブアプリケーションの脆弱性をスキャンすることが重要です。
6) 最小特権の強制.
最小特権の原則は、ユーザーが仕事をするために必要な最小限のアクセスに制限するセキュリティ概念です。これには、ユーザーが持つアカウントの数とそのアカウントが持つ特権を制限することが含まれます。.
機能性の最小制限(LRF)は、ユーザーの権利、アカウント、およびコンピューティングプロセスを基本的で許容可能なタスクに必要なリソースにのみ制限する実践と概念です。これにより、ユーザーの権利やクリアランスレベルを最小限に抑えることができ、人々が効果的に仕事をするために重要です。
最小特権は、アプリケーション、システム、およびデバイスが特定のタスクを達成するために必要な権限のみを持つことを要求するセキュリティ原則です。この方法では、誰かが脆弱性を利用して損害を与えた場合の影響が制限されます。これは、ユーザーに必要以上の権限を与えることとは対照的であり、SQL攻撃で重大な損害を引き起こすリスクを増加させます。.
SQLインジェクション – よくある質問
最も一般的なSQLインジェクションは何ですか?.
インバンドSQLインジェクションは、最も一般的なSQLインジェクション攻撃のタイプです。攻撃者がペイロードを配信し、結果を収集するために同じ通信チャネルを使用できる場合に発生します。
SQLインジェクションの最良の防御は何ですか?.
SQLインジェクションに対する最良の防御は、パラメータ化されたクエリを使用することです。このタイプのクエリは、後で提供されるパラメータのプレースホルダー値を使用します。この方法により、データベースはソースコードと情報を区別できます。.
SQLインジェクションはどのように検出されますか?.
SQLインジェクションは、いくつかの方法で検出できます。一つの方法は、ウェブアプリケーションファイアウォール(WAF)を使用することです。WAFは、ウェブアプリケーションとインターネットの間に位置するハードウェアまたはソフトウェアです。悪意のある活動を検査し、SQLインジェクション攻撃をブロックできます。
セカンドオーダーSQLインジェクションは、攻撃者がウェブアプリケーションによって保存され、後で実行されるペイロードを注入できる場合に発生します。このタイプの攻撃は、攻撃者が保存されたペイロードの実行をトリガーする方法を持っている必要があるため、達成がより困難です。.
ブラインドSQLインジェクションは、攻撃者がペイロードの結果を直接見ることができない攻撃です。代わりに、真または偽のステートメントを使用してデータベースから情報を推測する必要があります。このタイプの攻撃は実行がより困難ですが、他のタイプのSQLインジェクションと同様に危険です。.
スタッククエリは、攻撃者がデータベースから情報を抽出するために複数のクエリを使用するSQLインジェクションの一種です。このタイプの攻撃は実行がより困難ですが、成功した場合は非常に危険です。.
エラーベースSQLインジェクションは、攻撃者がデータベースのエラーを利用してデータベースから情報を推測する攻撃です。この攻撃は実行がより困難ですが、成功した場合は非常に危険です。.
SQLiとは何かと攻撃を防ぐ方法 | セキュリティブリーフィング.
A stacked query is a type of SQL injection where the attacker uses multiple queries to extract information from the database. This type of attack is more challenging to execute but can be very dangerous if successful.
Error-based SQL injection is an attack where the attacker uses database errors to infer information from the database. This attack is more challenging to execute but can be very dangerous if successful.
セキュリティ
ガバメント・テクノロジー誌のシニア・スタッフ・ライター。以前はPYMNTSとThe Bay State Bannerに寄稿し、カーネギーメロン大学でクリエイティブ・ライティングの学士号を取得。ボストン郊外に拠点を置く。