Search code examples
objective-csqlitefmdb

FMDB avoid sql injection


I am working on a project that is built on raw sqlite, and I have changed it to FMDB.

All the queries are parametrized.

Here is one such an example:

 NSString* sqlQuery = [NSString stringWithFormat:@"SELECT COUNT(*) FROM Contacts WHERE FirstName='%@' AND LastName='%@'", fName,lName];

and I pass it to my helper class:

 NSInteger count = [[[DB sharedManager] executeSQL:sqlQuery] integerValue];

Helper class:

- (NSString*)executeSQL:(NSString *)sql
{
    __block     NSString *resultString = @"";
    [_secureQueue inDatabase:^(FMDatabase *db) {
        FMResultSet *results = [db executeQuery:sql];
        while([results next]) {
            resultString= [results stringForColumnIndex:0];
        }
    }];
    return resultString;
}

I can make a workaround something like:

    sql = @"SELECT COUNT(*) FROM Contacts WHERE FirstName=? AND LastName=?"
    [db executeQuery:sql,firstParam, secondParam]

But I do not want to change the helper method, I need to pass the changed/updated sql query to my helper method.

How can I change this:

NSString* sqlQuery = [NSString stringWithFormat:@"SELECT COUNT(*) FROM Contacts WHERE FirstName='%@' AND LastName='%@'", fName,lName];

to something like:

NSString* sqlQuery = [NSString stringWithFormat:@"SELECT COUNT(*) FROM Contacts WHERE FirstName=? AND LastName=?", fName,lName];

Solution

  • If you want to avoid SQL Injection problems, then you must never build a query using stringWithFormat. You must properly bind variables into the query. Period. End of discussion.

    So you have no choice but to change your helper. Have it take two parameters instead of one. The first being the query with the proper use of ? and the second being an array of values that get bound into the query but the helper method.