またはSQLインジェクションからユーザーデータを保護する方法

Xkcd

楽しい事実:

sqlインジェクションは、ウェブサイトがデータベースにデータを格納して以来、かなりの周りされています。

Open Web Application Securityプロジェクトは、インジェクション攻撃をwebアプリケーションが直面するトップ10の脅威の2017の一つと評価しました。,

SQLインジェクションは、依然として多くの大規模なデータリークの原因です。 2016年、イリノイ州とアリゾナ州の選挙管理委員会の有権者登録データベースが破られました。 アリゾナ州では情報は盗まれませんでしたが、イリノイ州では、約80,000人の名前、住所、生年月日、性別、社会保障番号の一部などの有権者データにアクセ√

それは恐ろしいです、それは何ですか?

SQLインジェクションタイプの攻撃目標がアプリケーションのデータベースを通じて、挿入の意図しないコードユーザー入力ます。, Sql構文を利用することにより、攻撃者は入力フィールドを使用して、パスワードやクレジットカード番号などのデータベースから情報を取得できます。 誰かがあなたのデータベースの制御を取るか、または保持する情報すべてを削除できる。

それはどのように動作しますか?

SQLインジェクションは、フィールドに挿入された情報を使用して、対応するSQL文を操作して意図しないアクションを実行することによって機能,

基本的な例は次のとおりです。

SELECT * FROM customers WHERE name = " + user_name + ";

この例では、変数user_nameがwebサイト上のユーザーの入力から直接作成されるとします。 その文字列が上記のSQL文に挿入され、そのユーザー名に関連するすべてのフィールドが返されます。 大したことないしかし、誰かがSteve”OR1=1;—ユーザー名として入力した場合はどうなりますか? 次に、生成されたSQLは次のようになります。

SELECT * FROM customers WHERE name = "Steve" OR 1=1;--";

1=1は常にtrueなので、これはテーブル内のすべてのデータを返します。 良くない!,

Let’s take one more look at that comic.

xkcd

The son’s name is Robert’); DROP TABLE students; — What would that do exactly?,P>

INSERT INTO students (name) VALUES ('<Student Name>');

…そして、Bobbyを挿入すると…

INSERT INTO students (name) VALUES ('Robert'); DROP TABLE students;--');

ボビーの名前には)が含まれているため、VALUES引数は彼の名前の途中で閉じられ、DROP TABLE studentsに続くテキストは新しいSQLテーブル全体を削除するステートメント。 最後に、—最後に残りのSQLをコメントアウトし、元のコードの残りの部分を本質的に無視し、エラーが発生しないことを確認します。,

だから、あなたの言っていることは私のデータは決してありませんまた安全か?

いいえ! 実際には、この種の攻撃から身を守るために取ることができる多くの手順があります。 いくつか見てみましょう:

  1. データをサニタイズします。 最初のステップは、ユーザーが入力を許可するものを制御することです。 これを行う最善の方法は、特定のフィールドに許可される入力のタイプを制限することです。, たとえば、電話番号フィールドでは、数値入力のみを許可したり、電子メールフィールドでは、有効な電子メールアドレスに含まれる文字のみを許可したりでき 明らかに、いくつかのフィールドは攻撃で使用できる文字を必要とするので、この方法は無敵ではありません。
  2. エラー報告を構成します。 しばしばデフォルトのエラー報告とデータベース管理システム開発のデバッグ情報です。 これにより、テーブル名や列名など、攻撃者に役立つ情報が返される可能性があります。, 潜在的な攻撃者の生活を容易にする可能性があるため、この種の情報を外部のユーザーに表示しないようにしてください。
  3. バインドされたパラメータを使用します。 バインドされたパラメーターを使用すると、変数にユーザーデータを格納し、プレースホルダーを使用して作成されたSQL文に挿入できます。 以降、SQL文に変数がサーバに送信され別途にバインドされたパラメータは保護対す。 その小さなボビーtを取る!, Rubyのupdateメソッドでバインドされたパラメータの例は次のようになります。
def update sql = <<-SQL UPDATE students SET name = ?, grade = ? WHERE id = ? SQL DB.execute(sql, )end