Knowing the SQL-injection attacks and securing our Android applications from them

Exclusive offer: get 50% off this eBook here
Android Security Cookbook

Android Security Cookbook — Save 50%

Practical recipes to delve into Android's security mechanisms by troubleshooting common vulnerabilities in applications and Android OS versions with this book and ebook

$26.99    $13.50
by Keith Makan Scott Alexander-Bown | December 2013 | Open Source

It's time that we learned not only about the ways to prevent the attacks on our Android applications, but also about the attacks themselves. In this article by Keith Makan and Scott Alexander-Bown, the authors of Android Security Cookbook, we will see the casing exploitation techniques that target the Android applications. It shows how to examine them for security risks. This article also talks about the application flaws and fixes. It will walk the readers through the useful techniques that developers can use to protect the applications from such attacks.

(For more resources related to this topic, see here.)

Enumerating SQL-injection vulnerable content providers

Just like web applications, Android applications may use untrusted input to construct SQL queries and do so in a way that's exploitable. The most common case is when applications do not sanitize input for any SQL and do not limit access to content providers.

Why would you want to stop a SQL-injection attack? Well, let's say you're in the classic situation of trying to authorize users by comparing a username supplied by querying a database for it. The code would look similar to the following:

public boolean isValidUser(){ u_username = EditText( some user value ); u_password = EditText( some user value ); //some un-important code here... String query = "select * from users_table
where username = '" + u_username + "' and password = '" + u_password +"'"; SQLiteDatabase db //some un-important code here... Cursor c = db.rawQuery( p_query, null ); return c.getCount() != 0; }

What's the problem in the previous code? Well, what happens when the user supplies a password '' or '1'='1'? The query being passed to the database then looks like the following:

select * from users_table where username = '" + u_username + "' and password = '' or '1'='1' "

The preceding bold characters indicate the part that was supplied by the user; this query forms what's known in Boolean algebra as a logical tautology; meaning no matter what table or data the query is targeted at, it will always be set to true, which means that all the rows in the database will meet the selection criteria. This then means that all the rows in users_table will be returned and as result, even if a nonvalid password ' or '1'=' is supplied, the c.getCount() call will always return a nonzero count, leading to an authentication bypass!

Given that not many Android developers would use the rawQuery call unless they need to pull off some really messy SQL queries, I've included another code snippet of a SQL-injection vulnerability that occurs more often in real-world applications. So when auditing Android code for injection vulnerabilities, a good idea would be to look for something that resembles the following:

public Cursor query(Uri uri, String[] projection , String selection ,String[] selectionArgs , String sortOrder ) { SQLiteDBHelper sdbh = new StatementDBHelper(this.getContext()); Cursor cursor; try { //some code has been omitted cursor = sdbh .query(projection,selection,selectionArgs,sortOrder); } finally { sdbh.close(); } return cursor; }

In the previous code, none of the projection, selection, selectionArgs, or sortOrder variables are sourced directly from external applications. If the content provider is exported and grants URI permissions or, as we've seem before, does not require any permissions, it means that attackers will be able to inject arbitrary SQL to augment the way the malicious query is evaluated.

Let's look at how you actually go about attacking SQL-injection vulnerable content providers using drozer.

How to do it...

In this recipe, I'll talk about two kinds of SQL-injection vulnerabilities: one is when the select clause of a SQL statement is injectable and the other is when the projection is injectable. Using drozer, it is pretty easy to find select-clause-injectable content providers:

dz> run app.provider.query [URI] –-selection "1=1"

The previous will try to inject what's called a logical tautology into the SQL statement being parsed by the content provider and eventually the database query parser. Due to the nature of the module being used here, you can tell whether or not it actually worked, because it should return all the data from the database; that is, the select-clause criteria is applied to every row and because it will always return true, every row will be returned!

You could also try any values that would always be true:

dz> run app.provider.query [URI] –-selection "1-1=0" dz> run app.provider.query [URI] –-selection "0=0" dz> run app.provider.query [URI] –-selection "(1+random())*10 > 1"

The following is an example of using a purposely vulnerable content provider:

dz> run app.provider.query content://com.example.
vulnerabledatabase.contentprovider/statements –-selection "1=1"

It returns the entire table being queried, which is shown in the following screenshot:

You can, of course, inject into the projection of the SELECT statement, that is, the part before FROM in the statement, that is, SELECT [projection] FROM [table] WHERE [select clause].

Securing application components

Application components can be secured both by making proper use of the AndroidManifest.xml file and by forcing permission checks at code level. These two factors of application security make the permissions framework quite flexible and allow you to limit the number of applications accessing your components in quite a granular way.

There are many measures that you can take to lock down access to your components, but what you should do before anything else is make sure you understand the purpose of your component, why you need to protect it, and what kind of risks your users face should a malicious application start firing off intents to your app and accessing its data. This is called a risk-based approach to security, and it is suggested that you first answer these questions honestly before configuring your AndroidManifest.xml file and adding permission checks to your apps.

In this recipe, I have detailed some of the measures that you can take to protect generic components, whether they are activities, broadcast receivers, content providers, or services.

How to do it...

To start off, we need to review your Android application AndroidManifest.xml file. The android:exported attribute defines whether a component can be invoked by other applications. If any of your application components do not need to be invoked by other applications or need to be explicitly shielded from interaction with the components on the rest of the Android system—other than components internal to your application—you should add the following attribute to the application component's XML element:

<[component name] android:exported="false"> </[component name]>

Here the [component name] would either be an activity, provider, service, or receiver.

How it works…

Enforcing permissions via the AndroidManifest.xml file means different things to each of the application component types. This is because of the various inter-process communications ( IPC ) mechanisms that can be used to interact with them. For every application component, the android:permission attribute does the following:

  • Activity : Limits the application components which are external to your application that can successfully call startActivity or startActivityForResult to those with the required permission
  • Service : Limits the external application components that can bind (by calling bindService()) or start (by calling startService()) the service to those with the specified permission
  • Receiver : Limits the number of external application components that can send broadcasted intents to the receiver with the specified permission
  • Provider : Limits access to data that is made accessible via the content provider

The android:permission attribute of each of the component XML elements overrides the <application> element's android:permission attribute. This means that if you haven't specified any required permissions for your components and have specified one in the <application> element, it will apply to all of the components contained in it. Though specifying permissions via the <application> element is not something developers do too often because of how it affects the friendliness of the components toward the Android system itself (that is, if you override an activity's required permissions using the <application> element), the home launcher will not be able to start your activity. That being said, if you are paranoid enough and don't need any unauthorized interaction to happen with your application or its components, you should make use of the android:permission attribute of the <application> tag.

When you define an <intent-filter> element on a component, it will automatically be exported unless you explicitly set exported="false". However, this seemed to be a lesser-known fact, as many developers were inadvertently opening their content providers to other applications. So, Google responded by changing the default behavior for <provider> in Android 4.2. If you set either android:minSdkVersion or android:targetSdkVersion to 17, the exported attribute on <provider> will default to false.

Defending against the SQL-injection attack

The previous chapter covered some of the common attacks against content providers, one of them being the infamous SQL-injection attack. This attack leverages the fact that adversaries are capable of supplying SQL statements or SQL-related syntax as part of their selection arguments, projections, or any component of a valid SQL statement. This allows them to extract more information from a content provider than they are not authorized.

The best way to make sure adversaries will not be able to inject unsolicited SQL syntax into your queries is to avoid using SQLiteDatabase.rawQuery() instead opting for a parameterized statement. Using a compiled statement, such as SQLiteStatement, offers both binding and escaping of arguments to defend against SQL-injection attacks. Also, there is a performance benefit due to the fact the database does not need to parse the statement for each execution. An alternative to SQLiteStatement is to use the query, insert, update, and delete methods on SQLiteDatabase as they offer parameterized statements via their use of string arrays.

When we describe parameterized statement, we are describing an SQL statement with a question mark where values will be inserted or binded. Here's an example of parameterized SQL insert statement:

INSERT VALUES INTO [table name] (?,?,?,?,...)

Here [table name] would be the name of the relevant table in which values have to be inserted.

How to do it...

For this example, we are using a simple Data Access Object ( DAO ) pattern, where all of the database operations for RSS items are contained within the RssItemDAO class:

  1. When we instantiate RssItemDAO, we compile the insertStatement object with a parameterized SQL insert statement string. This needs to be done only once and can be re-used for multiple inserts:

    public class RssItemDAO { private SQLiteDatabase db; private SQLiteStatement insertStatement; private static String COL_TITLE = "title"; private static String TABLE_NAME = "RSS_ITEMS"; private static String INSERT_SQL = "insert into " +
    TABLE_NAME + " (content, link, title) values (?,?,?)"; public RssItemDAO(SQLiteDatabase db) { this.db = db; insertStatement = db.compileStatement(INSERT_SQL); }

    The order of the columns noted in the INSERT_SQL variable is important, as it directly maps to the index when binding values. In the preceding example, content maps to index 0, link maps to index 1, and title to index 2.

  2. Now, when we come to insert a new RssItem object to the database, we bind each of the properties in the order they appear in the statement:

    public long save(RssItem item) { insertStatement.bindString(1, item.getContent()); insertStatement.bindString(2, item.getLink()); insertStatement.bindString(3, item.getTitle()); return insertStatement.executeInsert(); }

    Notice that we call executeInsert, a helper method that returns the ID of the newly created row. It's as simple as that to use a SQLiteStatement statement.

  3. This shows how to use SQLiteDatabase.query to fetch RssItems that match a given search term:

    public List<RssItem> fetchRssItemsByTitle(String searchTerm) { Cursor cursor = db.query(TABLE_NAME, null, COL_TITLE + "LIKE ?",
    new String[] { "%" + searchTerm + "%" }, null, null, null); // process cursor into list List<RssItem> rssItems = new ArrayList<RssItemDAO.RssItem>(); cursor.moveToFirst(); while (!cursor.isAfterLast()) { // maps cursor columns of RssItem properties RssItem item = cursorToRssItem(cursor); rssItems.add(item); cursor.moveToNext(); } return rssItems; }

    We use LIKE and the SQL wildcard syntax to match any part of the text with a title column.

Summary

There were a lot of technical details in this article. Firstly, we learned about the components that are vulnerable to SQL-injection attacks. We then figured out how to secure our Android applications from the exploitation attacks. Finally, we learned how to defend our applications from the SQL-injection attacks.

Resources for Article:


Further resources on this subject:


Android Security Cookbook Practical recipes to delve into Android's security mechanisms by troubleshooting common vulnerabilities in applications and Android OS versions with this book and ebook
Published: December 2013
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

About the Author :


Keith Makan

Keith Makan is a former computer science and physics student, and a passionate hobbyist and security researcher. He spends most of his free time reading source code, performing reverse engineering and fuzz testing, and developing exploits for web application technology.

Keith works professionally as an IT security assessment specialist. His personal research has won him spots on the Google Application Security Hall of Fame numerous times. He has developed exploits against Google Chrome's WebKit XSSAuditor, Firefox's NoScript Add-on, and has often reported security flaws and developed exploits for WordPress plugins.

Scott Alexander-Bown

Scott Alexander-Bown is an accomplished developer with experience in financial services, software development, and mobile app agencies. He lives and breathes Android, and has a passion for mobile app security.

In his current role as senior developer, Scott specializes in mobile app development, reverse engineering, and app hardening. He also enjoys speaking about app security and has presented at various conferences for mobile app developers internationally.

Books From Packt


Android Application Programming with OpenCV
Android Application Programming with OpenCV

Augmented Reality for Android Application Development
Augmented Reality for Android Application Development

Android User Interface Development: Beginner's Guide
Android User Interface Development: Beginner's Guide

 Android Application Security Essentials
Android Application Security Essentials

Instant Android Fragmentation Management How-to [Instant]
Instant Android Fragmentation Management How-to [Instant]

Android 4: New Features for Application Development
Android 4: New Features for Application Development

Android Development Tools for Eclipse
Android Development Tools for Eclipse

Android Database Programming
Android Database Programming


No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
V
b
d
q
L
C
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software