web-dev-qa-db-ja.com

SQLインジェクションの例に関する疑問、正確にはどのように機能しますか?

私はソフトウェア開発者であり、アプリケーションのセキュリティの研究を始めており、SQLインジェクションに関連する以下の疑問があります。

私はビデオコースをフォローしていますが、次の2つの例があります。

  1. 次のような安全でないSQLクエリがあります。

    txtSql = "SELECT * FROM Users WHERE UserId = " + txtUserId
    

    渡されたtxtUserIdの値が99 OR 1 = 1のようなものである場合、次のようなクエリを取得します

    SELECT * FROM Users WHERE UserId = 99 OR 1 = 1
    

    1 = 1は常にtrueであり、Users連結はtrueを返すため、次のクエリのようになるため、ORテーブルに含まれるレコードのリスト全体が返されます。

    SELECT * FROM Users WHERE TRUE
    

    レコードのリスト全体を返します。この推論は正しいですか?

  2. 次に、この2つ目のより洗練された例を示します。

    ユーザーログインフォーム(ユーザー名とパスワード)があります。このフォームの背後には、安全でないクエリ実装があります。

    sql = 'SELECT * FROM USERS WHERE Name = "' + uName + '" AND Pass = "' + uPass + '"'
    

    ユーザーがログインフォームに次のデータを挿入した場合:

    uName = " OR ""="
    uPass = " OR ""="
    

    結果のクエリは次のようになります。

    SELECT * FROM Users WHERE Name = "" OR ""="" AND Pass = "" OR ""=""
    

    だからそれはレコードを選択しています

    • Nameフィールドは空(​​ "")または"="に等しい(そして、空のユーザー名や "="のようなユーザー名を持つのはかなり奇妙なので、この条件は常にfalseでなければなりません)。

    • Passフィールドは空(​​ "")または"="に等しい(そして、空のパスワードや "="のようなパスワードを持つのはかなり奇妙なので、この条件は常にfalseでなければなりません)。

    したがって、次のような条件があります。

    WHERE FALSE AND FALSE
    

    そして、ここで私の疑問:FALSE AND FALSE = FALSE

このクエリがユーザーテーブルのレコードのリスト全体を返すと言うのはなぜですか?

ロジックを正しく理解していれば、2番目のクエリは次のように変換されます。

SELECT * FROM Users WHERE FALSE AND FALSE

私の推論の何が問題になっていますか?何が欠けていますか?

8
AndreaNobili

あなたは注射、特にこの部分を誤って読みました:

""=""

これは、Nameが等号かどうかをチェックするのではなく、空の文字列が空の文字列と等しいかどうかをチェックします。これは1=1と実質的に同じものであり(ここでは1=1も使用できた可能性があります)、したがってTRUEと同等です。したがって、この句:

Name = "" OR ""=""

Name="" OR 1=1およびName="" OR TRUEと同じ

そのようなことを誤解するのは簡単です。それ以外の場合はこれらの概念を明確に理解しているため、これで十分です。ただ、ペダントになるために、クエリは基本的に次のように要約されます。

WHERE Name="" OR TRUE AND Pass="" OR TRUE

次に何が起こるかは、優先順位によって異なりますが、おそらく問題ありません。あなたが使うことができるもう一つのトリックは、バックスラッシュでユーザー名を終わらせることですPassを一緒にクエリから削除してください(これはSQLのすべての種類で機能しないかもしれません)。 User=\Pass= OR 1=1 --(コメントで終わる)を挿入するとします。あなたはこのクエリで終わるでしょう:

SELECT * FROM USERS WHERE Name="\" AND Pass = " OR 1=1 --"

バックスラッシュのため、Name of " AND Pass =(何にも一致しない)が検索されますが、OR 1=1はすべてに一致します。最後のコメントは、構文エラーの原因となる最後の二重引用符を取り除きます。このフォームを使用すると、Pass列の検索を効果的に無効にして、すべてのAND/OR句を破棄することで、クエリをより詳細に制御できます。たとえば、Pass条件をOR ID=10に変更することにより、実際のIDを検索できます(ID列があると想定)。

7
Conor Mancone