2021-12-01 16:21:48

Toolkit: Security Checklist for Mobile App Developers - 2

Rationale

Session Management

The Session Timeout Shall Be of a Reasonable Value and Configurable

This is a generic requirement that will depend on the context.

Session Data Shall Be Deleted When a Session Is Aborted or Terminated Unexpectedly

Abnormal termination of an application operation may leave data cached. Therefore, in case of a crash or an unexpected termination of the application, it should be foreseen that all session data is deleted, even if the app is built to not store any sensitive data in the first place.

GET Commands Shall Not Be Used for Querying Sensitive Data; POST Commands Should Be Preferred Over HTTPS

When dealing with web code, it is safer to use POST requests, rather than GET requests, to query sensitive data. Even when TLS is employed, GET requests can be logged unprotected in locations beyond the application's control, such as the browser history.

Error Handling and Logging

The App Shall Not Log Sensitive Data on the System Log or File System

Data such as passcodes, passwords and other credentials, as well as private information such as identifiers, names, phone numbers and payment information, must not be logged. This prevents attackers that may try to manipulate the app to recover this information.

The Crash and Debug Logs Shall Not Contain Sensitive Data

Logged data stored during crashes is typically sent to the server or stored in the app, and is used to discover bugs in the app. This data shall not contain sensitive data, such as passcodes, passwords and other credentials, as well as private information such as identifiers, names, phone numbers and payment information.

Permissions

Permissions and Resources Granted to Apps (i.e., AndroidManifest.xml, iOS Entitlements) Shall Be Limited to What the App Needs to Operate (If Third-Party Code Is Reused, This Is Valid for the Third-Party Code as Well)

It is often the case that apps request more privileges and access to information than they really require to operate. This makes the app a target for attackers that may try to exploit the application’s permissions to obtain access to the user’s private information. Apps sometimes run with more privileges than needed because developers reuse existing libraries in their apps. These libraries often request certain permissions by default.

Developers shall ensure that their code and the external libraries they leverage do not request unnecessary permissions.

As a concrete example, in Android, MODE_WORLD_WRITEABLE and MODE_WORLD_READABLE modes allow access to any applications, as well as any data format. This could lead to malicious applications accessing sensitive data. Therefore, Android apps shall not create files with permissions of MODE_WORLD_READABLE or MODE_WORLD_WRITABLE.

Tampering Protection

Method Swizzling Shall Not Be Adopted (in Rare Exceptions, When Swizzling Needs to Be Used, Thorough Security Testing Against Exploits Must Be Provided and Documented)

Method swizzling is a technique that certain developers use in iOS Objective-C and Swift apps (and, to a lesser extent, in Android Java apps). Swizzling is not inherently malicious, and can provide certain performance benefits; however, if used improperly, it could cause security issues. Swizzling with iOS apps consists of dynamically redirecting method invocations. This dynamicity makes it possible for an attacker to redirect to a malicious method, rather than the intended one.

Third-Party Libraries Used Shall Be Tested and Validated as Free From Vulnerabilities and Malicious Code

Developers tend to use third-party libraries that can support the functionality they want to have in the application. These third-party libraries are often the main source of vulnerabilities for applications, either because they have not been written properly, or they hold an excessive number of permissions. Only reputable APIs shall be used, and they shall be validated before use to verify they are not malicious and do not introduce any vulnerabilities.

Apps Shall Use Server-Side Checks and Shall Not Rely on Client-Side Checks for Functions That Can Be Manipulated to Steal Information or Compromise the App

If checks such as verifying a user identity or the integrity of the application are left to the client residing on the mobile app, then there is a risk that the attacker may compromise the client and bypass those controls. Server-side checks require that the client provides proof to the server, which validates the controls; therefore, an attacker cannon bypass them.

The App Shall Minimize Communication With Other Apps and Take Appropriate Measures When Doing So

Apps that are written to freely share data with third-party apps can be a source of leakage, as they can be exploited by attackers. Therefore, if apps are not meant to share data, they should be locked down. For example, in Android, an app that does not share data should report android:exported=“false” in the application manifest.

If apps are meant to share data with other apps, precautions should be taken. In the same Android example, if sharing between corporate apps is employed, android:protectionLevel “signature” should be selected, so that the system checks that both apps are signed with the same certificate.

Immutable Structures That Cannot Be Overwritten When Not Used Shall Be Avoided for Sensitive Data, and Mutable Structures Shall Be Preferred

Immutable objects can only be written once and cannot be erased. This is not only inconvenient, but can be dangerous when dealing with sensitive data.

The App Shall Not Support Implicit Intents for Android

An intent in Android programming is a description of an action that an app can perform. There are two possible ways to resolve an intent: explicit and implicit. Implicit intents do not specify the target component (for example, the application recipient of the data) in an explicit manner. In such a case, to identify the recipient Android compares the content of the intent to potential recipient components, thanks to component filters.

Since Android 5.0, the Android platform has been eliminating the option for an implicit intent, because a malicious application could impersonate itself as one able to receive and handle the data from an implicit intent. Information shall be sent only with explicit intents to other components of the Android system.

The App Shall Use Address Space Layout Randomization (ASLR), Where Available

Address space layout randomization (ASLR) is a feature supported on most modern mobile devices. It adds entropy to the way an app is memorized on a device. This randomness makes it harder for an attacker to exploit the app.

The App Shall Validate All Input Received

Input validation consists of verifying that data input in the app is in the expected format and length. This avoids many of the most common attack techniques, such as buffer overflows. These techniques try to take advantage of the lack of input validation to send unforeseen input that can carry out unwanted actions.

In the specific case of an iOS app that has registered a URL scheme, it shall validate the input received from the URL. It should only be able to receive specific input, to avoid directory traversals, buffer overflows and other similar attacks.

The App Shall Have the Necessary Measures in Place to Avoid Race Conditions

Race conditions arise in situations in which a control on a specific condition is conducted to lead to the app taking an action. A typical control can be verifying that the user is authorized to request a specific file or specific information before fetching it. Race conditions occur when the control is performed on one app or one user, but the resource is accessed by a different app or user. An attacker can exploit this to access resources without authorization.

Where the intended resource is shared, race conditions do not solely depend on the specific app. However, there are some precautions that developers can take to minimize risks of race conditions. Precautions depend on the specific context. When dealing with temporary files that can be overwritten, a typical precaution is to ensure that a temporary file with the same name exists. Another typical action is resource locking for the duration of the intended operation.

The App Shall Be Able to Detect Privilege Escalation Conditions, Including Jailbreak/Rooting and Unlocked Bootloaders

This is a requirement for Type A apps and a recommendation for Type B apps. These sorts of checks are habitually delegated to enterprise mobility management (EMM) tools on workforce devices, while they are employed by the app itself in consumer-facing apps.

These are checks that are performed before or during app operation and come in the form of libraries. The most common form of check is detection of Android rooting or iOS jailbreak. Among the various techniques used to detect this practice is looking for the presence of Cydia on the device (a popular app for jailbroken iOS devices). Another control can be that the app is not running in a debugger.

Controls of this nature may be considered privacy-invasive, because they investigate outside the boundaries of the application. The terms of agreement of the application (or the mobile policy, for enterprise apps) should reflect this and inform the user.

The way to handle these checks will depend on the context. Aborting the app may be acceptable in high-security B2E situations, but customer-facing apps should use this information to categorize the user in terms of risk, rather than denying service.

The App Shall Perform Checks for Indicators of Compromise

Mobile platforms have been providing developers with tools to perform checks of the status of a device, beyond simply checking for jailbreak/rooting detection. Although the functionality is mainly relevant to Android, the main active threats are in Android.

Developers should take advantage of this inbuilt functionality in the Android platform to ensure that the environment the device is running in is not compromised. A few examples are checks to see whether there is malware on the device, verify whether a device is a bot and perform an overall check for indicators of compromise on the device.

The App Code Shall Be Obfuscated

Obfuscation is typically done for consumer-facing apps and apps with sensitive data or intellectual property. Certain commercial app stores will also add their own obfuscation to apps.

Code obfuscation scrambles the code, making it harder for the attacker to understand what the application is doing. This may, for example, be achieved by renaming classes that may give away the application’s functioning.

Obfuscation makes it harder for an application to be attacked, and is a dissuasive measure. However, with enough time and effort, the protections of obfuscation can be bypassed, and developers should ensure obfuscation does not replace, but rather augments, all other security protections considered in this checklist.

Life Cycle

All Test Data Shall Be Removed From the App Container (.ipa, .apk, etc.)

At times, developers neglect the removal of test data from the application. For example, during testing, developers sometimes allow certain actions (e.g., key sequences) to bypass authentication to be able to test multiple sets of data rapidly. These constitute vulnerabilities in a production app, and they should be removed beforehand.

No Debugging Flags Shall Be Set in the Finalized App

It’s possible to forbid debuggers from interacting with the app. This makes it harder for an attacker to reverse-engineer an application and to have visibility on background processes.

The App Shall Go Through Application Security Testing

This is a generic requirement. Mobile AST unveils vulnerabilities that could be exploited by hackers or inadvertently leak sensitive information. The security checklist in this Toolkit provides a reminder for developers of the pitfalls to be avoided, but cannot replace testing.

 


Contact Us
Loading...