I want to dynamically filter a JDBI query.
The a list of parameters is passed from the UI via REST e.g.
http://localhost/things?foo=bar&baz=taz
http://localhost/things?foo=buz
Which is (clumsily) built (Jersey @Context UriInfo::getQueryParameters -> StringBuilder) to something like this:
WHERE foo=bar AND baz=taz
And passed to JDBI which looks like this:
@UseStringTemplate3StatementLocator
public interface ThingDAO {
@SqlQuery("SELECT * FROM things <where>)
List<Thing> findThingsWhere(@Define("where") String where);
}
As far as I understand the current implementation is vulnerable to SQL injection. I can obviously sanitize the column names but not the values. 1
There must be a more elegant and SQL Injection proof way of doing this.
Inspired by Jean-Bernard I came up with this:
Which is bound via a custom Binder
BindWhereClause
:And a combination of
@Define
and@Bind
:This should be injection proof. (is it?)
Use a parameterized query. Here is the jdbi page for them.
Parameterized queries are the way to prevent sql injection in most settings.
You can dynamically create the where statement, but leave parameter names instead of values, they will be bound later, in a safe way.
You would probably be interested in this bit specifically, since your parameters are dynamic:
I've never used jdbi so I'm not 100% sure what you'd have to do, but it looks like the q.bind(...) method is exactly what you want.