Swift Core Data Format String Injection
…Or how I developed a love/hate relationship with format strings
The function is fairly straightforward, but the interesting part to a security professional is the NSPredicate declaration, which is defined as a format string that limits what data is returned from Core Data.
This format string should set off all sorts of alarm bells to anyone creating authentication routines. This application does not follow proper security best practices when creating the predicate or building the associated format string.
First of all, the use of the ‘LIKE’ statement enables simple bypass of authentication within this app. A failed attempt at logging into the app results in:
But the use of wildcards (this is the star ‘*’ for format strings)
results in successful entry into the app.
As in creation of secure SQL statements, use of the ‘LIKE’ keyword within NSPredicate creation should be avoided for everything but search utilities. Not only does it allow an attacker to present wildcards to Core Data, it also allows an attacker to enumerate through all of the relevant accounts in the database (a*, b*, etc). In fact, any keyword that allows the use of wildcards (e.g. LIKE, CONTAINS) or uses them implicitly (BEGINSWITH, ENDSWITH) should be avoided. A full description of format string syntax can be found in Apple’s Predicate Programming Guide.
Remediation of wildcard injection vulnerabilities is a fairly simple matter. First of all, convert the format string ‘LIKE’ keyword to ‘=’. A ‘LIKE’ query is unnecessary within the authentication routine.
This simple change corrects the easy authentication bypass seen in the previous example.
However, the format string is still vulnerable to injection and can be bypassed by using more complicated predicate instructions. For example, entering the string ’) OR 1=1 OR (password LIKE ‘* into the username field allows an attacker to successfully bypass the authentication requirement.
This attack is very similar to SQL Injection and is the result of string concatenation during format string creation. To complete the secure format string, move the user input to format string objects that are added at runtime as follows.
This fully escapes any attempts at injection using double quotes, which are required to escape out of the format string when built in this manner.
Finally, our application login function is secure from format string injection.
As an application penetration tester, identifying format string injection points is critical to determining the security of an application. During an assessment, identification of Core Data use can be difficult. Some fields may be linked to user preferences or backend web services. The only sure way to identify these vulnerabilities is through source code analysis. Given client limitations in providing an Xcode project for analysis, fuzz each available field with the values identified in this guide, including the single quote (‘), double quote (“), and wildcard character (*).
In future blog posts, we will explore other mobile security issues as they relate to Swift and iOS development, including the OWASP Mobile Top 10. In the meantime, feel free to reach out to me (seth [at] nvisium.com or @sethlaw) with issues or questions related to Swift Security.