Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions best-practices/MASTG-BEST-0x31.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: Store Data Encrypted in App Sandbox Directory
alias: store-data-encrypted-in-the-app-sandbox-directory
id: MASTG-BEST-0x31
platform: android
knowledge: [MASTG-KNOW-0036]
---

Store sensitive data in `SharedPreferences` only after encrypting it. Standard `SharedPreferences` stores values in XML files inside the app's private data directory, so values such as credentials, authentication tokens, API keys, private keys, or personally identifiable information (PII) should not be stored in cleartext.

For apps that use `SharedPreferences`, use [`EncryptedSharedPreferences`](https://developer.android.com/reference/androidx/security/crypto/EncryptedSharedPreferences) or an equivalent mechanism that encrypts preference keys and values before they are written to disk.

`EncryptedSharedPreferences` wraps `SharedPreferences`, uses key material protected by the Android Keystore, and encrypts preference keys and values before storing them.

!!! note
`EncryptedSharedPreferences` is part of the Jetpack Security Crypto library, which has been [deprecated](https://developer.android.com/privacy-and-security/cryptography#jetpack_security_crypto_library). Until Android provides an official replacement, it remains a practical mitigation for apps that need to keep using `SharedPreferences` for sensitive data. Monitor Android's cryptography guidance and plan migrations when a supported replacement becomes available.

As Android recommends [`DataStore`](https://developer.android.com/topic/libraries/architecture/datastore) as a modern replacement for `SharedPreferences`, but `DataStore` doesn't encrypt data by default. If you migrate sensitive data to `DataStore`, apply an appropriate encryption layer before writing the data.
Comment thread
cpholguera marked this conversation as resolved.
Outdated
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ platform: android
title: Using SharedPreferences to Write Sensitive Data Unencrypted to the App Sandbox
id: MASTG-DEMO-0059
code: [kotlin]
test: MASTG-TEST-0207
test: MASTG-TEST-0287
Comment thread
cpholguera marked this conversation as resolved.
kind: fail
---

## Sample
Expand Down
4 changes: 2 additions & 2 deletions knowledge/android/MASVS-STORAGE/MASTG-KNOW-0036.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ Once the activity has been called, the file key.xml will be created with the pro

`MODE_PRIVATE` makes the file only accessible by the calling app. See ["Use SharedPreferences in private mode"](https://developer.android.com/privacy-and-security/security-best-practices#sharedpreferences).
Comment thread
cpholguera marked this conversation as resolved.
Outdated

> Other insecure modes exist, such as `MODE_WORLD_READABLE` and `MODE_WORLD_WRITEABLE`, but they have been deprecated since Android 4.2 (API level 17) and [removed in Android 7.0 (API Level 24)](https://developer.android.com/reference/android/os/Build.VERSION_CODES#N). Therefore, only apps running on an older OS version (`android:minSdkVersion` less than 17) will be affected. Otherwise, Android will throw a [SecurityException](https://developer.android.com/reference/java/lang/SecurityException). If an app needs to share private files with other apps, it is best to use a [FileProvider](https://developer.android.com/reference/androidx/core/content/FileProvider) with the [FLAG_GRANT_READ_URI_PERMISSION](https://developer.android.com/reference/android/content/Intent#FLAG_GRANT_READ_URI_PERMISSION). See [Sharing Files](https://developer.android.com/training/secure-file-sharing) for more details.
> Other insecure modes exist, such as `MODE_WORLD_READABLE` and `MODE_WORLD_WRITEABLE`, but they have been deprecated since Android 4.2 (API level 17) and [removed in Android 7.0 (API Level 24)](https://developer.android.com/reference/android/os/Build.VERSION_CODES#N). Therefore, only apps running on an older OS version (`android:minSdkVersion` less than 17) will be affected. Otherwise, Android will throw a [`SecurityException`](https://developer.android.com/reference/java/lang/SecurityException). If an app needs to share private files with other apps, it is best to use a [`FileProvider`](https://developer.android.com/reference/androidx/core/content/FileProvider) with the [`FLAG_GRANT_READ_URI_PERMISSION`](https://developer.android.com/reference/android/content/Intent#FLAG_GRANT_READ_URI_PERMISSION). See ["Sharing Files"](https://developer.android.com/training/secure-file-sharing) for more details.
Comment thread
cpholguera marked this conversation as resolved.
Outdated

You might also use [`EncryptedSharedPreferences`](https://developer.android.com/reference/androidx/security/crypto/EncryptedSharedPreferences), which is wrapper of `SharedPreferences` that automatically encrypts all data stored to the shared preferences.
You might also use [`EncryptedSharedPreferences`](https://developer.android.com/reference/androidx/security/crypto/EncryptedSharedPreferences) (see [source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:security/security-crypto/src/main/java/androidx/security/crypto/EncryptedSharedPreferences.java)), which is wrapper of `SharedPreferences` that automatically encrypts all data stored to the shared preferences using [Deterministic Authenticated Encryption with Associated Data (Deterministic AEAD) from Google's Tink Library](https://developers.google.com/tink/deterministic-encryption).
Comment thread
cpholguera marked this conversation as resolved.
Outdated

!!! Warning

Expand Down
1 change: 1 addition & 0 deletions tests-beta/android/MASVS-STORAGE/MASTG-TEST-0207.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ prerequisites:
- identify-sensitive-data
weakness: MASWE-0006
profiles: [L2]
best-practices: [MASTG-BEST-0x31]
knowledge: [MASTG-KNOW-0041]
---

Expand Down
44 changes: 41 additions & 3 deletions tests-beta/android/MASVS-STORAGE/MASTG-TEST-0287.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,47 @@ platform: android
id: MASTG-TEST-0287
type: [static, code]
weakness: MASWE-0006
best-practices: []
best-practices: [MASTG-BEST-0x31]
profiles: [L1, L2]
prerequisites:
- identify-sensitive-data
knowledge: [MASTG-KNOW-0036]
status: placeholder
note: This test checks if the app is using the SharedPreferences API to store sensitive data (e.g. user credentials, tokens) in an unencrypted format within the app's sandbox. This includes checking for the use of `SharedPreferences` without encryption as well as not using `EncryptedSharedPreferences` or similar secure storage mechanisms.
---

## Overview

When apps use the `SharedPreferences` API to store sensitive data without encryption, the data is written to plain-text XML files in the app's sandbox at `/data/data/<package-name>/shared_prefs/`. While `MODE_PRIVATE` restricts file access to the app itself, it doesn't protect the data from being read by attackers who gain access to the device's file system (for example, through device compromise, backup extraction, or physical access to rooted/unlocked devices).
Comment thread
cpholguera marked this conversation as resolved.
Outdated

This test uses runtime instrumentation to detect when the app writes data via `SharedPreferences` and determines whether sensitive data is being stored unencrypted.
Comment thread
cpholguera marked this conversation as resolved.

## Steps

1. Install the app on a device (@MASTG-TECH-0005).
2. Make sure you have @MASTG-TOOL-0145 installed on your machine and the Frida server running on the device.
Comment thread
cpholguera marked this conversation as resolved.
Outdated
3. Execute a method trace (@MASTG-TECH-0033) targeting the `SharedPreferences.Editor` methods that write data:
Comment thread
cpholguera marked this conversation as resolved.
Outdated
Comment thread
cpholguera marked this conversation as resolved.
Outdated
- `SharedPreferences.Editor.putString`
- `SharedPreferences.Editor.putStringSet`
Comment thread
cpholguera marked this conversation as resolved.
Outdated
4. Include tracing of cryptographic APIs to help determine if values are encrypted:
Comment thread
cpholguera marked this conversation as resolved.
Outdated
- `javax.crypto.Cipher.*`
- `java.security.KeyStore.*`
- `javax.crypto.KeyGenerator.*`
- `android.util.Base64.*`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Base64 is not encryption and should not be used as a reference. Only encryption methods should be traced.

5. Exercise the app, navigating through various workflows and inputting data that may be considered sensitive.
Comment thread
cpholguera marked this conversation as resolved.
Outdated
Comment thread
cpholguera marked this conversation as resolved.
Outdated

Comment thread
cpholguera marked this conversation as resolved.
## Observation

The output should contain a list of all calls to `SharedPreferences` write methods, including the keys, values, and stack traces showing where in the app's code these calls originate. The trace should also include any related cryptographic operations that may indicate encryption is being used.
Comment thread
cpholguera marked this conversation as resolved.
Outdated

## Evaluation

The test case fails if sensitive data is written to `SharedPreferences` without being encrypted first.

To evaluate the output:
Comment thread
cpholguera marked this conversation as resolved.
Outdated

1. **High-level trace inspection**: Review the sequence of calls to identify if `SharedPreferences.Editor.putString` or `putStringSet` calls are preceded by `Cipher` operations. Values written without prior encryption are likely stored in cleartext.
Comment thread
cpholguera marked this conversation as resolved.
Outdated

2. **Pattern matching**: Use a secrets detection tool (for example, @MASTG-TOOL-0144) to scan the output for known secret patterns such as API keys, tokens, passwords, or private keys.
Comment thread
cpholguera marked this conversation as resolved.

Comment thread
cpholguera marked this conversation as resolved.
Outdated
3. **Manual verification**: Use the stack traces to navigate to the relevant code locations in the reversed app (@MASTG-TECH-0117) and trace back the source of the values being written to confirm whether they contain sensitive data and whether encryption is applied.
Comment thread
cpholguera marked this conversation as resolved.
Outdated

Comment thread
cpholguera marked this conversation as resolved.
Outdated
4. **File system inspection**: Retrieve the `SharedPreferences` XML files from the app's sandbox using @MASTG-TOOL-0004 and inspect their contents to verify whether sensitive data is stored in cleartext.
Comment thread
cpholguera marked this conversation as resolved.
Outdated
Loading