2

データベース(POSTGRESQL)に挿入する前にデータを検証しようとしています。電子メール、郵便番号などに対応するデータは、ApacheCommonsValidatorを使用して簡単に検証できます。しかし、名前の場合、私はこれを使用しました:

^[a-zA-Z][ a-zA-Z]{1-30}$

これにより、特殊文字が名前として追加されるのを防ぐことができますが、ユーザーがDROP or GRANT名前として追加するのを防ぐことはできません。を使用しPreparedStatementているので、問題になるとは思いませんでしたが、2次SQLインジェクションにつながる可能性があるため、SQLキーワードをデータベースに含めないようにする必要があります。

すべてのSQLキーワードをブラックリストに登録することを考えました(確かに、これによりHuge Grantがサイトにログインできなくなります。:P)、64を超えるキーワードがあるようです。これ(SQLキーワードのブラックリストフィルタリングデータ)は、 2次SQLインジェクションを防ぐための適切なアプローチですか?私のオプションは何ですか?

私はこのコードを使用しています:

String sql="INSERT INTO users (username, password, name) VALUES (?,?,?);";
        try{
            conn=SomeStaticClass.createConnection();
            ps=conn.prepareStatement(sql);
            ps.setString(1, dataBean.getUsername());
            ps.setString(2, dataBean.getPassword());
            ps.setString(3, dataBean.getName());
            ps.execute();
        }catch(SQLException e){
            e.printStackTrace()
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            try{
                if(ps!=null){
                    ps.close();
                }
                conn.close();
            }catch(SQLException e){
                e.printStackTrace();
            }
        }
4

4 に答える 4

2

これは、この種の状況に適したアプローチですか?

いいえ。

SQLインジェクションは、文字列を連結してSQLクエリをアセンブルするときに発生します。

SQLインジェクションを防ぐための「ベストプラクティス」アプローチはPreparedStatement、パラメータのプレースホルダーを持つ定数SQLクエリでを使用することです。次に、プリペアドステートメントsetメソッドを使用して、各プレースホルダーパラメーターの値を設定します。このアプローチにより、SQLキーワードを含む「厄介な」文字列パラメータがリテラル文字列として解釈されることが保証されます。


更新-PreparedStatements一貫して使用することで、2次攻撃からも保護する必要があります...次のようなものを参照していると仮定します。

http://download.oracle.com/oll/tutorials/SQLInjection/html/lesson1/les01_tm_attacks2.htm

汚染されている可能性のあるものからSQLクエリ文字列を作成しないようにする必要があります。プレースホルダーを使用して汚染された可能性のあるデータを処理する場合、データがどこから来たかは関係ありません。

(SQLキーワードをブラックリストに登録すると、データベースにゴミが入らないようにするのに役立ちます。ただし、前述のように、正当なデータに損傷を与え、システムのユーザビリティに影響を与える可能性があります。私はそうしません。プログラマーの規律...そして徹底的なコードレビュー。)

于 2012-12-06T06:42:53.687 に答える
1

2次インジェクションは、キーワードをデータベースに保存し、後で安全でない方法で使用した場合にのみ発生します。プリペアドステートメントを使用し、それらが適切にパラメーター化されている場合、それは発生しません。シスコには、SQLインジェクションを理解するための優れた要約があります。

http://www.cisco.com/web/about/security/intelligence/sql_injection.html

「Grant」の例とは別に、IF、BY、IS、IN、TOなど、英語/名前で非常に一般的に発生するものも多数あります。

于 2012-12-06T06:49:01.360 に答える
1

データベース内のすべてのデータを、将来適切にエスケープせずに任意のスクリプト言語(SQLやHTMLなど)で使用できるようにすることは、不可能ではないにしても、非常に困難です。とにかく文字がどのように使用されるかを理解する前に、「安全な」文字と「安全でない」文字を区別することは不可能です。

データベースに挿入される前にすべてのデータをエスケープしてクリーンアップしようとすると、データベース内のユーザー生成データが「安全」であると信じてしまう可能性があります。これは非常に危険な信念です。データがどのように使用されるかを知っている場合にのみ、データが安全であるかどうかを知ることができ、実際にデータを使用する場合にのみ知ることができます(データベース内のデータは非常に長期間存続する可能性があるため)。

この種の問題を回避するための最善の戦略は、実際に使用するときに常にすべてのデータをエスケープすることです。これは、PreparedStatementを使用する場合、htmlで使用する場合は適切にエスケープする場合、電子メールに挿入する場合はエスケープする場合などです。等

私はこの答えでいくつかの例を挙げました:

OWASP HTML Sanitizerで特定の文字を許可するにはどうすればよいですか?

于 2012-12-06T10:14:47.193 に答える
0

PreparedStatementを使用することに加えて、Webページでユーザーから提供された入力を確認する必要があります。

これで、2つの異なるチェックがあります。1. Webページで、処理時間を短縮します。2.何かが最初のチェックに合格した場合、preparedstatementはクエリが適切に解析されることを確認します。

たとえば、ユーザーがアイテムを検索しています。

ユーザー入力は

' OR ITEM in (Select ITEM from SOME_TABLE) OR ITEM = ''

そして、文字列を連結してSQLを構築すると、SQLコマンドは次のようになります。

Select * from TABLE_X WHERE ITEM = '' OR ITEM in (Select ITEM from SOME_TABLE) OR ITEM = ''

したがって、DATABASEはハッキングされますが、それ以外の場合、PreparedStatementはクエリを解析し、ユーザーにSQLを変更させません...

于 2012-12-06T06:53:48.920 に答える