TECH I.S.

SQLインジェクション


SQLインジェクション

SQLインジェクションは、データベースを破壊する可能性のあるコードインジェクション手法です。

SQLインジェクションは、最も一般的なWebハッキング手法の 1 つです。

SQLインジェクションは、Webページの入力を介して、SQLステートメントに悪意のあるコードを配置することです。


WebページのSQL

SQLインジェクションは通常、ユーザーにユーザー名やユーザーIDのような入力を求めたときに発生します。

変数(txtUserId)をselect文字列に追加してSELECT文を作成する次の例を見てください。この変数は、ユーザー入力(getRequestString)から取得されます。

txtUserId = getRequestString("UserId"); txtSQL = "SELECT *FROM Users WHERE UserId = " + txtUserId;

この章の残りの部分では、SQLステートメントでユーザー入力を使用することの潜在的な危険性について説明します。


1=1が常にTrueであることに基づくSQLインジェクション

上の例をもう一度見てください。このコードの本来の目的は、特定のユーザーIDを持つユーザーを選択するためのSQL文を作成することです。

ユーザーが「間違った」入力をするのを防ぐものが何もない場合、ユーザーは次のような「スマートな」入力を入力できます。

ユーザーID:105 OR 1=1

次に、SQLステートメントは次のようになります。

SELECT * FROM Users WHERE UserId = 105 OR 1=1;

上記のSQLは有効であり、"Users"テーブルからすべての行を返します。または 1=1は常にTrueです。

上記の例は危険に見えますか? 「Users」テーブルに名前とパスワードが含まれている場合はどうなりますか?

上記のSQLステートメントは、次のステートメントとほとんど同じです。

SELECT UserId, Name, PasswordFROM Users WHERE UserId = 105 or 1=1;

ハッカーは、入力フィールドに105 OR 1=1を挿入するだけで、データベース内のすべてのユーザー名とパスワードにアクセスできる可能性があります。


""=""に基づくSQLインジェクションは常にTrue

Webサイトでのユーザー ログインの例を次に示します。

ユーザー名:John Doe

パスワード:myPass

uName = getRequestString("username"); uPass = getRequestString("userpassword"); sql = 'SELECT * FROM Users WHERE Name ="' + uName + '" AND Pass ="' + uPass + '"'

結果

SELECT * FROM Users WHERE Name ="John Doe" AND Pass ="myPass"

ハッカーは、ユーザー名またはパスワードのテキスト ボックスに「 OR ""=" 」を挿入するだけで、データベース内のユーザー名とパスワードにアクセスできる可能性があります。

ユーザー名:" or ""="

パスワード:" or ""="

サーバーのコードは、次のような有効なSQLステートメントを作成します。

結果

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

上記のSQLは有効であり、"Users"テーブルからすべての行を返します。または ""=""は常にTrueです。


バッチ化されたSQLステートメントに基づくSQLインジェクション

ほとんどのデータベースは、バッチSQLステートメントをサポートしています。

SQLステートメントのバッチは、セミコロンで区切られた2つ以上のSQLステートメントのグループです。

以下のSQLステートメントは、"Users"テーブルからすべての行を返し、"Suppliers"テーブルを削除します。

SELECT * FROM Users; DROP TABLE Suppliers

次の例を見てください。

txtUserId = getRequestString("UserId"); txtSQL = "SELECT *FROM Users WHERE UserId = " + txtUserId;

そして、次の入力:

ユーザーID:105; DROP TABLE Suppliers

有効なSQLステートメントは次のようになります。

結果

SELECT * FROM Users WHERE UserId = 105; DROP TABLE Suppliers;

保護のためにSQLパラメータを使用する

WebサイトをSQLインジェクションから保護するために、SQLパラメータを使用できます。

SQLパラメータは、実行時に制御された方法で SQLクエリに追加される値です。

ASP.NET Razor の例

txtUserId = getRequestString("UserId"); txtSQL = "SELECT *FROM Users WHERE UserId = @0"; db.Execute(txtSQL,txtUserId);

パラメータは、@マーカーによってSQLステートメントで表されることに注意してください。

SQLエンジンは、各パラメーターをチェックして、その列に対して正しく、実行されるSQLの一部としてではなく、文字どおりに処理されることを確認します。

もう一つの例

txtNam = getRequestString("CustomerName"); txtAdd = getRequestString("Address"); txtCit = getRequestString("City"); txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)"; db.Execute(txtSQL,txtNam,txtAdd,txtCit);

次の例は、いくつかの一般的なWeb言語でパラメーター化されたクエリを作成する方法を示しています。

ASP.NETのSELECTステートメント:

txtUserId = getRequestString("UserId"); sql = "SELECT * FROM Customers WHERE CustomerId = @0"; command = new SqlCommand(sql); command.Parameters.AddWithValue("@0",txtUserId); command.ExecuteReader();

ASP.NETのステートメントに挿入:

txtNam = getRequestString("CustomerName"); txtAdd = getRequestString("Address"); txtCit = getRequestString("City"); txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)"; command = new SqlCommand(txtSQL); command.Parameters.AddWithValue("@0",txtNam); command.Parameters.AddWithValue("@1",txtAdd); command.Parameters.AddWithValue("@2",txtCit); command.ExecuteNonQuery();

PHPのステートメントに挿入:

$stmt = $dbh->prepare("INSERT INTO Customers (CustomerName,Address,City) VALUES (:nam, :add, :cit)"); $stmt->bindParam(':nam', $txtNam); $stmt->bindParam(':add', $txtAdd); $stmt->bindParam(':cit', $txtCit); $stmt->execute();



プログラミング学習を加速させる

プログラミングをプロの講師に教えてもらいませんか。

テックアイエスのプログラミングスクールは初心者も大歓迎です。年齢制限もありません。転職・副業に強く、挫折させない手厚いサポートで稼ぐ力を身につけましょう!

スクールの詳細