Secure Mobile Development Guidelines

This is a summary of how to develop secure mobile applications. It is generated based on the contents form the following sources:

Authentication and Password Management

  1. Instances where the mobile application requires a user to create a password or PIN (eg for offline access), the application should never use a PIN but enforce a password which follows a strong password policy.

  2. Mobile devices may offer the possibility of using password patterns which are never to be utilized in place of passwords as sufficient entropy cannot be ensured and they are easily vulnerable to smudge-attacks.

  3. Mobile devices may also offer the possibility of using biometric input to perform authentication which should never be used due to issues with false positives/negatives, among others.

  4. Wipe/clear memory locations holding passwords directly after their hashes are calculated.

  5. Based on risk assessment of the mobile application, consider utilizing two-factor authentication.

  6. In scenarios where offline access to data is needed, add an intentional X second delay to the password entry process after each unsuccessful entry attempt (2 is reasonable, also consider a value which doubles after each incorrect attempt).

  7. In scenarios where offline access to data is needed, perform an account/application lockout and/or application data wipe after X number of invalid password attempts (10 for example).

  8. Based on a risk evaluation, consider adding context information (such as IP location, etc…) during authentication processes in order to perform Login Anomaly Detection.

  9. Instead of passwords consider using longer term authorization tokens that can be securely stored on the device

  10. Consider using asymmetric cryptography for authentication and authorization purposes.

  11. If a password based authentication mechanism is used, ensure that a strong a password policy is being followed. Consider enforcing restrictions about password length and formation, reuse of old user passwords, use of common passwords, password duration, etc. However, do not maintain any representation of the password strength in application storage or the back-end server as it may expose the password in preimage attacks.

  12. Do not reveal registered usernames and remove any fingerprint of their existence from verbose error messages.

  13. Use authentication that ties back to the end user identity (rather than only to the device identity).

  14. If the credentials or keys appear in the user interface (UI) components, try to release the UI frames immediately after use.

  15. Ensure passwords and keys are not visible in cache or logs.

Communication Security

  1. Ensure the application actually and properly validates (by checking the expiration date, issuer, subject, etc…) the server’s SSL certificate.

  2. The application should only communicate with and accept data from authorized domain names/systems.

  3. To protect against attacks which utilize software such as SSLStrip, implement controls to detect if the connection is not HTTPS with every request using HTTP Strict Transport Security (HSTS).

  4. When using SSL/TLS, use certificates signed by trusted Certificate Authority (CA) providers.

  5. Enforce secure TLS versions. Safely abort the connection, if this is not possible

  6. Introduce certificate pinning.

  7. Design the user interface in a way that warns the user if the peer certificate does not match the expected certificate and provide the ability to abort any further interaction.

  8. SMS and MMS should not be used to send sensitive data

  9. Always use platform supported or vetted frameworks for establishing secure communication channels.

  10. Ensure adequate logs on the server are retained about established connections.

Data Storage and Protection

  1. Classify data storage according to sensitivity and apply controls accordingly (e.g. passwords, personal data, location, error logs, etc.). Process, store and use data according to its classification

  2. Store sensitive data on the server instead of the client-end device, whenever possible. Assume any data written to device can be recovered.

  3. When storing sensitive data on the device, use a file encryption API provided by the OS or other trusted source.

  4. Use file encryption APIs which use a secret key protected by the device unlock code and deletable on remote wipe if available.

  5. Beyond the time required by the application, don’t store sensitive information on the device (e.g. GPS/tracking).

  6. Do not store temp/cached data in a world readable directory. Assume shared storage is untrusted.

  7. Use the PBKDF2 function to generate strong keys for encryption algorithms while ensuring high entropy as much as possible. The number of iterations should be set as high as may be tolerated for the environment (with a minimum of 1000 iterations) while maintaining acceptable performance.

  8. Sensitive data (such as encryption keys, passwords, credit card #’s, etc…) should stay in RAM for as little time as possible.

  9. Encryption keys should not remain in RAM during the instance lifecycle of the app. Instead, keys should be generated real time for encryption/decryption as needed and discarded each time.

  10. Address Space Layout Randomization (ASLR) should be taken advantage of to limit the impact of attacks such as buffer overflows.

  11. When displaying sensitive information (such as full account numbers), ensure that the sensitive information is cleared from memory (such as from the webView) when no longer needed/displayed.

  12. Do not store sensitive data on external storage like SD cards if it can be avoided.

  13. Make use of remote wipe and kill switch APIs to remove sensitive information from the device in the event of theft or loss.

  14. Use a time based (expiry) type of control which will wipe sensitive data from the mobile device once the application has not communicated with its servers for a given period of time.

  15. Automatic application shutdown and/or lockout after X minutes of inactivity (e.g. 5 mins of inactivity).

  16. Avoid cached application snapshots in iOS: iOS can capture and store screen captures and store them as images when an application suspends. To avoid any sensitive data getting captured, use one or both of the following options: 1. Use the ‘willEnterBackground’ callback, to hide all the sensitive data. 2. Configure the application in the info.plist file to terminate the app when pushed to background (only use if multitasking is disabled).

  17. Prevent applications from being moved and/or run from external storage such as via SD cards.

  18. Verify that OS level storage encryption is enabled and the device is protected by a PIN or passphrase.

  19. Consider the security of the whole data lifecycle in writing your application (collection over the wire, temporary storage, caching, backup, deletion, etc.).

  20. Ensure that during application removal (uninstall operation), any confidential user data and the corresponding app-specific credentials are deleted from the execution environment, the device, and any other storage medium.

  21. Apply the principle of minimal disclosure - only collect and disclose data which is required for business use of the application. Identify in the design phase what data is needed, its sensitivity and whether it is appropriate to collect, store and use each data type.

  22. Use non-persistent identifiers which are not shared with other apps wherever possible (e.g., do not use the device unique hardware identifiers such as IMEI or UDID as an identifier).

  23. Application developers may want to incorporate an application-specific "data kill switch" into their products, to allow the per-app deletion of their application’s sensitive data when needed (strong authentication is required to protect misuse of such a feature).

  24. Do not leak permission-protected data to other applications. This occurs when specific permissions are required to access the data, however an app that has been granted these permissions makes the data available to all other apps without restrictions (e.g., over IPC)

  25. Restrict the data that is shared with other applications (e.g., by implementing an Android Content Provider). This can be accomplished using fine-grained permissions (ensure permissions are protected using signature protection level on Android).

  26. Restrict broadcast messages (e.g., Android Broadcast Intents) to authorized applications and audit the application’s broadcast messages for sensitive content.

  27. Do not allow third party keyboards to be used for inputs that may contain sensitive data (e.g., credentials, credit card information). Prefer a custom keyboard for such inputs instead

  28. Disable Auto Correction and Autosuggestion for inputs that contain sensitive data.

  29. Disable cut, copy and paste functionalities for inputs that may contain sensitive data or restrict the pasteboard to be accessible only from this application.

  30. Introduce input field masking for inputs that contain sensitive data (e.g., passwords).

  31. Leverage the hardware-level encryption support for files at the highest supported security level.

  32. If the application while the device is locked needs to write data to a file, use temporary caches instead of weakening the encryption mode. Swap the file content when the device is unlocked and the original file is accessible again.

  33. Prefer using framework functionality (e.g., Android Content Provider) for data sharing instead of using file system permissions or a custom access scheme on platforms that support this (e.g., Android).

  34. Inspect application-initiated custom notification messages for sensitive content

  35. Exclude sensitive application files from device backups and cloud synchronization services.

  36. If the application allows the arbitrary selection of files from the device storage, consider the use of a white-list to restrict access only to the intended (absolute) file paths

  37. Delete application caches on app termination

  38. Database files that contain sensitive data (e.g., iOS WebView caches) must be manually removed from the file system. Deleting records using the database API will not necessary lead to complete data removal from database structure.

  39. Disable application logging and debug messages in production releases. All exceptions should be handled securely.

  40. In the case that the application includes embedded web browsing capabilities (e.g., WebViews), clear stored cookies on app termination or use in-memory cookie storage

Session Management

  1. Do not rely on client side security controls. Both authentication and authorization controls should be implemented on the server side.

  2. Ensure that the session management is handled securely after the initial authentication, using appropriate secure protocols.

  3. Perform a check at the start of each activity/screen to see if the user is in a logged in state and if not, switch to the login state.

  4. When an application’s session is timed out, the application should discard and clear all memory associated with the user data, and any master keys used to decrypt the data.

  5. Session tokens should be revocable (particularly on the server side).

  6. Use lower timeout values to invalidate expired sessions (in contrast to the typical timeout values on traditional (non-mobile) applications).

  7. Use unpredictable session identifiers with high entropy.

  8. Clear any maintained sensitive data on session termination. Reset the application state and request for user re-authentication.

Secure the backend services and the platform server and APIs

  1. Carry out a specific check of your code for sensitive data unintentionally transferred between the mobile device and web-server back-ends and other external interfaces

  2. All back-end services (web services) for mobile apps should be tested for vulnerabilities periodically

  3. Disable metadata publishing (e.g., metadata for WSDL documents and for WSDL derived objects), in order to prevent unintentional disclosure of potentially sensitive service metadata

  4. Ensure that the back-end platform (server) is running with a hardened configuration with the latest security patches applied to the OS, web server and other application components.

  5. Ensure adequate logs are retained on the back-end in order to detect and respond to incidents and perform forensics

  6. Protect the back-end from client initiated log injections that may corrupt or forge the history of events2

  7. Employ rate limiting and throttling on a per-user/IP basis

3rd Party libraries

  1. Vet the security/authenticity of any third party code/libraries used in your mobile application (e.g. making sure they come from a reliable source, will continue to be supported, contain no backdoors) and ensure that adequate internal approval is obtained to use the code/library.

  2. Track all third party frameworks/APIs used in the mobile application for security patches and perform upgrades as they are released.

  3. Pay particular attention to validating all data received from and sent to non-trusted third party apps (e.g. ad network software) before incorporating their use into an application.

  4. Avoid using third-party libraries that contain main processor-only cryptographic implementations. Prefer using cryptographic framework provided by a platform supported secure hardware (e.g. TEE, SE).

  5. Software components that are no longer supported by the vendor or developer must not be used

  1. Check whether your application is collecting personal data

  2. Create a privacy policy covering the usage of personal data and make it available to the user especially prior to making consent choices

  3. Prior to using personal data consent should be obtained.

  4. Consent may be collected in 3 main ways:

    1. At install time.

    2. At run-time when data is sent.

    3. Via “opt-in” mechanisms where a user has to explicitly turn on a setting

  5. It should be possible for the user to withdraw consent at any time in the application

  6. Audit communication mechanisms to check for unintended leaks

  7. Keep a record of user consent for the processing of different types of personal data

  8. Check whether data collection (from the user’s device) is not excessive with regard to the consent that has been granted by the user

  9. Consider taking advantage of built-in features to require access to device sensors and data

  10. Minimize access to sensor data whenever possible

  11. Reduce data granularity and anonymize data on the device instead of remotely

  12. Require consent prior to providing user data to third parties

  13. Reduce retention period on the mobile or remotely to the minimum amount of time needed to provide the service

  14. Use privacy enhancing technologies, that support data minimization, anonymization and security of personal data

  15. The default settings of the application should provide maximum privacy and security protection for the user

Protect paid resources

  1. Maintain logs of access to paid-for resources in non-repudiable format

  2. Check for anomalous usage patterns in paid-for resources usage and trigger re-authentication

  3. Consider a white-list model by default for paid-for resources addressing

  4. Warn user and obtain consent for any cost implications for app behaviour

  5. Follow the OS/device vendor guidelines for implementing In-App payment:

    1. Implement validation of payment receipts on the backend server not on the device

    2. Pay specific attention when integrating payment acceptance from a third party wallet

Secure software distribution

  1. Applications must be designed and provisioned to allow updates for security patches, taking into account the requirements for approval by app-stores and the extra delay this may imply

  2. Distributing apps through official app-stores

  3. Provide feedback channels for users to report security problems with apps such as a security email address

  4. If an enterprise app store is used, protect the application signing key with the utmost care

  5. Out-of-appstore security updates should be shipped using an encrypted connection and their content should be verified before applying the update

  6. Resources used by apps that are updated outside of the app-store normal mechanism must be signed. Apps must verify the signature before accepting the updated resource

  7. Do not deploy apps with ad-hoc signing certificates used for development and testing

  8. Do not generate one application for multiple environments

Handle runtime code interpretation correctly

  1. Filter user data passed to interpreters.

  2. Define comprehensive escape syntax as appropriate.

  3. Do not reveal sensitive information such as usernames, personal data and others through error messages.

  4. Deny interpreted code direct access to user data and encrypted storage.

  5. Strip unused functionalities from interpreters.

  6. Limit size of input data passed to interpreters.

Check device and application integrity

  1. Check the device/platform integrity to ensure that the device is not modified.

  2. Check the application integrity, check that the application and its resources are not modified

  3. Disable developer features

    1. Disable debugging in the application settings.

    2. Check if the device is in developer mode if supported by platform (e.g., Android).

    3. Check if debugger is attached and/or if the process is being traced. On platforms with managed code check for managed and native code debuggers

Code Obfuscation

  1. Obfuscate all sensitive application code where feasible by running an automated code obfuscation program.

  2. For applications containing sensitive data, implement anti-debugging techniques (e.g. prevent a debugger from attaching to the process; android:debuggable=”false”).

  3. Address Space Layout Randomization (ASLR) should be taken advantage of to hide executable code which could be used to remotely exploit the application and hinder the dumping of application’s memory.

Protect the application from client side injections

  1. In the case that the application includes embedded web browsing capabilities (e.g., WebViews), restrict access to third party domains that do not comply with the required security standards, disable any unused platform supported functionalities, such as the plugins, local file accessibility, local content provider (content URL) accessibility and the dynamic code (e.g., JavaScript)execution support. Furthermore, avoid using full screen web interfaces since these can be abused from attackers to create fake application screens

  2. Avoid using API calls that provide bridging of dynamic code (e.g., JavaScript) with native code (e.g., Objective-C) since an injection in the dynamic code will lead to native code execution

  3. In the case that the application uses JavaScript code running in the context of a file scheme URL, it is recommended to disable any unused platform supported attributes, such as accessing content from other file scheme URL and content from any origin

  4. Prevent interaction events when the application is obscured by another interface in the presentation layer in order to mitigate tapjacking attacks

  5. In the case that the application requests custom permissions, and older platforms are supported (e.g., earlier than Android 5.0), always verify on the first run of the app that no other application has previously requested the same permissions

  6. Always follow the domain name registration infrastructure to declare a custom permission, in order to avoid any collisions with other apps

  7. Restrict what apps can cause an application component (e.g., Android Activity) to start or are able to interact with it (e.g., Android Service and Content Provider)

  8. Restrict the third party applications whose broadcast messages will be accepted by the application.

  9. In the case that the application utilizes a platform provided download manager, always verify that the received manager’s notifications are related to application’s initiated downloads

  10. Always verify dynamic code downloads and application updates at the client side.

  11. Always validate server responses when using backend APIs.

  12. Mitigate SQL injections, local file inclusion, JavaScript injections, XML injections. When dealing with dynamic queries (e.g., SQL queries with untrusted inputs) or Content-Providers ensure you are using parameterized queries. Always validate user provided inputs that will be used for file accessing purposes or as part of a dynamic code execution. Use a vetted framework for XML operations.

  13. Protect from memory corruptions in applications that are developed using a programming language which supports explicit memory management (e.g., Objective-C, C, C++).

  14. Do not use insecure cached data in HTTP connections and in embedded web browsing capabilities (e.g., WebViews).

  15. In platforms that support custom applications with accessibility permissions (e.g., Android), exclude sensitive user interface elements from being accessed by accessibility applications

  16. Avoid populating webviews loaded from the file URI scheme with user supplied DOM input

Ensure correct usage of biometric sensors and secure hardware

  1. Always verify that there is a biometric sensor (e.g., Fingerprint reader) present and available on the device before using the API for authentication purposes

  2. Always verify that the biometric sensor/secure hardware authentication policy of the in-use platform complies with the application’s authentication policy (passcode required after cold boot, biometric sensor authentication expiration, adding a fingerprint requires pin/passcode/biometric authentication, requirement for biometric sensor being individually paired with secure hardware)

  3. Ensure that there are enrolled data using the biometric sensor (e.g., user’s fingerprints and/or user’s iris are registered) before using the API for authentication purposes

  4. Ensure that the enrolled biometric data has not been changed since the activation of the authentication control using the biometric sensor

  5. The application should not use the biometric sensor for just verifying user presence (e.g., iOS LocalAuthentication). Instead, the application should use the biometric sensor to access keys stored using a hardware backed keystore/keychain and protected with keychain access control lists (ACL).

  6. Ensure that the key material is bound to the secure hardware (e.g., TEE, SE) in platforms that this is optional (e.g., Android)

  7. For keys whose key material is inside a secure hardware (e.g., TEE, SE), ensure that cryptographic and user authentication authorizations are also enforced by secure hardware, in platforms that this is optional (e.g., Android).

  8. The application should avoid using temporal validity interval authorizations, since they are unlikely to be enforced by the secure hardware because it normally does not have an independent secure real-time clock.

  9. Verify that the application’s authentication policy complies with the possibility that different people may enroll for biometric authentication in the same device.