Table of Contents
In a previous article we saw an example on how an attacker could analyse 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 most common security flaws. We will cover the following topics: system API’s, Data Handling, Data transportation and App Hardening.
System API’s Usage
- Cryptography: Use CryptoKit whenever possible and check 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
applicationDidEnterBackground.
- Handle the pasteboard securely: if pasteboard persistence is enabled, check that it’s being cleared when application backgrounds. Check
UIPasteboardNameFind
andUIPasteboardNameGeneral
. - 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
userDidTakeScreenshotNotification
and useUIScreen.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 useNSPredicate(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. - Ensure a proper use of Web Views, check and validate possible javascript code injection.
Data Handling
- Setting a Protection Level for writing data: Check for desired usage of Data Protection API, refer to
NSData.WritingOptions
andURLFileProtection
. - 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 to your database.
- Do not use
UserDefaults
to 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 on where to store your data in the file system.
Data Transportation
- 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
ephemeralSessionConfiguration
which does not store cookies nor caches. Global cache can also be disabled, check URLCache, you can assign 0 capacity to it and assign it toURLCache.shared
.
App Hardening
- Check if you want to support third party keyboards, and disable them if you believe it can be a threat for 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 schemes 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’s. Attackers from jailbroken devices can reverse engineer your app and access sensitive data.
Conclusion
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.
Author
-
iOS Developer working in the software development industry with agile methodologies. Skilled in Swift, objective-C, Python, PostgreSQL, SQL, PHP, and C++. More than 8 years of experience working as iOs Developer, following the best practices.
View all posts
One Comment
Jake Clarke
Thanks for the tips, I am definitely going to use them.