6

バックグラウンド:

私は現在、エンタープライズCMSデータベース(ビジネスオブジェクト)用のJavaフロントエンドを開発しています。現在、ユーザーがカスタムデータベースクエリを作成できるようにする機能を作成しています。ユーザーがユーザーアクセスが承認された使用可能な列と演算子のサブセットのみを使用して選択できるようにするための対策をすでに実装しました(たとえば、SI_EMAIL_ADDRESSは選択できますが、SI_CUIDなどのより強力なフィールドは選択できません)。これまでのところ順調に進んでいますが、SQLインジェクション攻撃の可能性からこの機能を保護する時が来ました。

質問:

ユーザー入力文字列をエスケープするメソッドを探しています。私はすでにPerparedStatementを見てきましたが、データベースにアクセスするためにサードパーティのAPIを使用することを余儀なくされています。これらのAPIは私には不変であり、データベースへの直接アクセスは問題外です。個々のメソッドは、実行するクエリを表す文字列を受け取るため、PreparedStatementが無効になります(私の知る限り、これは直接データベース接続に対して実行する必要があります)。

String.replace()の使用を検討しましたが、可能であれば車輪の再発明はしたくありません。さらに、PerparedStatementを開発したセキュリティの専門家とはかけ離れています。

また、ある種のtoString()メソッドを見つけることを期待して、PerparedStatementのJavaAPIリファレンスも調べました。残念ながら、私はそのようなものを見つけることができませんでした。

どんな助けでも大歓迎です。前もって感謝します。

参照:

Java-SQLインジェクションを防ぐためのエスケープ文字列

PHPのmysql_real_escape_string()に相当するJava

4

3 に答える 3

2

プリペアドステートメントを引き続き使用できる場合があります。この投稿を参照してください:javasqlpreparedstatementからクエリを取得しますまた、その投稿に基づいて、 Log4JDBCを使用してこれを処理できる場合があります。

これらのオプションのいずれかを使用すると、SQLインジェクションを防ぐために文字列をエスケープすることを心配する必要がなくなります。これは、プリペアドステートメントが自動的に行うためです。

于 2012-05-09T18:51:58.533 に答える
2

もちろん、PreparedStatementを使用する方が簡単で安全です。

ANSI SQLでは、単一引用符で開始および終了する文字列リテラルが必要です。単一引用符の唯一のエスケープメカニズムは、2つの単一引用符を使用することです。

'Joe''s Caffee'

したがって、理論的には、一重引用符を2つの一重引用符に置き換えるだけで済みます。ただし、いくつかの問題があります。まず、一部のデータベース(MySQLなど)も(またはのみ)エスケープメカニズムとしてバックスラッシュをサポートしています。その場合、バックスラッシュを2倍にする必要があります(同様に)。

MySQLの場合、MySQLUtilsを使用することをお勧めします。MySQLを使用しない場合は、使用する正確なエスケープメカニズムを確認する必要があります。

于 2012-05-09T19:12:49.553 に答える
0

ただし、JavaでPHPのmysql_real_escape_string()を処理する標準的な方法はありません。私が行ったのは、replaceAllメソッドをチェーンして、例外を回避するために必要なすべての側面を処理することでした。これが私のサンプルコードです:

public void saveExtractedText(String group,String content) { try { content = content.replaceAll("\", "\\") .replaceAll("\n","\n") .replaceAll("\r", "\r") .replaceAll("\t", "\t") .replaceAll("\00", "\0") .replaceAll("'", "\'") .replaceAll("\"", "\\"");

    state.execute("insert into extractiontext(extractedtext,extractedgroup) values('"+content+"','"+group+"')");
} catch (Exception e) {
    e.printStackTrace();

}

于 2016-01-19T15:01:32.287 に答える