単純な正規表現を使用して、可能なSQLi攻撃を100%検出できるかどうか疑問に思っています。
言い換えれば、非常に単純なPHPコードを例として使用します:
if (preg_match("/select/i", $input)) {
attack_log("Possible SELECT SQLi detected.")
}
質問は次のとおりです。
SQLiのキーワードフィルタリングは良い手法ではありません。それをバイパスする方法は多すぎます。
たとえば、_sel/**/ect
_のようなクレイジーなものが機能する可能性があります。または、substr()
を使用してゲームをプレイします。そしてEXEC('SEL' + 'ECT 1')
があります。
一般的なフィルタリング技術を回避する方法については、 多くのガイド があります。
ただし、フィルタリングするもののスーパーセット(select
と_/**/
_とsubstr
とEXEC
)があるかどうかを尋ねるかもしれませんが、リストは非常に、非常に長く、それでも包括的なリストを取得できない場合があります。
より適切なアプローチは、許容可能な入力の範囲を理解してそれらを保護するか、適切な設計を通じてSQLiを無効にすることです。
.+
確かにSQLiをすべて検出します。ただし、通常のクエリを実行しようとする試みも検出されます(または任意のテキスト)、データベースを完全に無用にする 。
同様に、データベースをオフにするとSQLiから保護できると言えます。それは本当ですが、それはまたそれが意図された目的のためにデータベースを役に立たなくします。
準備されたステートメントまたはパラメーター化されたクエリを使用します。彼らはこの問題を解決するために存在します。
単純な正規表現を使用して、可能なSQLi攻撃を100%検出できるかどうか疑問に思っています。
この方法で質問しているという事実は、問題について誤って考えていることを示しています。
SQLインジェクションはdataの脆弱性ではありません。これはアプリケーションの脆弱性ですcode that handles that data。
例:現在、「SQLインジェクション」をWebサイトのテキストエリアに入力しています!そして、「-DROP TABLE Users;ここ!私の答えはSQLインジェクション攻撃ですか?もちろん違います。
さて、あなたがやろうとしていることは、試みられた SQLインジェクション攻撃を検出することだと主張することができます。しかし、ここで、入力のintentを決定する必要があります。フィールドに裸のアポストロフィを入力した場合、それはタイプミスですか、それともSQLインジェクション攻撃の試みですか?私の意図を100%検出できますか?もちろん違います。
基本的に、可能攻撃を特定しようとすると、検出率が100%になることはありません。
SQLインジェクションの脆弱性はコードにのみ存在し、データには存在しないため、データのみを考慮した分析では、せいぜい非常に大きな誤検知率が発生します。実際のすべての攻撃トラフィックに一致する可能性がある、あなたが考案したソリューションは、このWebサイトへの非常に大量のlegitimateトラフィックを、そのような攻撃が意図されていない「攻撃」として解釈します。
いいえ。まず、SQLインジェクションを使用して、悪意のあるユニバーサルパスワード' OR '1' = '1
や一般的なユーザー名 Robert'); DROP TABLE Students;--
。また、「選択」は英語で非常に一般的な単語であり、さまざまな状況で完全に無害な方法で表示される場合があります。したがって、/select/i
に一致する入力をフィルタリングすると、大量の誤検知が発生します(たとえば、16件の誤検知と、現在読んでいるWebサイトだけでカウントされます)。
データベースにデータを送信する前に入力をサニタイズしたい場合、 PHPにはその目的のための便利な機能があります (これらはmySQLの機能です)、他のデータベースAPIは、特定のデータベースに合わせて調整された同様の機能を提供する必要があります構文)。
しかし、特定の入力をブロックすることでSQLインジェクションから身を守ろうとすると、間違った最前線で戦います。文字列連結によるSQLステートメントの作成を停止することにより、SQLインジェクションから身を守る方がはるかに賢明です。 SQLインジェクションを意図せずに作成することを困難にする方法でデータベースと対話する一般的な代替方法は次のとおりです。