PLEASE NOTE: This course was retired on
24 Jan 2019. This means
it is no longer being updated or maintained, so information within the
course may no longer be accurate. FutureLearn accepts no liability for any
loss or damage arising as a result of use or reliance on this information.

Control access to the Content Provider through Android permissions. This was covered in week 3.

Guard against SQL injection for Content Providers that wrap SQLite databases (or any other database that supports SQL).

The parameterised methods provided by a Content Provider: query(), insert(), update(), and delete(), help guard against SQL injection.

However, we do need to pay attention to the projection and selection clauses passed to these methods, as carelessness here could result in SQL injection.

Where should the security barrier be?

There are two approaches we could take:

The implementation of the query(), update(), and delete() methods within the Content Provider could try to catch SQL injection attempts.

The caller of the query(), update(), and delete() methods within the client apps can block SQL injection attempts.

The choice depends upon where the threat is coming from. The first method puts the security barrier within the Content Provider, whereas the second method puts the security barrier within the clients of the Content Provider.

If the Content Provider is accessible by any app, or any app that the user grants permission to, then the security barrier needs to be within the Content Provider itself.

However, if access to the Content Provider is restricted to apps you know you can trust, then moving the security barrier into the client apps might make sense.

The technical stuff

At the technical level the solution is the same, the only difference is where the defensive code is placed: in the Content Provider, or in the calling app.

The key idea is the same as the one we saw in week 2 where we used parameterised queries to block SQL injection.

Inside the Content Provider the call to the query() method will result in a corresponding query call on the database itself.

We need to ensure that the only user input that reaches that inner query is passed in the selectionArgs array (of the inner call), with corresponding placeholders (parameters) in the actual SQL command.

The SQL command MUST NOT directly include any user input.

Our code can use the user input to select from a predefined hard-coded list of SQL commands, but not use the user input to construct the SQL command.