Android provides several options to save persistent application data, one of which is External Storage (/sdcard
, /mnt/sdcard
).
Files saved to the external storage are world-readable. Consequently, they can be modified by other apps installed on the device or by the user (by enabling USB mass storage and manipulating files from a PC).
The Android API Guides [Android Guides 2013] Storage Options states:
Caution: External storage can become unavailable if the user mounts the external storage on a computer or removes the media, and there’s no security enforced upon files you save to the external storage. All applications can read and write files placed on the external storage and the use can remove them.
Developers should not store sensitive data to external storage devices because files stored externally have no guarantee of availability, integrity, and confidentiality.
Noncompliant Code Example
The following code creates a file on the external storage and saves sensitive information to the file:
Code Block | ||
---|---|---|
| ||
private String filename = "myfile" private String string = "sensitive data such as credit card number" FileOutputStream fos = null; try { file file = new File(getExternalFilesDir(TARGET_TYPE), filename); fos = new FileOutputStream(file, false); fos.write(string.getBytes()); } catch (FileNotFoundException e) { // handle FileNotFoundException } catch (IOException e) { // handle IOException } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { } } } |
Proof of Concept
Typically, an application stores files in the directory as follows:
Code Block |
---|
/sdcard/Android/data/com.company.app/files/save/appdata/save_appdata |
Compliant Solution (Save a File on Internal Storage)
The following code uses the openFileOutput()
method to create "myfile"
in an application data directory with permission set to MODE_PRIVATE
so that other apps cannot access the file:
Code Block | ||
---|---|---|
| ||
private String filename = "myfile" private String string = "sensitive data such as credit card number" FileOutputStream fos = null; try { fos = openFileOutput(filename, Context.MODE_PRIVATE); fos.write(string.getBytes()); fos.close(); } catch (FileNotFoundException e) { // handle FileNotFoundException } catch (IOException e) { // handle IOException } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { } } } |
Risk Assessment
Storing sensitive information on external storage can leak sensitive information to malicious apps.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
DRD00-J | high | probable | medium | P12 | L1 |
Automated Detection
It is possible to automatically detect whether an application writes to external storage. It is not feasible to automatically determine whether such output could be stored internally.
Related Vulnerabilities
- JVN#92038939 mixi for Android information management vulnerability
- JVN#05102851 Yome Collection for Android issue in management of IMEI
Related Guidelines
Android Secure Coding Guidebook by JSSEC | 4.6 Secure File Handling |
Bibliography
[Android API 2013] | Class Environment |
[JSSEC 2013] | 4.6 Secure File Handling |