2012-05-09 20 views
5

背景:エスケープSQL文字列Javaで

私は現在、エンタープライズCMSデータベース(ビジネスオブジェクト)用のJavaフロントエンドを開発しています。現時点では、ユーザーがカスタムデータベースクエリを作成できるようにする機能を構築しています。私はすでにユーザーが利用可能な列のサブセットとユーザーアクセス用に承認された演算子を使用して選択できるようにする手段を実装しています(SI_CUIDのような強力なフィールドは選択できないようにSI_EMAIL_ADDRESSを選択できます)。これまでのところはうまくいきましたが、今度はこの機能を潜在的なSQLインジェクション攻撃から保護する必要があります。

質問:私は、ユーザー入力文字列をエスケープする方法を探しています

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

私はString.replace()を使用することを検討しましたが、可能であればホイールを再作成したくありません。加えて、私はPerparedStatementを開発したセキュリティ専門家からははるかに驚いています。

また、PerparedStatementのJava APIリファレンスを見て、何らかの種類のtoString()メソッドが見つかることを期待しました。悲しいかな、私はこの種のものを見つけることができませんでした。

ご協力いただきまして誠にありがとうございます。前もって感謝します。

参考文献:

Java - escape string to prevent SQL injection

Java equivalent for PHP's mysql_real_escape_string()

答えて

2

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

ANSI SQLを開始し、単一引用符で終了する文字列リテラルを必要とし、単一引用符のための唯一の脱出メカニズムは、2つの単一引用符を使用することです:

'Joe''s Caffee' 

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

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

2

あなたはまだ準備されたステートメントを使用することができるかもしれません。このポストを参照してください:get query from java sql preparedstatement。また、その投稿に基づいて、これを処理するためにLog4JDBCを使用することができます。

これらのオプションのいずれかを使用すると、準備された文がそれを実行するため、SQL注入を防ぐためにエスケープ文字列を心配する必要がなくなります。

+0

:ここに私のサンプルコードです。私は、暗黙的に定義されたtoString()メソッドの未定義の動作に懸念しています。エンタープライズアーキテクトは、データベースそのものが適切に隠されていることを確実にするために驚くべき努力をしてきました。私はそれが実行されているDBMS、または将来変更されるかどうかを知りません。 – phobos51594

+0

実際には、PreparedStatementには公にアクセス可能なコンストラクタさえあるように見えません。私はJDBC接続オブジェクトを持っていないので、どのようにPreparedStatmentオブジェクトをどのように取得するか分からない。 Hm。 – phobos51594

+0

ええ、私はそれがどのように謎になるか見ることができます。私はLog4JDBCを使用していませんが、準備されたステートメントに基づいてSQLを生成できるようです。 – ametren

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(); 

} 

関連する問題