同じボックスで複数の SQL Server データベースと通信する Java アプリケーションがあります。これらのデータベースの数と名前はさまざまです。概して、CallableStatement を使用したストアド プロシージャのみを使用して、データベースにアクセスします。SQL インジェクションの回避とバインド変数の使用については、非常に優れています。
唯一の懸念事項は、データベース名自体が次のように CallableStatement に渡す SQL に連結されることです。
"{call [" + dbName + ".dbo." + procName + "(?, ?, ?)}"
procName は、テンプレート メソッド パターンを使用して子クラスにハードコードされるため、文字列の安全性が保証されます。
dbName は外部で定義されます。dbName をあらゆる種類のパターンに設定して、構文をエスケープし、開発環境でこれを利用しようとしましたが、成功しませんでした。
次のSQL呼び出しを生成するために、次のように設定しました(無実を保護するためにテーブルとprocの名前が変更されました)。
securitytest].nx_proc()};delete from poor_victim_table;
になる
{call [securitytest].nx_proc()};delete from poor_victim_table;].dbo.proper_proc_name()}
と
securitytest].nx_proc()};exec('delete from poor_victim_table');
になる
{call [securitytest].nx_proc()};exec('delete from poor_victim_table');].dbo.proper_proc_name(?,?,?,?,?,?,?)}
結果はまだ行がありますIncorrect syntax near ')'.
。poor_victim_table
を使用しましたがtruncate table
、機能しない場合は、シンプルに切り替えてセキュリティ設定を除外しました。drop table
drop database
delete
バインド パラメーターを受け取る proc を使用すると、予期されるパラメーターの数とThe index 1 is out of range.
.
securitytest]};exec('delete from poor_victim_table');
になる
{call [securitytest]};exec('delete from poor_victim_table');].dbo.proper_proc_name(?,?,?,?,?,?,?)}
すべての道路で実行時エラーが発生するようで、SQL が実行されません。もちろん、これは素晴らしいことです。しかし、成功できないために失敗していることを確認したいのですが、正しい組み合わせを試していないために失敗していないことを確認したいと思います。
一般的な意見/都市伝説は、ストアド プロシージャを使用すると SQL インジェクションの影響を受けなくなるというものですが、セキュリティに関しては、そのような絶対的なステートメントを信頼したくありません。
これをしばらく調査した後、私が思いついたのは、次のスタックオーバーフローの質問です。. procコード自体が入力パラメータから動的SQLを作成しない限り、 SQLインジェクションから保護するため、CallableStatementの使用をサポートしているようです。
そこで、コミュニティへの私の質問は、proc 内の SQL コードが安全であると仮定すると、JDBC で CallableStatement を使用すると SQL インジェクションを本当に防ぐことができるのでしょうか? または、SQL Server ドライバーはそれを防ぐ方法で文字列を解析しますが、他のドライバーはそうしない可能性がありますか? それとも私の努力が足りないのでしょうか?
安全である場合、その保証はどのように行われますか? { call blah(?) }
実際の SQL ではなく、SQL に変換されるusing の抽象的な構文が原因ですか?