web-dev-qa-db-ja.com

DB2 SQLクエリで使用する前に、ユーザー入力からフィルタリングする必要がある危険な文字は何ですか?

私は、DB2 SQLクエリに補間されるユーザー入力から危険な文字を適切にフィルタリング/エスケープする方法を完全に理解しようとしています。

私が分析しているサニタイズルーティングは次のように機能します。

  • すべてのバックスラッシュを削除します(s/\\ //)
  • すべての単一引用符を二重単一引用符で置き換えます(s/'/' '/)

私の最初の本能は、既存のdb2消毒関数を調べて、違いがないかどうかを確認することでした。したがって、私は db2_real_escape_string を調べましたが、これはまったく異なります。文字列引数の特殊文字の前にバックスラッシュを付加します。バックスラッシュが前に付いている文字は、\ x00、\ n、\ r、\、 '、 "、および\ x1aです。

私が持っているいくつかの特定の質問は:

  1. なぜdb2_real_escape_string()は二重引用符ではなく引用符でバックスラッシュエスケープするのですか?これは間違っているようです。
  2. 私が分析しているサニタイズ機能が、\ x00、\ n、\ r、\ x1a、 "をエスケープまたはフィルタリングできません。これらの文字が攻撃者に悪用される可能性はありますか?これが私の主な質問です。
  3. 私のサニタイズ関数のもう1つの欠点は、文字セットに対応していないことですが、db2はこの場合、デフォルトの文字セットを使用するように構成されているため、これは問題ではないと推測しています(これは私が推測していることではありません) tマルチバイト)。したがって、AFAIKは、GBKのようなマルチバイト文字セットが構成されていない限り、 mysql GBKにおけるこの既知の脆弱性 のようなマルチバイトSQLインジェクション攻撃は問題になりません。
  4. 私が分析しているサニタイズ機能が不足している他の考慮事項/手順はありますか?

パラメータ化されたクエリを使用することが明白な解決策であることを理解しています。ただし、この場合は、A)現在のデザインが悪用可能かどうかを判断し、B)サニタイズ機能のパッチを提供する必要があります(必要な場合)。

edit上記のサニタイズ関数と次の使用法を前提として、基本的にはSQL注入の概念実証ペイロードを構築しようとしています:execute( " SELECT foo FROM bar WHERE col='" + my_sanitize($_GET['input']) + "'" )

現在のサニタイズ機能の設計(バックスラッシュと二重引用符を削除する)を考慮して、上記の使用例のように単一引用符から抜け出す方法はありますか?

ご協力ありがとうございます!

6
octagonC

"私が分析しているサニタイズ関数は、\ x00、\ n、\ r、\ x1a、"をエスケープまたはフィルタリングできません。これらの文字が攻撃者によってどのように悪用される可能性がありますか?これが私の主な質問です。

空白スペースと代替文字の\ x00および\ x1a 16進表記。\nと\ rは改行と復帰です。

ほとんどの場合、私はこれらがひどく展開可能な文字になるとは思いません。ここでタイプすると、\ x00(空白)を使用して静的バッファーをフラッディングできる可能性があります。\x1a(サブ)文字は、システムがバイナリモードの場合、またはバイナリをストリーミングしている場合に、ファイルの終わりに達したとシステムに思わせる可能性があります。

\ nと\ rについては...あまり考えられない。

システム上にある/システムで取得できる情報の量に応じて、考えられるさまざまな文字エンコーディングを調査することができます。時には、UTF-8をUTF-7に設定されたプロセス(ランダムな例、私が考えている実際のアプリケーションではない)に渡して、変換エラーの魔法からエキサイティングな結果を得ることができます。

ペンテストで頑張ってください。

3
grauwulf

「サニタイズ」は壊れやすいです。データベースの新しいサブバージョンが余分な特殊文字を導入する場合に備えて、データベースが「特殊文字」を解釈する方法のすべての詳細を検討する必要があり、それを綿密に追跡する必要があります。これは大変な作業であり、しばしば失敗します。

ユーザーデータをSQLクエリに挿入する(非常に)望ましい方法は、 準備済みステートメント を使用することです。これはあなた(プログラマー)にとってより簡単で、より堅牢で、より安全で、おそらくより高速になります。

8
Thomas Pornin

重要なユーザー入力を検証するには、SQL文字列が壊れる可能性があります。「有効な文字配列/文字列」を作成し、ユーザー入力の各文字が許可された文字列内にあることを確認します。

たとえば、数値のみを許可する場合、文字列は次のようになります。

function ParseIntoValid(userinput)
{
    string validOutput = "";
    Array allowedChars = new Array("0123456789");

    foreach (char c in userinput[])
    {

        if (c.instr(allowedChars))
        {

            // if this is a parser, then add valid chars to new output
            validOutput += c;
         }
         else
         { 
            // exit loop and return false/error if you just need a check or just ignore the illigal chars
         }
    }
}

目的に応じて、このチェックを単純な「CheckIfValid(input)」または「ParseIntoValid(input)」に簡単にラップできます。

チェックするだけでなく解析することで、有効な出力が得られます。文字数が少ない可能性がありますが、ユーザーが誤って単一の不正な文字を入力した場合、この関数は「良いユーザー」を助け、「悪いユーザー」はまだ得られません。それらを使用してアクセスします。

0
BerggreenDK