Skip to content

Commit

Permalink
Port MASTG-TEST-0001 (by @Guardsquare) (#3040)
Browse files Browse the repository at this point in the history
* Add a deprecation note

* Add a new note for the deprecation coverage

* Update notes about SharedPreferences

* Apply suggestions from code review

Co-authored-by: Carlos Holguera <[email protected]>

* Fix markdown issue

---------

Co-authored-by: Carlos Holguera <[email protected]>
  • Loading branch information
serek8 and cpholguera authored Nov 7, 2024
1 parent 3cfb5e2 commit 7b8cb49
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 19 deletions.
46 changes: 27 additions & 19 deletions Document/0x05d-Testing-Data-Storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,14 @@ Understanding each relevant data storage function is crucial for performing the

### Shared Preferences

The [SharedPreferences](https://developer.android.com/training/data-storage/shared-preferences "Shared Preferences") API is commonly used to permanently save small collections of key-value pairs. Data stored in a SharedPreferences object is written to a plain-text XML file. The SharedPreferences object can be declared world-readable (accessible to all apps) or private.
Misuse of the SharedPreferences API can often lead to exposure of sensitive data. Consider the following example:
The [`SharedPreferences`](https://developer.android.com/training/data-storage/shared-preferences "Shared Preferences") API is commonly used to permanently save small collections of key-value pairs.

Example for Java:
Since Android 4.2 (API level 17) the `SharedPreferences` object can only be declared to be private (and not world-readable, i.e. accessible to all apps). However, since data stored in a `SharedPreferences` object is written to a plain-text XML file so its misuse can often lead to exposure of sensitive data.

```java
SharedPreferences sharedPref = getSharedPreferences("key", MODE_WORLD_READABLE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("username", "administrator");
editor.putString("password", "supersecret");
editor.commit();
```

Example for Kotlin:
Consider the following example:

```kotlin
var sharedPref = getSharedPreferences("key", Context.MODE_WORLD_READABLE)
var sharedPref = getSharedPreferences("key", Context.MODE_PRIVATE)
var editor = sharedPref.edit()
editor.putString("username", "administrator")
editor.putString("password", "supersecret")
Expand All @@ -74,14 +65,31 @@ Once the activity has been called, the file key.xml will be created with the pro
</map>
```

- `MODE_WORLD_READABLE` allows all applications to access and read the contents of `key.xml`.
`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).

```bash
root@hermes:/data/data/sg.vp.owasp_mobile.myfirstapp/shared_prefs # ls -la
-rw-rw-r-- u0_a118 170 2016-04-23 16:51 key.xml
```
> 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.
> Please note that `MODE_WORLD_READABLE` and `MODE_WORLD_WRITEABLE` were deprecated starting on API level 17. Although newer devices may not be affected by this, applications compiled with an `android:targetSdkVersion` value less than 17 may be affected if they run on an OS version that was released before Android 4.2 (API level 17).
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.

```kotlin
var masterKey: MasterKey? = null
masterKey = Builder(this)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()

val sharedPreferences: SharedPreferences = EncryptedSharedPreferences.create(
this,
"secret_shared_prefs",
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)

val editor = sharedPreferences.edit()
editor.putString("username", "administrator")
editor.putString("password", "supersecret")
editor.commit()
```

### Databases

Expand Down
2 changes: 2 additions & 0 deletions tests/android/MASVS-STORAGE/MASTG-TEST-0001.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ title: Testing Local Storage for Sensitive Data
masvs_v1_levels:
- L1
- L2
status: deprecated
covered_by: [MASTG-TEST-0207, MASTG-TEST-0200]
---

## Overview
Expand Down

0 comments on commit 7b8cb49

Please sign in to comment.