Recipe Name:
Information Exposure: Avoid DeviceEncryptedStorage for Sensitive Information
Description:
Using DeviceEncryptedStorage for Sensitive information is insecure
Level:
warning
Language:
  • java
Tags:
  • security
  • framework specific
  • mobile
  • Android
Documentation

Abstract

Out of Android best practices and secure coding guidelines, recommendations were abstracted that state that sensitive data should be stored in a private location, inaccessible from other applications.

Description

Developers must ensure that sensitive information is written to a private location which is inaccessible by other applications. One solution is to write data to the internal storage of the device instead of the external storage. The following code example shows how to create a file on the internal storage. A flag should be set to ensure that the file can only be accessed by the current application. To ensure good code quality it is recommended to use a meaningful constant for this flag instead of its raw value.

Correct code example:

FileOutputStream fos;
File file = new File(filepath) ;
Context c = this.getApplicationContext();
fos = c.openFileOutput(file.getPath(), android.content.Context.MODE_PRIVATE);
Recipe
id: scw:android:secure-storage-context
version: 10
metadata:
  name: 'Information Exposure: Avoid DeviceEncryptedStorage for Sensitive Information'
  shortDescription: Using DeviceEncryptedStorage for Sensitive information is insecure
  level: warning
  language: java
  enabled: true
  comment: ""
  descriptionFile: descriptions/java_android_sensitive_information_store_sensitive_data_in_a_private_location.html
  tags: security;framework specific;mobile;Android
search:
  methodcall:
    name: createDeviceProtectedStorageContext
    anyOf:
    - type: android.content.Context
    - type: android.support.v4.content.ContextCompat
    - type: android.core.content.ContextCompat
availableFixes:
- name: Use the default secure storage location in the current context (try-with-resources)
  actions:
  - rewrite:
      to: "String filename = \"myfile\";\nString string = \"output\";\n\ntry (java.io.FileOutputStream outputStream = {{{ children.0.children.0.children.0 }}}.openFileOutput(filename, android.content.Context.MODE_PRIVATE)) {\n\toutputStream.write(string.getBytes());\n} catch (Exception e) {\n\t// TODO: handle exception\n}"
- name: Use the default secure storage location in the current context
  actions:
  - rewrite:
      to: "String filename = \"myfile\";\nString string = \"output\";\njava.io.FileOutputStream outputStream;\n\ntry {\n\toutputStream = {{{ children.0.children.0.children.0 }}}.openFileOutput(filename, android.content.Context.MODE_PRIVATE);\n\toutputStream.write(string.getBytes());\n} catch (Exception e) {\n\t// TODO: handle exception\n} finally {\n\toutputStream.close();\n}"