2017-12-13 3 views
0

私は、準備文がデータベースへのSQLインジェクションを避けるための良い方法だと読んでいます。 問題は顧客が静かな変数UIを望んでいることです 彼は最初にテーブルを選択し、次にいくつかの制約を列とテキストで構成します。 だから基本的には(ナイーブ)最終生成物は、次のようになります。prepared statement/sql-injection preventation on変数

Select * from %TABLENAME% where %ATTRIBUTENAME% = %VALUE% 

今の質問は、これは安全な取得する方法ですか?

私は、事前にすべてのテーブルのステートメントを作成するprepareステートメントソリューションを構築することができますが、これを維持するための努力は非常に静かなので、私はかなり馬鹿げたアイデアのように聞こえます静かないくつかのテーブル)。 可能な限り一般的な安全な方法でこれをどのように解決するか考えてみましょうか?

+0

そして、はい、私は顧客に等しいが、negativなどの操作をしないために考えに来ることができることを知っているが、それはそうしてくださいなしanswesその主に私の悩みの少なくともありますここでの説明の弱点に焦点を合わせます。目的を少し簡略化したからです。 – Aeglasin

+0

**文**は、通常、ユーザーからの入力がない場合にのみ使用されます。それ以外の場合は、** PreparedStatement **を使用します。適切な入力衛生状態であっても、** Statement **は安全ではありません。 –

答えて

1

あなたは、SQLインジェクションのために使用することはできませんので

select * from %TABLENAME% where %ATTRIBUTENAME% = ? 

その少なくともVALUEにあなたの例を変更する必要があります。データベースの既知のテーブルと列に対して、TABLENAMEATTRIBUTENAMEの検証を行うことができます。

実行時に検証で使用するDatabaseMetaData.getColumns(...)を参照してください。あるいは、ビルド時に生成された静的ファイルを有効なテーブル/カラムで保持することもできます。

ビルド時にテーブル/列の組み合わせごとにEnumを生成できますか?私はjOOQは、この種のデータベーススキーマからのビルド時間のJavaコードの生成を知っている...おそらくそれは助けることができますか?

例:

public enum TableColumn { 
    CUSTOMER_NAME("customer", "name"), CUSTOMER_ID("customer", "id"), 
    ORDER_ID("order", "id"), // etc etc 

    String table; 
    String column; 

    public TableColumn(String table, String column) { 
     // set values 
    } 
} 

public List<Row> doSelect(TableColumn tc, Object value) { 
    String sql = String.format("select * from %s where %s = ?", tc.table, tc.column); 
    Connection con = getConnection(); 
    try { 
     PreparedStatement ps = con.prepareStatement(sql); 
     ps.setObject(1, value); 
     ... 
+0

私は、私の同僚を説得することができれば、私は内部でそれを見直す必要があります、私は答えを受け入れたとマークします – Aeglasin

+0

@Aeglasinテーブル名を検証するとき、ユーザをシステム、テーブルではなく_user_に制限したいと思うかもしれません。 (ユーザーのビューも公正なゲームかもしれません)。有効なテーブル名を取得したら、テーブルに対して列名を検証できます。追加の混乱の層を追加するには、['sp_addextendedproperty'](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/)を使用して適切な表、列、およびビューにタグを付けることができます。 sp-addextendedproperty-transact-sql)を使用して、ユーザーがさらに限定されたデータのサブセットにアクセスできるようにします。 – HABO