web-dev-qa-db-ja.com

2次SQLインジェクション保護

私は常に準備されたステートメントを使用するため、通常のSQLインジェクションは問題ありませんが、 2次SQLインジェクション から身を守る方法は?

26
J. Smith

2次のSQLインジェクションは、ペイロードが(GETパラメーターで配信されるのではなく)データベースに既に格納されているインジェクションです。その意味では、保存されたXSSにいくらか似ています(そして、通常の「一次」SQLインジェクションは、反映されたXSSに類似しています)。

どのように機能しますか?ユーザーに任意のユーザー名を選択させるとしましょう。そのため、攻撃者は名前を選択できます'; DROP TABLE Users; --。このユーザー名を単純にSQLクエリに連結して、そのユーザーに関する情報を取得すると、問題が発生します。

sql = "SELECT * FROM Users WHERE UserName = '" + $username + "'";

それで、これにどう対処しますか?

常にパラメーター化されたクエリを常に使用します。データベースに由来する変数であっても、すべての変数を信頼できないユーザーデータとして扱います。すべてがGETパラメーターであるかのように振る舞い、パラメーターとしてバインドすることでそれに応じて動作します。

また、データベースに保存する前と、データベースから取得した後の入力を無害化して制限することもできます(たとえば、英数字のユーザー名のみを許可します)。しかし、私はそれを唯一の防御線としてそれに依存しないので、パラメータ化されたクエリも使用します。

39
Anders

ここには特別なことは何もありません。いわゆる「2次」SQLインジェクションはSQLインジェクションと同じですが、ユーザーが直接入力したデータからではなく、データベース内からコンテンツが送信されるという小さな違いがあります。同じルールが適用されます

  • 入力データの出所(ユーザー、ファイル、データベースなど)に関係なく、常に入力データをサニタイズします

  • 実行可能なコマンドを構築するために文字列連結を使用しないでください。準備されたステートメントなどを使用します.

経験則としては、どれほど安全であると思われるかに関係なく、入力データを決して信頼しないことです。ユーザーが入力する内容を信頼することはできません。自分のデータリポジトリ(データベースなど)でも、何らかの方法でセキュリティが侵害されているか、「不正なデータ」が含まれている可能性があると想定する必要があります。現実のように敵対的な環境で実行することを想定して、コードを記述します。

ところで、オラクルのドキュメントは改善されていません。これは、SQlインジェクションに関して非常に不適切な言葉で説明が不十分な言い回しです。

1
Tim X