Security Practice for iOS
Security and Privacy are some of the most crucial aspects of application development. Inappropriately managing and storing data can lead to security issues. The user’s data can be either insignificant (such as a service’s contact) or critical (such as credit card information). This document introduces some different approaches used to protect such data from falling into the wrong hands.
Store Sensitive Information in Keychain
Most applications store sensitive data of some kind, be it the user’s full name or access token. These data can be stored in
UserDefault but the issue with UserDefault is data are stored locally without encryption. This is risky and prone to hacking. The alternative to storing data with the benefit of encryption is
Keychain is an encrypted local database provided on the device. Apple provides an encrypted mechanism for
Keychain’s local database and makes it the best place to store secrets, like passwords and cryptographic keys. To use Keychain, it is advisable to use one of the wrappers or create a new one.
Managing Secret in CI
When it comes to Continous Integration (CI) such as using Bitrise or GitHub Actions to automate building, signing, and publishing to the App Store. Some sensitive data such as Apple ID, password, or API keys must be stored on the CI server for the CI pipelines to work successfully.
This is where CI Secret comes in. A secret is an encrypted value stored on the CI server. Github’s secret, for example, is write-only, meaning they can be overridden but contributors are not allowed to see the real value on Github Console. Some services even allow Organization Level secret where one value is shared among multiple projects.
Services provide a simple accessible Secret Terminal such as Github for users to manage their secrets.
Password Manager such as 1Password allows the user to store passwords and sensitive data and sync them across the team.
Using Password Manager command-line tool (CLI) let the developer invent a Continuous Integration/Development (CI/CD) flow with an extra layer of security. One example is syncing Fastlane with 1Password’s vault to keep CI credentials up to date.
The short explanation for SSL Pinning’s importance is: SSL Pinning can prevent a hacker from eavesdropping or fabricating fake data in the application’s network. Such an attack is possible when a hacker fakes a certificate and tricks the application into believing that it is real.
SSL Pinning means to store the certificate’s signature or the whole certificate inside the app and re-verify it with the certificate on API’s server.
SSL Pinning is possible using
URLSession or other Networking libraries such as Alamofire 5. To implement SSL Pinning, download certificate using OpenSSL script
openssl s_client -showcerts -connect google.com:443 </dev/null 2>/dev/null|openssl x509 -outform der >mycertfile.der
- 443 is the default HTTPS port and Alomofire uses
.derfile as default.
With Alamofire 5, SSL Pinning can be easily implemented by creating a
ServerTrustManager and a
ServerTrustPolicy with the URL of the pinning endpoint.
let serverTrustPolicies: [String: ServerTrustPolicy] = [ "test.example.com": .PinCertificates( certificates: ServerTrustPolicy.certificatesInBundle(), validateCertificateChain: true, validateHost: true ), "insecure.expired-apis.com": .DisableEvaluation ] let manager = Manager( serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies) )
On a jailbroken device, users can access multiple files that are off-limit such as
UserManager or dumped Keychain. This also gives a hacker more power to access the user’s sensitive data. It is a common practice to check for device security status before allowing the user to access the application’s functionality or limiting such device to limited functionality.
The best approaches to check for a jailbroken device are:
- Check for files related to Cydia or other common Jailbreak apps.
- Check for a jailbreak related path.
- Try launching Cydia via the URL Schemes.
- Check for read-write permission outside the sandbox environment.
App Transport Security
ATS is both an API and a Policy. By 2017, Apple requires all apps to use ATS reasonably. ATS is an option specified in the
Info.plist. The default configuration, suggested by Apple, blocks all network traffic that does not meet the minimum standard. In a simple term, any connection that is not a secure HTTPS will be rejected.
Inside ATS, Apple provides an exception in different levels, including media streaming, web-content, or excluding a specific domain. It is advisable to sparingly use these exceptions.
Manage Secret Keys in App
Sometimes sensitive data must be stored in the application’s source code such as a key for a Google Service. One way to mitigate the risk of this information leaking is to use cocoapods-keys.
Cocoapods-keys manages a project’s sensitive values by keeping them in the machine’s Keychain and provides an encrypted version in source code. Only at runtime will the keys have meaningful value.
There is currently no automatic check for a security vulnerability in iOS third-party libraries. The best way to check for a vulnerability is to read through its source code for any suspicious code. Also, check the issues and read the document thoroughly. The last step is to cross-checking with blacklist or using other security tools.