SQL Injection in iOS
Vulnerable example
The following snippet outlines a vulnerable SQL(ITE) query performed in iOS Swift:
let sql = "SELECT * FROM user WHERE username = '\(username)' AND password = '\(password)'"
let result = sqlite3_exec(db, sql, nil, nil, nil)
// ...
sqlite3_close(db)
The string interpolation syntax merely inserts the username
and password
values into the query, and wrapping them in '
is obviously not enough to prevent the injection if those are user-controlled values.
In fact, one could provide a valid username, say admin
, and use ' OR 1 LIMIT '1
as the password to return the associated record, even without knowing the password. The resulting query would then be:
SELECT * FROM user WHERE username = 'admin' AND password = '' OR 1 LIMIT '1';
Prevention
As usual, the most effective prevention is to use prepared statements:
let sql = "SELECT * FROM user WHERE username = ? AND password = ?"
var updateStatement: OpaquePointer?
if sqlite3_prepare_v2(db, sql, -1, &updateStatement, nil) == SQLITE_OK {
sqlite3_bind_text(updateStatement, 1, username, -1, nil)
if sqlite3_step(updateStatement) == SQLITE_DONE {
print("OK")
// ...
} else {
print("ERROR")
}
} else {
print("ERROR")
}
sqlite3_finalize(updateStatement)
sqlite3_close(db)
References
CWE - CWE-89: Improper Neutralization of Special Elements used in an SQL Command