Introduction In our daily work, we often come across mobile applications, primarily for Android and iOS platforms. This article describes an example that demonstrates how popular security mechanisms should not replace essential application logic.
Vulnerability example During a recent audit, we discovered a security gap that allowed a bypass of the child mode restrictions within a mobile app. Although the app lacked an option to exit child mode (which protects content, applications, or resources designated by the parent), it was possible to disable the child module due to a flaw in the application's logic. This was possible because both the child and parent modes used the same API endpoints, and the assigned access data (JWT tokens) did not distinguish between the two modes.
As a result, an authenticated child session could disable monitoring mode with a single request to the server, which would log out device instances, disable the child mechanism, and remove parental controls.
Below is an example request that successfully removes the child mode functionality (using the AccessibilityService API on the Android platform):
The device ID in the URL specifies the paired child and parent mode instances, and the JWT token in the authorization header is issued specifically for the child mode instance. Subsequent API requests then receive a response indicating the absence of an active child mode, prompting the application to disable current restrictions and log out.
Security mechanisms and limitations It is clear that the implemented certificate pinning mechanism, which protects the communication channel and the mechanisms responsible for detecting:
• rooted/jailbroken devices
• emulated devices
• app file integrity manipulation
• runtime integrity manipulation
However, these protections are not 100% effective due to one simple fact: the user has full control over the device, both from user space and kernel space. They may be able to instrument the application process in relation to the device’s kernel or even influence the kernel's behavior directly. For example, using eBPF (supported by current Android kernels), they could create a specific function hook at the kernel level to bypass mechanisms associated with cryptographic operations.
The effectiveness of these security mechanisms lies in making it extremely difficult for users to bypass security effectively. Therefore, an effective mechanism is complex, does not rely on widely accepted implementations, and monitors a comprehensive range of platform parameters rather than just common indicators, such as the presence of specific executables in the file system. Security mechanisms are mandatory in modern mobile applications, but they should not be the sole reliance for protecting an app. A second critical component is the application logic itself and the logic of the API with which the application communicates.
Recommended approach and conclusion To address this in our security audits, we recommend an ideal solution: having two versions of the application. The first version includes standard security mechanisms, such as rooted/jailbroken device detection and certificate pinning. The second version lacks any implemented security features, allowing us to focus on testing application and API logic itself.
This approach not only focuses the testing on the application itself but also provides a clear view of the app’s existing security mechanisms. This enables us to thoroughly evaluate the level of implemented security mechanisms, allowing us to provide recommendations to enhance their effectiveness.
#Cybersecurity #MobileAppSecurity #PenetrationTesting #InfoSec #MobileDevelopment