SQL注入是一个老话题,没想到今天有同事在android framework踩到了这个坑,mark下。
业务需求要修改查询mmssms.db的一张表canonical_addresses,看到代码有点懵圈,类似如下:
ContentResolver cr = this.getContentResolver();
Cursor cursor = cr.query(Uri.parse("content://mms/"),
new String[]{"* from canonical_addresses where _id=1 --"}, null,null,null);
if(null != cursor && cursor.getCount()>0){
StringBuilder stringBuilder = new StringBuilder();
while (cursor.moveToNext()){
String _id=cursor.getString(cursor.getColumnIndex("_id"));
String address=cursor.getString(cursor.getColumnIndex("address"));
stringBuilder.append("{"+_id+","+address+"}");
}
tv.setText(stringBuilder.toString());
} else {
tv.setText("no data");
}
在源码中一番搜索,SmsProvider在检查权限后只是简单的调用了query方法执行查询:
@Override
public Cursor query(Uri url, String[] projectionIn, String selection,
String[] selectionArgs, String sort) {
final boolean accessRestricted = ProviderUtil.isAccessRestricted(
getContext(), getCallingPackage(), Binder.getCallingUid());
final String smsTable = getSmsTable(accessRestricted);
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
// Generate the body of the query.
int match = sURLMatcher.match(url);
switch (match) {
case SMS_ALL:
constructQueryForBox(qb, Sms.MESSAGE_TYPE_ALL, smsTable);
break;
......
}
......
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor ret = qb.query(db, projectionIn, selection, selectionArgs,
null, null, orderBy);
ret.setNotificationUri(getContext().getContentResolver(),
NOTIFICATION_URI);
return ret;
}
仔细思索一番,发觉 “ --”在SQL的作用是注释,而上述代码会根据权限在qb中设置相应的table,然后生成正确的SQL语句执行。
这样以来,正确的SQL语句岂不是不起任何作用。想到这里突然反映过来应该是SQL注入,于是写下代码测试。去掉" -- "后,代码
果然出现了错误:
6916 8333 E TP/MmsProvider: android.database.sqlite.SQLiteException: near "SELECT": syntax error (code 1): , while compiling: SELECT * from canonical_addresses where _id=1 FROM pdu_restricted ORDER BY date DESC
想不明白,明明MmsSmsProvider可以查到该表,前辈高人为什么要使用这种"高招", 倘若是想叫后辈多学一技的话,这是十分感谢了!
SQL注入的技巧还是不少的,我们虽不能效仿有道德问题的黑客去祸害别人,但也不能不了解相关技术,防患于未然。
最后分享一个SQL注入的链接,共同学习:http://www.2cto.com/article/201501/370137.html