Secure Mobile Development Guide

This is a summary of Secure Mobile Development Guide.

CODING PRACTICES

Increase Code Complexity and Use Obfuscation

  • Restricting debuggers

    • Android applications should have android:debuggable=”false” set in the application manifest to prevent easy runtime manipulation by an attacker or malware.

    • On iOS you can make use of the PT_DENY_ATTACH

  • Trace Checking

    • Debugger tracing can be detected by checking the process status flags or using other techniques like comparing the return value of ptrace attach, checking the parent process, blacklisting debuggers in the process list or comparing timestamps on different parts of the program

  • Optimizations

    • In Android this can be achieved more easily by utilizing natively compiled libraries with the native development kit (NDK). In addition, using an LLVM Obfuscator or any protector SDK will provide better machine code obfuscation

  • Stripping binaries

    • Stripping binaries does not discard the Objective-C class or object-mapping data on iOS.

    • On Android you can reuse techniques used on GNU/Linux systems like sstriping or using UPX

Avoid Simple Logic

  • Consider a better programming paradigm, where privileges are enforced by the server when the session is not trusted, or by preventing certain data from being decrypted or otherwise available until the application can determine that the session is trusted using challenge/response, OTP, or other forms of authentication

  • it is recommended to declare all sanity check functions static inline.

  • more sophisticated approaches founded in secure coding principles may be worth further investigation.

Test Third-Party Libraries

  • Security auditing must thoroughly test third-party libraries and functionality as well

  • Upgrading to a new version of a third-party library (or OS version) should be treated as version of your app

  • On iOS, statically compile third-party libraries to avoid LD_PRELOAD attacks

Implement Anti-tamper Techniques

  • Use checksums, digital signatures and other validation mechanisms to help detect file tampering.

  • Android Sample

Securely Store Sensitive Data in RAM

  • Nullify any variables that hold keys after use

  • Avoid using immutable objects for sensitive keys or passwords such as in Android java.lang.String and use char array instead.

Understand Secure Deletion of Data

  • Operate under the assumption that any data written to a device can be recovered

  • Wherever possible, avoid storing sensitive data on the device

Avoid Query String for Sensitive Data

  • Use secure POST to send user data, with XSRF token protection.

  • Encrypting data using a non-zero initialization vector and temporary session keys can also help prevent a replay attack.

  • query string data can be encrypted using a temporary session key negotiated between hosts using secure algorithms, such as Diffie-Hellman

HANDLING SENSITIVE DATA

Implement Secure Data Storage

  • Add an additional layer of verified, third-party encryption (e.g., SQLCipher) to the data as device encryption is not sufficient

  • Android

    • using the standard cryptographic provider “AES” will often default to the less secure AES-ECB. Best practice is to specify AES-CBC or AES-GCM with a 256-bit key and a random IV generated by SecureRandom.

    • You should also derive the key from a passphrase using the well tested PBKDF2 (Password-Based Key Derivation Function)

Use SECURE Setting For Cookies

  • The Set-Cookie headers should use the “Secure” and “HTTPOnly” settings.

Fully Validate SSL/TLS

  • use certificate pinning to protect against MITM attacks

  • If certificate pinning cannot be implemented for any app functionality that handles highly sensitive data, implement proper certificate validation

    • Certificate validation: Certificates presented to the app must be fully validated by the app and be signed by a trusted root CA

    • Hostname validation: The app must check and verify that the hostname (Common Name or CN) extracted from the certificate matches that of the host with which the app intends to communicate

  • Android

    • Android 7.0 will only trust a preselected list of certificate authorities (CAs) maintained by the Android Open Source Project and will not trust custom CAs or CAs added by a user

    • Developers can also use the Network Security Configuration file for certificate pinning

    • CWAC-NetSecurity

  • iOS

Protect Against SSL Downgrade Attacks

  • Serve all traffic, even non-sensitive traffic,over TLS

  • Validate that SSL/TLS is active

  • Android recently added android:usesCleartextTraffic

  • iOS 9 and above require that you manually add exceptions for plaintext traffic.

Limit Use of UUID

  • avoid using any device-provided identifier to identify the device, especially if it’s integral to an implementation of device authentication.

  • recommend the creation of an app-unique "device factor" at the time of registration, installation, or first execution.

  • Apple recommends using the advertisingIdentifier - a unique identifier shared across all apps in the system.

Treat Geolocation Data Carefully

  • avoid storing GPS data

  • Unless required, do not log or store GPS information.

  • Cameras often geo-tags images. If this is a concern, make sure to strip the EXIF data from the image

  • Do not activate GPS in applications that will run at or near secure locations, whose coordinates or wireless network topology should not be reported back to vendors.

Institute Local Session Timeout

  • Any time the app is not used for more than 5 minutes, terminate the active session, redirect the user to the log-in screen, ensure that no app data is visible, and require the user to re-enter log-in credentials to access the app

  • After timeout, also discard and clear all memory associated with user data including any master keys use to decrypt that data

  • Also, make sure the session timeout occurs on both the client side and the server side

Implement Enhanced / Two-Factor Authentication

  • When sensitive data or transactions are involved, implement two-factor authentication

  • may not be feasible every time a user logs in but can be used at intervals or when accessing selected functions

  • Consider step-up authentication methods to provide normal access to non-transactional areas but require a second layer of authentication for sensitive functions

Protect Application Settings

  • Compile settings into the code when possible

  • Don’t store any critical settings in dictionaries or other files unless encrypted first

  • Ideally, encrypt all configuration files using a master key encrypted with a passphrase that is supplied by the user, or with a key provided remotely when a user logs into a system

Hide Account Numbers and Use Tokens

  • displaying partial numbers

  • store the partially hidden numbers

  • instead of account numbers, tokens be assigned to each account and provided to the client

Implement Secure Network Transmission Of Sensitive Data

  • Use SSL/TLS either with standard trust validation, or, for increased security, implement certificate pinning

  • For highly sensitive values, implement additional encryption in transit

Validate Input From Client

  • all input from the client should be must be treated as untrusted.

  • Services must thoroughly filter and validate input from the app and user.

Avoid Storing App Data in Backups

  • Android

    • By default, the allowBackup flag within an Android app’s Manifest file is set as true. Therefore, explicitly declare the allowBackup flag as false

  • iOS

    • avoid storing any sensitive data in plaintext within any of the files or folders within the app’s private directory or subdirectories

CACHING AND LOGGING

Avoid Caching App Data

  • Prevent HTTP caching

  • avoid caching of URL history and page data for any Web process such as registration.

Avoid Crash Logs

  • Ensure released apps are built without warnings and are thoroughly tested to avoid crashes.

  • Consider disabling NSAssert for iOS

  • avoid sending crash logs over the network in plaintext

  • Use secure development tools like clang-analyzer, coverity, ASAN and other linting utilities in order to identify all possible operations that can make the app crash

  • If the app is obfuscated and stripped, the developer will need keep an address-to-symbol database in order to recover meaningful backtraces in crashlogs

Limit Caching of Username

  • store a masked username instead of the actual username, and replace the username value in authentication with a hash value

Carefully Manage Debug Logs

  • REMOVE METHOD CALLS TO THE LOG CLASS IN RELEASE BUILDS

  • SET THE “ANDROID:DEBUGGABLE” FLAG TO “FALSE” IN PRODUCTION BUILDS

  • On iOS disabling the NSLog statements on will remove potentially sensitive information which can be intercepted and as an added benefit may slightly increase the performance of the app.

Be Aware of the Keyboard Cache

  • Disable the auto-correct feature for any sensitive information, not just for password fields.

  • Add an enterprise policy to clear the keyboard dictionary at regular intervals.

Be Aware of Copy and Paste

  • Where appropriate, disable copy/paste for areas handling sensitive data

WEBVIEWS

Prevent Framing and Clickjacking

  • Use X-FRAME-OPTIONS HEADER

    Header add X-FRAME-OPTIONS "DENY"
  • Basic frame busting javascript

    if( self != top ) {
      top.location = self.location ;
    }

Protect Against CSRF with Form Tokens

  • Each form submission should contain a token which was loaded with the form or at the beginning of a user session. Check this token on the server when receiving POST requests to ensure the user originated it.

IOS

Use the Keychain Carefully

  • When storing data in the keychain, use the most restrictive protection class (as defined by the kSecAttrAccessible attribute) that still allows your application to function properly

  • To prevent the exposure of keychain items via iTunes backup, use the ThisDeviceOnly protection class where practical

  • Finally, for highly sensitive data, consider augmenting protections offered by the keychain with application-level encryption.

Avoid Cached Application Snapshots

  • To protect sensitive data, block caching of application snapshots using API configuration or code

  • When applicationDidEnterBackground: method returns, the snapshot of the application user interface is taken, and it’s used for transition animations and stored in the filesystem. This method should be overridden and all the sensitive information in the user interface should be removed before it returns.

Implement Protections Against Buffer Overflow Attacks

  • Enable ARC

  • Implement full ASLR protection

    • can be enabled when compiling by command line with option -PIE

  • Implement stack-smashing protection

    • Compile the application with the -fstack-protector-all

Avoid Caching HTTP(S) Requests/Responses

  • set the cachePolicy property of the NSURLRequest to disable the caching of HTTP(S) requests and responses

Implement App Transport Security (ATS)

  • Enable ATS globally by linking to the iOS 9.0 or later SDK and NOT setting the NSAllowsArbitraryLoads key to Yes or True

Implement Touch ID Properly

  • When using Touch ID for authentication, store the app’s secret in the Keychain with an ACL assigned to that item.

  • Developers can use Touch ID enrollment changes to detect and prevent a physically proximate attacker from enrolling their own fingerprint in order to gain access to protected Keychain items.

    • read LAContext.evaluatedPolicyDomainState to check whether the evaluatedPolicyDomainState value has changed.

Android

Implement File Permissions Carefully

  • Do not create files with permissions of MODEWORLD_READABLE or MODE_WORLD_WRITABLE unless it is required as any app would be able to read or write the file even though it may be stored in the app’s private data directory

  • Do not use modes such as 0666, 0777, and 0664 with the chmod binary or syscalls accepting a file mode

Implement Intents Carefully

  • Components accessed via Intents can be public or private. it is easy to mistakenly allow the component to be or become public.

  • If a component does not need to be accessed by all other apps, consider setting a permission on the component declared in the Manifest

  • Data received by public components cannot be trusted and must be scrutinized

Check Activities

  • Activities can ensure proper behavior by checking internal app state to verify they are ready to load

    • For example, first see if the app is in the "unlocked" state and if not jump back to the lock screen.

  • input validation is recommended when operating on data provided by an untrusted source

  • Avoid intent filters on Activities if they are private, instead use explicit intent

Use Broadcasts Carefully

  • Use permissions to protect Intents in your application

Implement PendingIntents Carefully

  • Use PendingIntents as delayed callbacks to private BroadcastReceivers or broadcast activities, and explicitly specify the component name in the base Intent

Protect Application Services

  • When calling a service with sensitive data, validate that the correct service is being called and not a malicious service

Avoid Intent Sniffing

  • Do not pass sensitive data between apps using broadcast intents. Instead, use explicit intents

Implement Content Providers Carefully

  • Do not give a content provider write access unless it’s absolutely necessary

  • Limit access to the minimum required for an operation

  • Treat parameters passed to content providers as untrusted input and don’t use them directly in SQL queries without sanitation

  • Content providers that serve files based on a file name being passed to the provider should ensure path traversals are filtered out.

Follow WebView Best Practices

  • Disable JavaScript and Plugin support if they are not needed.

  • Disable local file access.

  • Disallow the loading of content from third-party hosts.

Avoid Storing Cached Camera Images

  • Do not transmit a check image using non-volatile storage on the device where check image artifacts may be left behind.

    • Create a SurfaceView that displays a camera preview or live preview of what the camera sensor is seeing

    • Insert and program a button that when pressed returns the camera preview as a pixel array

    • Finally, convert the pixel array to bitmap, compress it to a .jpg, encode it to Base64, and submit it to the remote location

Avoid GUI Objects Caching

  • Quit the app entirely when the user logs out.

  • Any time an activity is initiated or a screen is accessed, execute a check to determine whether the user is in a logged-in state

  • Nullify the data on a GUI screen before leaving the screen or logging out

Sign Android APKs

  • Sign a production app with a production certificate, not a debug certificate

  • Make sure the certificate includes a sufficient validity period (i.e., won’t expire during the expected lifespan of the app)

  • Google recommends that your certificate use at least 2048-bit encryption

  • Make sure the keystore containing the signing key is properly protected

  • Also, restrict access to the keystore to only those people that absolutely require it

Servers

Implement Proper Web Server Configuration

  • disable verbose errors

  • return the minimum amount of information in server responses.

  • change any default directories.

  • Administration or other restricted areas should not be publicly web-accessible unless absolutely necessary, and must be resistant to brute force attacks.

Properly Configure Server-side SSL

  • Ensure SSL certificates are properly installed and configured for the highest encryption possible.

  • TLSv1 is more than 10 years old and was found vulnerable to a “renegotiation attack” in 2009

  • Avoid weak ciphers, such as:

    • NULL cipher suite

    • Anonymous Diffie-Hellmann

    • DES and RC4 because of their vulnerability to crypto-analytical attacks (NOTE: iOS 10 disables RC4 by default)

  • Avoid weak protocols, such as:

    • SSLv2

    • SSLv3 because of its vulnerability to the POODLE attack - CVE-2014-3566 (NOTE: In iOS 10, the Apple Secure Transport API no longer supports SSLv3)

    • TLS 1.0 and earlier because the protocols are vulnerable to the CRIME

Use Proper Session Management

  • Web languages (e.g. Java, .NET) offer session management, which is well-developed and security tested

  • Keep server software up-to-date with security patches

  • Ensure the size of the session cookie is sufficient

Protect and Pen Test Web Services

  • web server must be thoroughly tested and hardened against malicious attack

  • Production server software should be updated to the latest versions, and hardened to prevent information disclosures regarding server software and interfaces

  • Authentication forms should not reflect whether a username exists

  • All login forms and forms/pages exchanging sensitive data should implement and require HTTPS

Protect Internal Resources

  • should be blocked from external access.

  • Any resource that does not require public Internet access should be restricted using firewall rules and network segmentation.