The SQL injection through query parameters is the common security issue of any system using SQL database. Android is no different than any other system, so if you’re using SQLite database in your Android app, you should always sanitize the database inputs.
If you are also using an exported ContentProvider
, you need to take care of one more vector of attack: the projection parameter of the queries. Just like SQLiteDatabase
, the ContentProvider
allows the users to specify which columns they want to retrieve. It makes sense, because it reduces the amount of data fetched, which might improve performance and reduce the RAM footprint of your app. Unlike the SQLiteDatabase
, the ContentProvider
might be exported, which means that the external applications can query the data from it requesting an arbitrary projection, which are then turned into raw SQL queries. For example:
1 2 3 |
|
Basically it means that if you exposed a single uri without sanitizing the projection, you have exposed your entire db.
So how do you sanitize your projections? I’ve given it some thought and it seems that the only sensible thing to do is allowing only subsets of predefined set of columns.
You cannot allow any expression, because you’d allow any expressions, including SELECTs from other tables and allowing certain expressions is not a trivial task.
You shouldn’t ignore the provided projection and return all columns, because one of the benefits of using projections is limiting the amount of data retrieved from database. Besides, certain widely used Google application ignores the existence of Cursor.getColumnIndex
method and assumes that the columns will be returned in the same order they were specified in projection. The other app won’t work correctly, and the users will probably blame you.