With the Android 11 preview beta being released last month, you may be scratching your head asking, “What did I miss in Android 10?” Developers will face a Nov. 2 deadline to update their mobile apps to accommodate a target SDK of Android API level 29 or higher. The addition of Scoped Storage ushers in noteworthy changes to external storage, otherwise known as public storage, SD card, shared storage, or emulated storage.

As with any new feature, we must always consider the intended value, so let’s dive in to learn about Scoped Storage and gain best practices for testing mobile apps that use the feature. If you’ve been tracking Android changes for the last year, you might already be familiar with Scoped Storage. Scoped Storage changes the way mobile apps access external storage on users’ mobile devices.

From a high level, your apps have access to internal and external storage. Internal storage is accessible only by the app, whereas a user and other apps can access external storage. Specific locations on external storage may require a user permission, but that varies based on the version of Android the app runs on.

This can present a major security issue for some apps because they use external storage locations on the device to store sensitive information. For example, say an app stores a configuration file in public storage. That file is then modified by a third-party app on the device. The file was originally used to supply the app with the endpoints for authentication and other resources used by its own processes. An attacker uses a malicious app to switch the endpoints to their own, harvest user credentials and change the app’s context. This allows the attacker to tarnish the brand and use the app as a phishing vector. That’s just one example of many insecure uses of external storage.

Scoped Storage doesn’t prevent that type of scenario. Instead, it lays the groundwork for a major change to how that file access permission model works. Today, if apps use the external storage for sensitive files, they may be creating those security issues for themselves. Other apps with the READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE permissions are able to access the app-specific files on external storage. Scoped Storage changes this by only allowing apps that meet certain requirements to access those app-specific storage locations.

While Scoped Storage doesn’t change the security and privacy of external storage use, it does change the process by which you are allowed to access other app-specific files, media, and documents (broad storage) on the device. The goal of Scoped Storage is to provide a purpose-based approach, where apps will use specific APIs to create media files, cache files, or share files, rather than obtain overprivileged permissions to perform these functions. Google is likely to spend more time vetting apps for the Play Store that access broad storage because this constitutes extraneous and potentially malicious functionality for most apps, and should be limited to certain types of apps that will use it for legitimate purposes.

NowSecure Academy Mobile AppSec Training

Get Started for Free with Mobile AppSec Training

External Storage Testing Tips

What follows are my tips for beginner mobile app security analysts who need to assess the security of Android apps.

  • Be aware of what an app might be storing to external storage. If your app uses external storage, avoid storing data that’s crucial to an app’s processes. That also includes data that needs to be protected either because of its sensitive nature to the user or the app creator. For example, this could be patient records in a medical app or a config file that sets user stats in a gaming app.
  • Keep in mind is that external storage can go by a number of names, which can create confusion. While your device might not have a physical SD card port, it likely has an emulated SD card that represents external storage. The two most common directory paths for external storage on devices are /scard/ and /storage/emulated/0/, and are in fact the same location.
  • If you haven’t performed app forensic analysis before, consider using Android Debug Bridge (adb) to evaluate files on external storage. Once you’ve enabled “USB Debugging” on an Android device, use a computer with the adb command-line tool installed to access and navigate device storage with the adb shell command. A good place to look for app data in is the /sdcard/Android/data directory. You’ll likely see a list of subdirectories for apps that are storing data to external storage as, on most devices, this is the default location for external storage app-specific folders. You can then use the adb pull command to bring those files to your desktop.
    $ adb shell ls /sdcard/Android/data
    System                                com.google.android.gms                  
    com.android.chrome                    com.google.android.googlequicksearchbox 
    com.android.vending                   com.google.android.music                
    com.example.app
    $ adb pull /sdcard/Android/data/com.example.app ~/Desktop/ExampleData/
    /sdcard/Android/data/com.example.app/: 4 files pulled. 0.0 MB/s (406 bytes in 0.136s)
  • If you want to perform code analysis, inspect the app’s code for uses of getExternalStorageState(), getExternalFilesDir() and getExternalCacheDir() as those are usually the first step in an app using external storage for app specific files. A common misconception is that apps require READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE permissions to use external storage, but that is only true for apps accessing Media folders and broad storage.
  • If you’re interested in performing dynamic analysis, I recommend checking out a tool in the NowSecure public GitHub repo, nowsecure/FSMON. FSMON lets you monitor the filesystem events on the device. While FSMON can be a bit overwhelming, it is useful in understanding how an app might use the emulated storage on a device along with its own private app storage.
  • As part of your analysis, be sure to look for config files and other files where modification can lead to fraud or phishing users through the app. Spend time looking for confidential data too, because external storage is not an appropriate place to store it. In cases where an app must store this data for later use, private app storage should be used in lieu of external storage.
  • It’s important to note that external storage does have some legitimate use cases. For example, if the app allows users to take pictures such as one that would be necessary when creating a profile, the app will likely store that image in external storage using the MediaStore API. This would be a necessary use that should be allowed. But if an app did the same thing with a picture of the user’s ID card or paycheck, that would be considered extraneous because of the sensitive nature of that data.
  • Beware of apps that use the READ_EXTERNAL_STORAGE permission. Apps that use this permission typically need access to the entire media storage directory. This can be an extremely overprivileged behavior, so be aware of what those apps might be doing and use situational awareness to determine if the app is overprivileged. An app that displays media files may need to access that functionality, while an app that plays Tic-Tac-Toe would not.
  • Using the requestLegacyExternalStorage flag should also be seen as another extraneous functionality. This flag reverts the app back to the old permission model, where any app with the READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE permissions will grant full access to device broad storage. If you plan to use this flag as part of updating your app to accommodate API Level 29, consider moving forward with adopting the Scoped Storage practices as your app will be forced to next year. Android 11 (API Level 30) will prevent the use of this flag, which may be an incentive to leave it out now instead of later.

Implement External Storage Securely

Keep in mind that there are some legitimate reasons to use external storage on your device, as well as ways to implement external storage securely. I advise mobile app security teams working with developers to define some data classification and controls for data that your app handles. If you know what is being stored by the app, then you can define where it should be stored and what controls should be in place to protect that data. That might include encryption and some other data integrity measure, or it might mean just avoiding external storage. Finally, while Scoped Storage may seem to be a protection for users and apps, it’s important to be aware that older versions of Android will not support all of these controls.

You can ease the task of testing apps for security and privacy gaps in code functionality, improper data storage and network transmission with automated testing tools that pinpoint vulnerabilities. The NowSecure Workstation hardware and software kit shrinks testing time from days to hours and the NowSecure Platform solution offers scalable continuous testing of the apps your organization builds and buys from a single unified interface.

What to read next:

Tony Ramirez

linkedin icon twitter icon

Senior Application Security Analyst

As mobile security analyst at NowSecure, Tony Ramirez consults with customers and performs mobile app penetration testing of iOS and Android apps as part of the NowSecure Services team. Tony holds a master's degree in cyber forensics and security from Illinois Institute of Technology.