IOS Developer Cheat Sheet
- 1 Introduction
- 2 Basics
- 3 Remediation’s to OWASP Mobile Top 10 Risks
- 3.1 Insecure Data Storage (M1)
- 3.2 Weak Server Side Controls (M2)
- 3.3 Insufficient Transport Layer Protection (M3)
- 3.4 Client Side Injection (M4)
- 3.5 Poor Authorization and Authentication (M5)
- 3.6 Improper Session Handling (M6)
- 3.7 Security Decisions via Untrusted Inputs (M7)
- 3.8 Side Channel Data Leakage (M8)
- 3.9 Broken Cryptography (M9)
- 3.10 Sensitive Information Disclosure (M10)
- 4 References and Further Reading
- 5 Authors and Primary Editors
- 6 Other Cheatsheets
This document is written for iOS app developers and is intended to provide a set of basic pointers to vital aspects of developing secure apps for Apple’s iOS operating system. It follows the OWASP Mobile Top 10 Risks list.
From a user perspective, two of the best things one can do to protect her iOS device are: enable strong passwords, and refrain from jailbreaking the device. For developers, both of these issues are problematic, as they are not verifiable within an app’s sandbox environment. (Apple previously had an API for testing devices to see if they are jailbroken, but that API was deprecated in 2010.) For enterprises, strong passwords, along with dozens of other security configuration attributes can be managed and enforced via a Mobile Device Management (MDM) product. Small businesses and individuals with multiple devices can use Apple’s iPhone Configuration Utility (http://www.apple.com/support/iphone/enterprise/) and Apple Configurator (available in the Mac App Store) to build secure configuration profiles and deploy them on multiple devices.
Remediation’s to OWASP Mobile Top 10 Risks
Insecure Data Storage (M1)
Without a doubt, the biggest risk faced by mobile device consumers comes from a lost or stolen device. The information stored on the device is thus exposed to anyone who finds or steals another person’s device. It is largely up to the apps on the device to provide adequate protection of any data they store. Apple’s iOS provides several mechanisms for protecting data. These built in protections are quite adequate for most consumer-grade information. For more stringent security requirements (e.g., financial data), additional protections beyond those provided by Apple can be built into an application.
In general, an app should store locally only the data that is required to perform its functional tasks. This includes side channel data such as system logging (see M8 below). For any form of sensitive data, storing plaintext data storage in an app’s sandbox (e.g., ~/Documents/* ) should always be avoided. Consumer-grade sensitive data should be stored in secure containers using Apple-provided APIs.
- Small amounts of consumer grade sensitive data, such as user authentication credentials, session tokens, etc., can be securely stored in the device’s Keychain (see Keychain Services Reference in Apple’s iOS Developer Library).
- For larger, or more general types of consumer-grade data, Apple’s File Protection mechanism can safely be used (see NSData Class Reference for protection options).
- More data that exceeds normal consumer-grade sensitivity, if it absolutely must be stored locally, consider using a third party container encryption API that is not encumbered by the inherent weaknesses in Apple’s encryption (e.g., keying tied to user’s device passcode, which is often a 4-digit PIN). Freely available examples include SQLcipher (see http://sqlcipher.net). In doing this, proper key management is of utmost importance -- and beyond the scope of this document.
- For items stored in the keychain leverage the most secure API designation, kSecAttrAccessibleWhenUnlocked (now the default in iOS 5/6)
- Avoid using NSUserDefaults to store sensitive pieces of information
- Be aware that all data/entities using NSManagedObects will be stored in an unencrypted database file.
Weak Server Side Controls (M2)
Although most server side controls are in fact necessary to handle on the server side — and as such we refer the reader to the Web Service Security Cheat Sheet—there are several things that can be done on the mobile that aid in the work to be done on the server.
Design and implement the mobile client and the server to support a common set of security requirements. For example, information deemed sensitive on the server should be handled with equivalent due caution on the client side. Perform positive input validation and canonicalization on all client-side input data. Use regular expressions and other mechanisms to ensure that only allowable data may enter the application at the client end. Perform output encoding on untrusted data where feasible.
Insufficient Transport Layer Protection (M3)
Exposing sensitive data to eavesdropping attacks is a common issue with all networked applications, and iOS mobile apps are no exception.
Design and implement all apps under the assumption that they will be used on the most wide-open Wi-Fi networks on the planet. Make an inventory of all app data that must be protected while in transit. (Protections should include confidentiality as well as integrity.) The inventory should include authentication tokens, session tokens, as well as application data directly. Ensure SSL/TLS encryption is used when transmitting or receiving all inventoried data. (See CFNetwork Programming Guide.) Ensure your app only accepts properly validated SSL certificates. (CA chain validation is routinely disabled in testing environments; ensure your app has removed any such code prior to public release.) Verify through dynamic testing that all inventoried data is adequately protected throughout the operation of the app. Verify through dynamic testing that forged, self-signed, etc., certificates cannot be accepted by the app under any circumstances.
Client Side Injection (M4)
Data injection attacks are as real in mobile apps as they are in web apps, although the attack scenarios tend to differ (e.g., exploiting URL schemes to send premium text messages or toll phone calls).
In general, follow the same rules as a web app for input validation and output escaping. Canonicalize and positively validate all data input. Use parameterized queries, even for local SQLite/SQLcipher calls. When using URL schemes, take extra care in validating and accepting input, as any app on the device is able to call a URL scheme. When building a hybrid web/mobile app, keep the native/local capabilities of the app to a bare minimum required. That is, maintain control of all UIWebView content and pages, and prevent the user from accessing arbitrary, untrusted web content.
Poor Authorization and Authentication (M5)
Although largely a server side control, some mobile features (e.g., unique device identifiers) and common uses can exacerbate the problems surrounding securely authenticating and authorizing users and other entities.
In general follow the same rules as a web app for authentication and authorization. Never use a device identifier (e.g., UDID , IP number, MAC address, IMEI) to identify a user or session. Avoid when possible “out-of-band” authentication tokens sent to the same device as the user is using to log in (e.g., SMS to the same iPhone). Implement strong server side authentication, authorization, and session management (control # 4.1-4.6). Authenticate all API calls to paid resources (control 8.4).
Improper Session Handling (M6)
Similarly, session handling is in general, principally a server task, but mobile devices tend to amplify traditional problems in unforeseen ways. For example, on mobile devices, “sessions” often last far longer than on traditional web applications.
For the most part, follow sound session management practices as you would for a web application, with a few twists that are specific to mobile devices. Never use a device identifier (e.g., UDID, IP number, MAC address, IMEI) to identify a session. (Control 1.13) Use only tokens that can be quickly revoked in the event of a lost/stolen device, or compromised session. Protect the confidentiality and integrity of session tokens at all times (e.g., always use SSL/TLS when transmitting). Use only trustworthy sources for generating sessions.
Security Decisions via Untrusted Inputs (M7)
While iOS does not give apps many channels for communicating among themselves, some exist—and can be abused by an attacker via data injection attacks, malicious apps, etc.
The combination of input validation, output escaping, and authorization controls can be used against these weaknesses. Canonicalize and positively validate all input data, particularly at boundaries between apps. When using URL schemes, take extra care in validating and accepting input, as any app on the device is able to call a URL scheme. Contextually escape all untrusted data output, so that it cannot change the intent of the output itself. Verify the caller is permitted to access any requested resources. If appropriate, prompt the user to allow/disallow access to the requested resource.
Side Channel Data Leakage (M8)
Side channels refer here to data I/O generally used for administrative or non-functional (directly) purposes, such as web caches (used to optimize browser speed), keystroke logs (used for spell checking), and similar. Apple’s iOS presents several opportunities for side channel data to inadvertently leak from an app, and that data is often available to anyone who has found or stolen a victim’s device. Most of these can be controlled programmatically in an app.
Design and implement all apps under the assumption that the user’s device will be lost or stolen. Start by identifying all potential side channel data present on a device. These sources should include, at a bare minimum: web caches, keystroke logs, screen shots, system logs, and cut-and-paste buffers. Be sure to include any third party libraries used. Never include sensitive data (e.g., credentials, tokens, PII) in system logs. Control iOS’s screenshot behavior to prevent sensitive app data from being captured when an app is minimized. Disable keystroke logging for the most sensitive data, to prevent it from being stored in plaintext on the device. Disable cut-and-paste buffer for the most sensitive data, to prevent it from being leaked outside of the app. Dynamically test the app, including its data stores and communications channels, to verify that no sensitive data is being inappropriately transmitted or stored.
Broken Cryptography (M9)
Although the vast majority of cryptographic weaknesses in software result from poor key management, all aspects of a crypto system should be carefully designed and implemented. Mobile apps are no different in that regard.
Never “hard code” or store cryptographic keys where an attacker can trivially recover them. This includes plaintext data files, properties files, and compiled binaries. Use secure containers for storing crypto keys; alternately, build a secure key exchange system where the key is controlled by a secure server, and never stored locally on the mobile device. Use only strong crypto algorithms and implementations, including key generation tools, hashes, etc. Use platform crypto APIs when feasible; use trusted third party code when not. Consumer-grade sensitive data should be stored in secure containers using Apple-provided APIs.
- Small amounts of data, such as user authentication credentials, session tokens, etc., can be securely stored in the device’s Keychain (see Keychain Services Reference in Apple’s iOS Developer Library).
- For larger, or more general types of data, Apple’s File Protection mechanism can safely be used (see NSData Class Reference for protection options).
To more securely protect static data, consider using a third party encryption API that is not encumbered by the inherent weaknesses in Apple’s encryption (e.g., keying tied to user’s device passcode, which is often a 4-digit PIN). Freely available examples include SQLcipher (see http://sqlcipher.net).
Sensitive Information Disclosure (M10)
All sorts of sensitive data can leak out of iOS apps. Among other things to remember at all times, each app’s compiled binary code is available on the device, and can be reverse engineered by a determined adversary.
Anything that must truly remain private should not reside on the mobile device; keep private information (e.g., algorithms, proprietary information) on the server. If private information must be present on a mobile device, ensure it remains in process memory and is never unprotected if it is stored on the device. Never hard code or otherwise trivially store passwords, session tokens, etc. Strip binaries prior to shipping, and be aware that compiled executable files can still be reverse engineered.
References and Further Reading
OWASP Top 10 Mobile Risks presentation, Appsec USA, Minneapolis, MN, 23 Sept 2011. Jack Mannino, Mike Zusman, and Zach Lanier.
“iOS Security”, Apple, May 2012, http://images.apple.com/ipad/business/docs/iOS_Security_May12.pdf
“Deploying iPhone and iPad: Apple Configurator”, Apple, March 2012, http://images.apple.com/iphone/business/docs/iOS_Apple_Configurator_Mar12.pdf
“iPhone OS: Enterprise Deployment Guide”, Apple, 2010, http://manuals.info.apple.com/en_US/Enterprise_Deployment_Guide.pdf
“iPhone in Business”, Apple resources, http://www.apple.com/iphone/business/resources/
Apple iOS Developer website.
"iOS Application (in)Security", MDSec - May 2012, http://www.mdsec.co.uk/research/iOS_Application_Insecurity_wp_v1.0_final.pdf
Authors and Primary Editors
Ken van Wyk ken[at]krvw.com
OWASP Cheat Sheets Project Homepage