web-dev-qa-db-ja.com

Unicodeを介したSQLインジェクション

私のチームは現在、ソフトウェアにASP.NETとMS SQL Serverを使用しています。セキュリティは私が始めてから重要になっただけで、そこにはあらゆる場所に注入の脆弱性があります。

OracleおよびMS SQLとの現在の統合により、ビジネス上の決定は、パラメーター化されたクエリを使用することではありませんでした。もちろん、これは問題です。

パラメータのホワイトリストとともに検索と置換を実装すると、この問題が大幅に軽減されます。

私の唯一の問題は、SQLインジェクションの原因であるUnicodeやその他のエンコーディングについてたくさん読んだことです。よくわかりません。現在、次のようにすべてをサニタイズしています:

        Const pattern As String = "^[a-zA-Z0-9.=,:\s\\\/\']*$"
        term = term.Replace("'", "''")

        If Not Tools.ValidString(term, pattern) Then
            term = String.Empty
        End If 

    Public Shared Function ValidString(ByVal source As String, ByVal pattern As String) As Boolean
        If source = String.Empty Then Return True

        Dim params As Text.RegularExpressions.RegexOptions = Text.RegularExpressions.RegexOptions.None
        Dim regex As New Text.RegularExpressions.Regex(pattern, params)
        Dim match As Text.RegularExpressions.Match = regex.Match(source, pattern, params)
        Return match.Success
    End Function

誰かがユニコード/エンコードされたインジェクションを使用できる例、またはこの正規表現がSQLインジェクションを防止できない単純な例を持っていますか?.

ありがとう

[〜#〜]更新[〜#〜]

標準のSQLインジェクションに関する回答を教えてください。私はすでにこれをよく知っています。また、文字列のサニタイゼーションを使用しないと言って投稿を中止してください。クライアントがOracleを使用している場合は、ODP.NETを使用するためのロジックを構築しながら、すべてのクエリをADO.NETでパラメーター化されたクエリにシフトするためのリソースは社内にありません。 OWASPは、パラメータ化が疑わしい場合の文字のホワイトリストの使用について言及しているため、正規表現と同様に、許可される文字はごくわずかです。これはばかげているので、私は文字をブラックリストに載せていません。

保持するデータにコンプライアンスは必要ありません。コンテンツが変更されると悪夢になるため、セキュリティはデータベースの整合性のためです。

私たちのソフトウェアは非常に大規模なクラウドアプリケーションCMSとDMSであり、ソフトウェアの99%は内部で使用され、少数のみが外部であり、パブリックレビューとドキュメントへのコメントにのみ使用されます。

Unicodeインジェクションに関する私の新しい理解から。クエリに配置される前にデータがエンコードされている場合にのみ発生する可能性があるため、Unicodeインジェクションはデータのグローバリゼーションを伴うアプリケーションでのみ発生します。上記のサニタイズの後、生の文字列フィールドを文字列クエリに直接渡しています。

私の状況ではUnicodeが適用されないという私の主張を裏付けることができる、注射の専門家からの回答のみをいただけますか?

4
Cyassin

暗黙の変換nicodeホモグリフ のUnicode文字列タイプ(NCHAR、NVARCHAR)から文字列タイプ(CHAR、VARCHAR)へのSQLインジェクションの事例があります。 NVARCHARの ʼ(U + 02BC)などの文字は、エスケープルーチンを通り抜けて'(U + 0027)VARCHAR に変換され、その結果、このような文字列を使用してSQLステートメントを動的に構築する場合のSQLインジェクション。

ただし、検証はかなり厳密であり( Basic Latin Unicode block および nicode whitespace characters の文字のみ)、これが失敗するケースは考えられません。

6
Gumbo

SQLインジェクションを停止するために最も必要なことは、セミコロン(;)です。ただし、それらを削除するだけでは必ずしも簡単ではありません。セミコロンがSQLコマンドのターミネータとしてではなく、文字としてテキストフィールドで使用される場合があります。

クエリにSQLを挿入および防止する方法について詳しく説明している記事はたくさんあります。

テキスト出力をWebページに書き込む場合は、HttpUtility.HtmlEncodeを使用してエンコードします。テキストがユーザー入力、データベース、またはローカルファイルからのものである場合は、これを行います。

これは、SQLインジェクションから保護するために使用される方法の1つを思い出します。それができない文字で問題を引き起こす文字をエンコードします。

特にUnicodeと他のエンコーディングでは、文字列内の問題のある文字を検索し、削除または置換するために同じテクニックを使用する必要があります。

[〜#〜]更新[〜#〜]

Unicode文字列を/ u0000などにエンコードする場合は、文字列をエンコードしたままにして、SQLインジェクションを心配することなくデータベースに安全に配置できます。ただし、サニタイズを実行するルーチンはSQL Serverに組み込まれていないため、作成する必要があります。

2
Adam Zuckerman

ユニコードをどのように利用できるかを確認している場合は、 この質問 を参照してください。解決策を探している場合、本当に安全であると考えられるのは、パラメーター化されたクエリとすべてのエンコーディングの2つだけです。 hexまたはbase64への入力、または値のコンテキストを変更する可能性を開いたままにしないその他のエンコード。

パラメータ化されたクエリの使用を真剣に再考します-実際には非常に使いやすいですが、コードベースはわかりませんが、一般に切り替えはかなり簡単です。特に拡張メソッドの導入以来。

2
jmoreno

SQLインジェクションを防ぐために手作りの正規表現を使用しないでください。 SQLインジェクション、XSS、シェルインジェクションなどを防ぐために、独自のエスケープ、フィルタリング、サニタイズ関数を記述してはなりません。これらは、組み込みライブラリと検査済みライブラリに依存しているものです。

回避できる場合は、標準ライブラリのエスケープ関数を使用しないでください。パラメータ化されたクエリを使用します。

たとえば、クエリの最後に引用符で囲まれていない整数値を使用している場合、そのエスケープは役に立ちません。擬似コード:

check ValidString(input)
query("SELECT * FROM table WHERE id=" + input)

ユーザーは簡単に1 OR 1=1tableのすべての行を表示します。

...または、1 UNION ALL SELECT password,1,1 FROM password_tableなど。そして今、出力にはすべてのユーザーパスワードが含まれています。

パラメータ化されたクエリを使用するためにすべてのSQLコードに戻って変換することは不可能だと言っていますか?もしそうなら、あなたはSQL値を常に引用し、整数の比較や挿入を決して行わないことを100%確信している方がいいと思います...

もし私があなただったら、セキュリティがほんの少しでも望まれるなら、実際にコードを安全に書き直すのに時間がかかる必要があることを、あなたの経営陣やチームに納得させます。

2
Anorov