In a previous article, we saw an example of how an attacker could analyze an app in the search of vulnerabilities, and perform an XSS attack through the misuse of a web view. Hopefully after reading that, if you weren’t aware of how easy it is to at least get into some source code of an app published on the AppStore, now you are and you might be wondering if there are other ways to hack an iOS application and how to prevent it.
In this article, I will try to make a compilation of stuff to check if you want to ensure your app handles the most common security flaws. We will cover the following topics: system APIs, Data Handling, Data transportation, and App Hardening.
System API’s Usage
- Cryptography: Use CryptoKit whenever possible and check the correct usage of it. Avoid implementing custom crypto algorithms, apart from mistakes it could be an issue during AppStore reviews.
- App backgrounding: If the app handles any sensitive user data visible on the screen, you may want to implement a way to hide the content when the app is entering background mode (a snapshot of the app is taken at this moment and stored on the device). Check
- Handle the pasteboard securely: if pasteboard persistence is enabled, check that it’s being cleared when application backgrounds. Check
- Disable auto-correction for sensitive input fields or mark them as secure (passwords, credit cards, etc).
- Check for unwanted screen recordings and capturing of sensitive data. Subscribe to
UIScreen.isCaptured()in order to blur or hide the content.
- Keep in mind possible SQL injection or formatted strings injection vulnerabilities (the latter should not be an issue in Swift). Always use parameterized strings for NSPredicates and for formatted strings. E.g.: instead of using
NSPredicate(format: “(email LIKE ‘(user.email)’) AND (password LIKE ‘(user.password)’)”, nil)you should better use
NSPredicate(format: “(email = @) AND (password = @)”, user.email, user.password). If necessary, input text validation measures can be taken in place before saving to the database or interacting with the server.
- Setting a Protection Level for writing data: Check for the desired usage of Data Protection API, refer to
- CoreData and Realm store the databases as .db files that can be copied from your bundle, and easily read. Make sure to encrypt sensitive data before storing it in your database.
- Do not use
UserDefaultsto store any sensitive data, such as Access Tokens, subscription flags, or relevant account information. It can be easily accessed from outside the app. Use KeychainService API instead.
- Hash data using CryptoKit instead of Swift Standard Library hashing functions, as the latter have a high collision rate.
- Check Apple documentation in order to be sure of where to store your data in the file system.
- Configure App Transport Security (ATS) correctly, try to avoid adding exceptions for it.
- Use TLS/SSL securely. Check for any HTTP and replace by HTTPS, also check for any token being sent in the URL, they should always be sent in the headers.
- Keep in mind that HTTP Requests/Responses are cached by NSURLSession by default in a Cache.db file. If handling sensitive data, you may want to use
ephemeralSessionConfigurationwhich does not store cookies nor caches. The Global cache can also be disabled, check URLCache, you can assign 0 capacity to it and assign it to
- Check if you want to support third-party keyboards, and disable them if you believe they can be a threat to your data.
- Run XCode static analysis report. It can help to reveal memory leaks and other common bugs.
- Debug logs: keep in mind that logs are public by default, so never log sensitive information, and use the appropriate tools for it. Avoid the usage of prints.
- Code obfuscation: code can be easily reverse engineered, so in order to prevent that we can obfuscate the code. There are many third-party libraries for that matter.
- Do not abuse URL scheme usage, and validate each URL you will handle to prevent XSS attacks.
- Ensure you have a strong Jailbreak detection system, jailbreak is still possible for most devices and iOS. Attackers from jailbroken devices can reverse engineer your app and access sensitive data.
As you can see, there are a considerable amount of things to keep in mind when addressing the security of your application. And of course, these are not all of them, but at least with this list you have a point to start checking your application and think which items are relevant for your application security profile. I hope this short read was useful for you and that you keep it handy for the next time you have to audit an application’s security.