誰かが SQL インジェクションを説明できますか? 脆弱性はどのように発生しますか? SQL が挿入されるポイントは正確にはどこですか?
9 に答える
誰かがSQLインジェクションを説明できますか?
SQL インジェクションは、一部のコンテンツを SQL クエリ文字列に挿入したときに発生し、その結果、意図しない方法でクエリの構文が変更されます。
悪意がある必要はありません。事故の可能性があります。しかし、偶発的な SQL インジェクションは、脆弱性よりもエラーになる可能性が高くなります。
有害なコンテンツはユーザーからのものである必要はありません。アプリケーションが任意のソースから取得したり、コードで生成したりするコンテンツである可能性があります。
脆弱性はどのように発生しますか?
攻撃者は、SQL 文字列に補間されることがわかっている値をアプリケーションに送信できるため、脆弱性につながる可能性があります。非常に巧妙であるため、クエリの結果を操作したり、データを読み取ったり、許可されるべきではないデータを変更したりすることさえできます。
PHP での例:
$password = $_POST['password'];
$id = $_POST['id'];
$sql = "UPDATE Accounts SET PASSWORD = '$password' WHERE account_id = $id";
ここで、攻撃者が POST リクエスト パラメータを " password=xyzzy
" と " id=account_id
" に設定すると、次の SQL が生成されます。
UPDATE Accounts SET PASSWORD = 'xyzzy' WHERE account_id = account_id
整数であると予想$id
していましたが、攻撃者は列の名前である文字列を選択しました。もちろん、すべての行で条件が true になっているため、攻撃者はすべてのアカウントにパスワードを設定しただけです。攻撃者は、特権ユーザーを含む、誰のアカウントにもログインできるようになりました。
SQL が挿入されるポイントは正確にはどこですか?
注入されたのは SQL ではなく、SQL 文字列に補間 (「注入」) されたコンテンツであるため、意図したものとは異なる種類のクエリが生成されます。私は動的コンテンツを検証せずに信頼し、結果の SQL クエリをやみくもに実行しました。そこからトラブルが始まります。
SQL インジェクションは、通常、データベースやデータベース アクセス ライブラリまたはフレームワークではなく、アプリケーション コードの障害です。
SQL インジェクションのほとんどのケースは、クエリ パラメーターを使用することで回避できます。PHP で SQL インジェクションを防ぐにはどうすればよいですか? を参照してください。例えば。
SQL インジェクションは、アプリケーションのユーザーがデータベース クエリの意味に影響を与えることができる場合に発生します。これは、ユーザー入力からの任意の文字列が連結されて、データベースに供給される SQL を作成するときによく発生します。たとえば、ユーザーのログインを処理するために使用される可能性のある次のコード (PHP のコードですが、どの言語でも同じことが言えます) があるとします。
$sql = "SELECT FROM users WHERE username='".$_GET['username']."' AND password='".$_GET['password']."'";
ユーザーが次のようなものを入力すると、害が生じます
administrator'; --
... ユーザー名の場合。適切なエンコードがないと、クエリは次のようになります。
SELECT * FROM users WHERE username='administrator'; -- AND password=''
ここでの問題は、ユーザー名の ' がユーザー名フィールドを閉じてから -- が SQL コメントを開始し、データベース サーバーが残りの文字列を無視することです。最終的な結果として、ユーザーはパスワードを知らなくても管理者としてログインできるようになりました。SQL Inection は、UPDATE、DELETE、または DROP クエリを実行するためにも使用でき、データベースに実際に損傷を与える可能性があります。
パラメータ化されたクエリを使用するか、言語/ツールキットのエスケープ関数 (PHP の mysql_real_escape_string() など) を適用することで、SQL インジェクションを防ぐことができます。
SQL インジェクションを理解すれば、この漫画の背後にある冗談がわかります。
SQL インジェクションとは、データであるはずのものが、不本意ながら SQL コードとして扱われることです。
たとえば、あなたがするなら
mysql_query("SELECT * FROM posts WHERE postid=$postid");
通常は、指定された id の投稿を取得しますが、それが$postid
string に設定されていると仮定します10; DROP TABLE posts --
。突然、送信している実際のクエリは
mysql_query("SELECT * FROM posts WHERE postid=10; DROP TABLE posts --");
悪意のあるユーザーのために投稿テーブル全体を失うことになるため、これはかなりの問題です。
これを防ぐ最も簡単な方法は、たとえばPDOやMySQLiを介して、準備済みステートメントを使用することです。
PDO での同等の例は次のようになります。
$statement = $db->prepare('SELECT * FROM posts WHERE postid = :postid');
$statement->bindValue(':postid', $postid);
$statement->execute();
これにより、データベース システムは、$postid がコードではなくデータとして扱われ、適切に処理されることを認識します。
この質問は StackOverflow で何度も回答されていますが、誰もが知っておくべき重要なトピックであるため、この質問を閉じるために投票するつもりはありません。
このトピックに関する私の過去の回答へのリンクは次のとおりです。
- SQL インジェクションとは何ですか?
- この関数を SQL インジェクションから保護するにはどうすればよいですか?
- Sqlインジェクションを防ぐのにパラメータは本当に十分ですか?
- SQL インジェクションは今日のリスクですか?
今月の MySQL カンファレンスでもプレゼンテーションを行いました。私のスライドはオンラインです。
SQL インジェクションは、悪意のあるユーザーが SQL を入力フィールドに入力して、サーバー上で SQL を実行しようとする場所です。
私が一番守っているアドバイスは、生の SQL をコードで作成するのではなく、パラメーター化されたストアド プロシージャを使用することです。
ストアド プロシージャのパラメーターは実行されないため、ほとんどの場合安全です。
この論文は、SQL インジェクション手法に関する非常に優れた読み物であることがわかりました (リンクは PDF です): Advanced SQL Injection In SQL Server Applications。
タイトルに「上級編」とありますが、SQLインジェクションの知識があまりなくても読みやすい内容です。
一般的な背景については、SQL インジェクションに関するウィキペディアの記事を参照してください。
要するに、SQL インジェクション攻撃は、データベース データの盗難と破壊のすべてに対して無防備になる可能性があります。システムに対して実行できることの正確な詳細は、システム自体の詳細によって異なります。
ユーザーからデータベースに入力を渡すときはいつでも、潜在的なインジェクション ポイントがあります。新しいプログラマーはユーザーからの入力を処理するリスクを理解していないことが多く、Web アプリケーションは、プログラムを見つけるとは思っていなかった非常に賢い人々によって攻撃されるため、Web アプリケーションはこの点で欠けていることがよくあります。
コード プロジェクトのこの記事を気に入っていただけると思います。)
概要
- 機密データを暗号化します。
- 必要最小限の権限を持つアカウントを使用してデータベースにアクセスします。
- 必要最小限の権限を持つアカウントを使用してデータベースをインストールします。
- データが有効であることを確認してください。
- コード レビューを実行して、二次攻撃の可能性を確認します。
- パラメータ化されたクエリを使用します。
- ストアド プロシージャを使用します。
- ストアド プロシージャ内のデータを再検証します。
- エラー メッセージが、アプリケーションまたはデータベースの内部アーキテクチャについて何も明らかにしていないことを確認してください。
SQL が挿入されるポイントは、アプリケーションがユーザーからの入力を受け入れる任意のポイントです。
これが Web アプリケーションにとって危険な脆弱性になるかどうかは、この入力が後で SQL クエリの一部として使用され、その型を適切にチェックし、必要に応じてエスケープするかどうかによって決まります。
適切なエスケープを行わないと、ユーザーによって「挿入」された一部の SQL コードが、単純な文字列や値ではなく、SQL コードとして SQL エンジンによって実行される可能性があります。