2016-04-01 22 views
4

JDBIクエリを動的にフィルタリングする必要があります。JDBI SQLインジェクションを防止しながらWHERE句を動的に作成する方法はありますか?

パラメータのリストは、UIからREST経由で渡されます。

WHERE foo=bar AND baz=taz 

そして、このようになりますどのJDBIに渡さ:

@UseStringTemplate3StatementLocator 
public interface ThingDAO { 
    @SqlQuery("SELECT * FROM things <where>) 
    List<Thing> findThingsWhere(@Define("where") String where); 
} 
次のようなものへ - (不器用)構築された(> StringBuilderのジャージー@Context UriInfo :: getQueryParameters)である

http://localhost/things?foo=bar&baz=taz 
http://localhost/things?foo=buz 

私の知る限り、現在の実装はSQLインジェクションに対して脆弱です。 明らかにカラム名はサニタイズできますが、値はサニタイズできません。 1

これを行うには、より洗練されたSQLインジェクションの証明方法が必要です。

+0

私はそうではないと思います。彼は 'Long'型のパラメータのリストを持っています(注入ウィザードには使用できないはずです))' @BindIn'はPreparedStatements 「@ Define」(私が理解する限り)はそうではありません。 – unSinn

答えて

1

私はこの思い付いた:

@BindingAnnotation(BindWhereClause.WhereClauseBinderFactory.class) 
@Retention(RetentionPolicy.RUNTIME) 
@Target({ElementType.PARAMETER}) 
public @interface BindWhereClause { 
    class WhereClauseBinderFactory implements BinderFactory { 
     public Binder build(Annotation annotation) { 
      return new Binder<BindWhereClause, WhereClause>() { 
       public void bind(SQLStatement q, BindWhereClause bind, WhereClause clause) { 
        clause.queryValues 
          .keySet() 
          .forEach(s -> q.bind(s, clause.queryValues.get(s))); 
       } 
      }; 
     } 
    } 
} 

そして@Define@Bindの組み合わせ::

@UseStringTemplate3StatementLocator 
public interface ThingDAO { 
    @SqlQuery("SELECT * FROM things <where>) 
    List<Thing> findThingsWhere(@Define("where") String where, 
           @BindWhereClause() WhereClause whereClause); 
} 
カスタムバインダー BindWhereClauseを介して結合され

public class WhereClause { 
    public HashMap<String, String> queryValues; // [<"foo","bar">, <"baz","taz">] 
    public String preparedString; // "WHERE foo=:foo AND bar=:baz" 
} 

これは注射用にしてください。 (それは?)

+0

あなたの 'queryValues'キーはどこから来ますか?クライアントからのものであれば、まだ注射に脆弱です。例えば"foo;ドロップテーブルの学生、 - "また、JDBIの '@BindIn'アノテーションを見てください。これは、定義とバインディングの両方を単一のアノテーションにまとめています。それはあなたの使用を簡素化するかもしれません。 – qualidafial

+0

はここで使用されていないpreparedStringですか?どのように "findThingsWhere"メソッドを呼び出しますか?ここでparamsを供給するには? –

0

パラメータ化されたクエリを使用します。 Hereはそれらのjdbiページです。
パラメータ化クエリは、ほとんどの設定でSQLインジェクションを防止する方法です。

whereステートメントを動的に作成できますが、値の代わりにパラメータ名を残しておくと、後で安全にバインドされます。

あなたはおそらく、あなたのパラメータは動的であるため、特にこのビットに興味がある:私はそうjdbi使ったことがない私は、あなたがしなければならないと思いますどのような100%わからない

@BindingAnnotation(BindSomething.SomethingBinderFactory.class) 
@Retention(RetentionPolicy.RUNTIME) 
@Target({ElementType.PARAMETER}) 
public @interface BindSomething 
{ 

    public static class SomethingBinderFactory implements BinderFactory 
    { 
    public Binder build(Annotation annotation) 
    { 
     return new Binder<BindSomething, Something>() 
     { 
     public void bind(SQLStatement q, BindSomething bind, Something arg) 
     { 
      q.bind("ident", arg.getId()); 
      q.bind("nom", arg.getName()); 
     } 
     }; 
    } 
    } 
} 

が、 q.bind(...)メソッドがまさにあなたが望むものであるように見えます。ジャン=ベルナールに触発さ

関連する問題