From 0bc19a71cf6fd8fa623a2a1543928d5b8bcbce6b Mon Sep 17 00:00:00 2001 From: Jan Seredynski Date: Tue, 5 Mar 2024 11:45:03 +0100 Subject: [PATCH 01/33] Add Risk and Tests for: Sensitive Data Stored Unencrypted in External Locations --- .../example-1/example.md | 30 ++++++++ .../example-1/output.txt | 1 + .../example-1/run.sh | 13 ++++ .../example-1/snippet.kt | 7 ++ .../test.md | 37 ++++++++++ .../example-1/AndroidManifest.xml | 29 ++++++++ .../example-1/example.md | 29 ++++++++ .../example-1/output.sarif | 44 +++++++++++ .../example-1/output.txt | 11 +++ .../example-1/run.sh | 2 + ...oid-data-unencrypted-external-manifest.yml | 10 +++ .../test.md | 23 ++++++ .../example-1/example.md | 32 ++++++++ .../example-1/output.sarif | 74 +++++++++++++++++++ .../example-1/output.txt | 9 +++ .../example-1/run.sh | 2 + .../example-1/use-of-external-store.kt | 35 +++++++++ ...astg-android-data-unencrypted-external.yml | 21 ++++++ .../test.md | 25 +++++++ .../data-unencrypted-external/risk.md | 46 ++++++++++++ 20 files changed, 480 insertions(+) create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/example.md create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/output.txt create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/run.sh create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/snippet.kt create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/test.md create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/AndroidManifest.xml create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/example.md create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/output.sarif create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/output.txt create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/run.sh create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/rules/mastg-android-data-unencrypted-external-manifest.yml create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/test.md create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/output.sarif create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/output.txt create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/run.sh create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/use-of-external-store.kt create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/rules/mastg-android-data-unencrypted-external.yml create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/test.md create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/risk.md diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/example.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/example.md new file mode 100644 index 0000000000..f6c9a15ffb --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/example.md @@ -0,0 +1,30 @@ +--- +platform: android +title: File Tracing +tools: [frida-trace] +code: [kotlin] +--- + +### Sample + +The snippet below shows sample code that creates a file in external storage. You can put this code into your app and follow the steps to see a sample usage of `frida-trace` to identify a potential data leak. + +{{ snippet.kt }} + +### Steps + +Execute `frida-trace` against the sample app to trace all usage of file IO. + +{{ run.sh }} + +### Observation + +`frida-trace` has identified one file path in the external storage that the app opened. + +{{ output.txt }} + +### Evaluation + +Review each of the reported instances by manually opening a file and inspecting its content. + +NOTE: If you want to test more file locations than only the file locations inside the external storage, remove `grep` from the script. diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/output.txt new file mode 100644 index 0000000000..25fcbad95b --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/output.txt @@ -0,0 +1 @@ +638 ms open(path="/storage/emulated/0/Android/data/com.example/files/secret.json", oflag=0x241) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/run.sh new file mode 100644 index 0000000000..e3ae6321d7 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/run.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# SUMMARY: This script uses frida-trace to trace files that an app has opened since it spawned +# The script filters the output of frida-trace to print only the paths belonging to external +# storage but the the predefined list of external storage paths might not be complete. +# A sample output is shown in "output.txt". If the output is empty, it indicates that no external +# storage is used. + +frida-trace \ + -U \ + -f com.example \ + -i "open" \ + | grep -E "(/sdcard|/storage)" diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/snippet.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/snippet.kt new file mode 100644 index 0000000000..5662e44f8c --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/snippet.kt @@ -0,0 +1,7 @@ +// On lower Android verions, you might need to add `WRITE_EXTERNAL_STORAGE` permission to the manifest to write to an external app-specific directory. + +val externalDirPath = getExternalFilesDir(null)!!.absolutePath +val file: File = File("$externalDirPath/secret.json") +FileOutputStream(file).use { fos -> + fos.write("password:123".toByteArray()) +} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/test.md new file mode 100644 index 0000000000..3d331c88b2 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/test.md @@ -0,0 +1,37 @@ +--- +platform: android +title: Storing Data in External Locations +apis: [Environment#getExternalStorageDirectory, Environment#getExternalStorageDirectory, Environment#getExternalFilesDir, Environment#getExternalCacheDir, SharedPreferences, FileOutPutStream] +type: [dynamic] +--- + +## Overview + +Android apps utilize a variety of APIs to obtain a file path and save a file. Collecting a comprehensive list of these APIs can be challenging, especially when an app employs a third-party framework, loads code at runtime, or incorporates native code. Therefore, dynamic testing might be the most effective approach to find writing to the external storage. + +## Steps + +1. Install the app. + +2. Execute a [method trace](https://mas.owasp.org/MASTG/techniques/android/MASTG-TECH-00xx/) to spawn an app and log all interactions with files. + +3. Navigate to the screen of the mobile app that you want to analyse. + +4. Close the app to stop `frida-trace` + + +## Observation + +The **method trace output** contains a list of file locations that your app interacts with. You may need to use [adb shell](https://mas.owasp.org/MASTG/techniques/android/MASTG-TECH-0002/) to inspect these files manually. + +## Evaluation + +The test case fails if the files found above are not encrypted and leak sensitive data. + +For example, the following output shows sample files that should be manually inspected. + +```shell +/storage/emulated/0/Android/data/com.example/keys.json +/storage/emulated/0/Android/data/com.example/files/config.xml +/sdcard/secret.txt" +``` diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/AndroidManifest.xml b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/AndroidManifest.xml new file mode 100644 index 0000000000..67c0372dea --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/AndroidManifest.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/example.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/example.md new file mode 100644 index 0000000000..41d92f39a2 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/example.md @@ -0,0 +1,29 @@ +--- +platform: android +title: Common APIs to return paths to External Storage +tools: [semgrep] +code: [java] +--- + +### Sample + +{{ use-of-external-store.kt }} + +### Steps + +Let's run our semgrep rule against the sample manifest file. + +{{ ../rules/mastg-android-data-unencrypted-external-manifest.yml }} + +{{ run.sh }} + +### Observation + +The rule has identified that the manifest file declares `WRITE_EXTERNAL_STORAGE` permission at line 9. + +{{ output.txt }} + +### Evaluation + +Review your code to make sure you don't store sensitive unencrypted data in the external storage unintentionally. + diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/output.sarif new file mode 100644 index 0000000000..2042592a68 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/output.sarif @@ -0,0 +1,44 @@ +{ + "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json", + "runs": [ + { + "invocations": [ + { + "executionSuccessful": true, + "toolExecutionNotifications": [] + } + ], + "results": [], + "tool": { + "driver": { + "name": "Semgrep OSS", + "rules": [ + { + "defaultConfiguration": { + "level": "warning" + }, + "fullDescription": { + "text": "[MASVS-STORAGE] Make sure you encrypt files in external storage if necessary" + }, + "help": { + "markdown": "[MASVS-STORAGE] Make sure you encrypt files in external storage if necessary", + "text": "[MASVS-STORAGE] Make sure you encrypt files in external storage if necessary" + }, + "id": "rules.mastg-android-data-unencrypted-external", + "name": "rules.mastg-android-data-unencrypted-external", + "properties": { + "precision": "very-high", + "tags": [] + }, + "shortDescription": { + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external" + } + } + ], + "semanticVersion": "1.63.0" + } + } + } + ], + "version": "2.1.0" +} \ No newline at end of file diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/output.txt new file mode 100644 index 0000000000..0250a4b88f --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/output.txt @@ -0,0 +1,11 @@ + + +┌────────────────┐ +│ 1 Code Finding │ +└────────────────┘ + + AndroidManifest.xml + mrules.mastg-android-data-unencrypted-external + [MASVS-STORAGE] Make sure you encrypt files in external storage if necessary + + 5┆ diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/run.sh new file mode 100644 index 0000000000..463a8635d1 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/run.sh @@ -0,0 +1,2 @@ +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external-manifest.yml ./AndroidManifest.xml --text -o output.txt +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external-manifest.yml ./AndroidManifest.xml --sarif -o output.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/rules/mastg-android-data-unencrypted-external-manifest.yml b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/rules/mastg-android-data-unencrypted-external-manifest.yml new file mode 100644 index 0000000000..7d9390a94f --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/rules/mastg-android-data-unencrypted-external-manifest.yml @@ -0,0 +1,10 @@ +rules: + - id: mastg-android-data-unencrypted-external-manifest + severity: WARNING + languages: + - generic + metadata: + summary: This rule looks for permissions that allows your app to write in External Storage + message: "[MASVS-STORAGE] Make sure you encrypt files in external storage if necessary" + patterns: + - pattern: WRITE_EXTERNAL_STORAGE diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/test.md new file mode 100644 index 0000000000..687d5d080a --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/test.md @@ -0,0 +1,23 @@ +--- +platform: android +title: Declaration of the external storage permission +apis: [] +type: [static] +--- + +## Overview + +An app must declare an intent to write to external storage in order to save files in the public locations. + +## Steps + +1. Run a [static analysis](../../../../../techniques/android/MASTG-TECH-0014.md) tool on the app and look for a use of sensitive permissions. + + +## Observation + +The output shows that the manifest files declares `WRITE_EXTERNAL_STORAGE` permission at line 5. + +## Evaluation + +Inspect app's source code to make sure the data stored externally is secure. diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md new file mode 100644 index 0000000000..7dce265886 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md @@ -0,0 +1,32 @@ +--- +platform: android +title: Find common APIs that return paths to External Storage locations +tools: [semgrep] +code: [java] +--- + +### Sample + +{{ use-of-external-store.kt }} + +### Steps + +Let's run our semgrep rule against the sample code. + +{{ ../rules/mastg-android-data-unencrypted-external.yml }} + +{{ run.sh }} + +### Observation + +The rule has identified 1 location in the code file where a path to external storage is retuened. Make sure you don't store unencrypted code there unintentionally. + +{{ output.txt }} + +### Evaluation + +Review each of the reported instances. In this case, it's only one instance. Line 9 shows the occurence of API that returns external storage location. Make sure to either: +- encrypt this file if necessary +- move the file to the internal storage +- keep the file in the same location if intended and secure + diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/output.sarif new file mode 100644 index 0000000000..7583696973 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/output.sarif @@ -0,0 +1,74 @@ +{ + "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json", + "runs": [ + { + "invocations": [ + { + "executionSuccessful": true, + "toolExecutionNotifications": [] + } + ], + "results": [ + { + "fingerprints": { + "matchBasedId/v1": "7fff0cca477ae1b0a93a5b8e265d8a7471c4144464dcbbd55d7256be707b55568882a55bbac36d334816deb905d562cb7f9c4cee168fb02f8ca6f31936c62fb7_0" + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "use-of-external-store.kt", + "uriBaseId": "%SRCROOT%" + }, + "region": { + "endColumn": 101, + "endLine": 26, + "snippet": { + "text": " val externalDirPath = getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)" + }, + "startColumn": 35, + "startLine": 26 + } + } + } + ], + "message": { + "text": "[MASVS-STORAGE] Make sure you encrypt files at these locations if necessary" + }, + "properties": {}, + "ruleId": "rules.mastg-android-data-unencrypted-external" + } + ], + "tool": { + "driver": { + "name": "Semgrep OSS", + "rules": [ + { + "defaultConfiguration": { + "level": "warning" + }, + "fullDescription": { + "text": "[MASVS-STORAGE] Make sure you encrypt files at these locations if necessary" + }, + "help": { + "markdown": "[MASVS-STORAGE] Make sure you encrypt files at these locations if necessary", + "text": "[MASVS-STORAGE] Make sure you encrypt files at these locations if necessary" + }, + "id": "rules.mastg-android-data-unencrypted-external", + "name": "rules.mastg-android-data-unencrypted-external", + "properties": { + "precision": "very-high", + "tags": [] + }, + "shortDescription": { + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external" + } + } + ], + "semanticVersion": "1.63.0" + } + } + } + ], + "version": "2.1.0" +} \ No newline at end of file diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/output.txt new file mode 100644 index 0000000000..f4672a559a --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/output.txt @@ -0,0 +1,9 @@ +┌────────────────┐ +│ 1 Code Finding │ +└────────────────┘ + + use-of-external-store.kt + rules.mastg-android-data-unencrypted-external 0m + [MASVS-STORAGE] Make sure you encrypt files at these locations if necessary + + 26┆ val externalDirPath = getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/run.sh new file mode 100644 index 0000000000..a8623be3ec --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/run.sh @@ -0,0 +1,2 @@ +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external.yml ./use-of-external-store.kt --text -o output.txt +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external.yml ./use-of-external-store.kt --sarif -o output.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/use-of-external-store.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/use-of-external-store.kt new file mode 100644 index 0000000000..fe01e440c1 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/use-of-external-store.kt @@ -0,0 +1,35 @@ +package com.example + +import android.content.Intent +import android.os.Bundle +import android.os.Environment +import android.os.Environment.getDownloadCacheDirectory +import android.os.Environment.getExternalStorageDirectory +import android.os.Environment.getExternalStoragePublicDirectory +import android.view.View +import android.widget.Button +import androidx.appcompat.app.AppCompatActivity +import java.io.File +import java.io.FileOutputStream +import java.io.IOException + +class MainActivity : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setContentView(R.layout.activity_main) + saveDatabase() + } + + fun saveDatabase(){ + try { + val externalDirPath = getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + val file: File = File("$externalDirPath/download.json") + FileOutputStream(file).use { fos -> + fos.write("password:12345".toByteArray()) + } + } catch (e: IOException) { + e.printStackTrace() + } + } +} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/rules/mastg-android-data-unencrypted-external.yml b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/rules/mastg-android-data-unencrypted-external.yml new file mode 100644 index 0000000000..96ad04d373 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/rules/mastg-android-data-unencrypted-external.yml @@ -0,0 +1,21 @@ +rules: + - id: mastg-android-data-unencrypted-external + severity: WARNING + languages: + - kotlin + metadata: + summary: This rule looks for methods that returns locations to external storage + message: "[MASVS-STORAGE] Make sure you encrypt files at these locations if necessary" + pattern-either: + - patterns: + - pattern-either: + - pattern: getExternalFilesDir(...) + - pattern: getExternalStorageDirectory(...) + - pattern: getExternalStoragePublicDirectory(...) + - pattern: getExternalCacheDir(...) + - pattern: getDownloadCacheDirectory(...) + - pattern: Intent.ACTION_CREATE_DOCUMENT + + + + diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/test.md new file mode 100644 index 0000000000..4ab1b77137 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/test.md @@ -0,0 +1,25 @@ +--- +platform: android +title: Usage of API to get to external storage locations +apis: [Environment#getExternalStoragePublicDirectory, Environment#getExternalStorageDirectory, Environment#getExternalFilesDir, Environment#getExternalCacheDir] +type: [static] +--- + +## Overview + +Developers can obtain paths to the external storage locations with `Environment.getExternal...` methods. This test searches for a set of APIs that are commonly used for obtaining external storage locations in source code. + +## Steps + +1. Run a [static analysis](../../../../../techniques/android/MASTG-TECH-0014.md) tool on the app and look for uses of `getExternal...` API. + + +## Observation + +The output should contain a **list of locations where paths to external storage are returned**. + +## Evaluation + +Inspect app's source code using the provided location information. + +The test case fails if you find code that writes sensitive unencrypted to these locations. diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/risk.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/risk.md new file mode 100644 index 0000000000..b226a9a5ef --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/risk.md @@ -0,0 +1,46 @@ +--- +title: Sensitive Data Stored Unencrypted in External Locations +alias: data-unencrypted-external +platform: [android] +profiles: [L1, L2] +mappings: + masvs-v1: [MSTG-STORAGE-2] + masvs-v2: [MASVS-STORAGE-1] + mastg-v1: [MASTG-TEST-0052, MASTG-TEST-0001] + +--- + +## Overview + +Apps frequently opt to store data in the external storage due to its larger capacity and the ability to share files with other apps. However, this convenience comes with a potential drawback. Data stored on external devices like SD cards can be accessed not only by other apps on the device, given the right permissions, but also if the external storage is physically removed. This means that files meant to be private might unintentionally become public. Even if the external storage is emulated by the system, the risk arises from improper file permissions or the misuse of APIs for saving files. In such cases, files become vulnerable to unauthorized modifications and deletions, posing a security threat to the application. + +Developers may consider switching to the internal storage if they need more privacy and security. However, if the external storage is the most suitable for the app, it's a good practise to encrypt data stored in the external storage. Below you can find potential security impacts and mitigations linked to the use of the external storage. + + +## Impact + +- **Loss of confidentiality**: An attacker can extract sensitive data stored externally, such as personal information and media like photos, documents, and audio files. + +- **Loss of secure material**: An attacker can extract passwords, cryptographic keys, and session tokens to facilitate additional attacks, such as identity theft or account takeover. + +- **Modification of app's behaviour**: An attacker can tamper with data used by the app, altering the app's logic. For example, they could modify a database describing the state of premium features or inject a malicious payload to enable further attacks such as SQL injection and Path Traversal. + +- **Modification of downloaded code**: An app can download new functionality from the Internet and store the executable code in external storage before loading it into the process. An attacker can modify this code before it is used by the app. + + +## Modes of Introduction + +This threat is primarily a concern for Android devices since they permit the use of external storage. Even if a device lacks physical external storage, Android emulates it to provide access to the external storage API. + +- **Data Stored Unencrypted**: Sensitive data is stored in the external storage unencrypted. +- **Hardcoded Encryption Key**: Sensitive data is encrypted and stored in the external storage but the key is hardcoded inside the application. +- **Encryption Key Stored on Filesystem**: Sensitive data is encrypted and stored in the external storage but the key is stored alongside it or in another easily accessible location. +- **Encryption Used is Insufficient**: Sensitive data is encrypted but the encryption is not considered to be strong. +- **Reuse of encryption key**: The encryption key is shared between two devices owned by a single user, enabling the process of data cloning between these devices in the external storage. + + +## Mitigations + +Sensitive data stored in the external storage should be encrypted, and any keys used for encryption methods should be protected by the device's hardware-backed keystore, where available. It is highly discouraged to include a cryptographic key inside the application. + +- [Android's EncryptedFile API wrapper for file encryption](https://developer.android.com/reference/androidx/security/crypto/EncryptedFile) From af5056831515f7b27d5a6f4f1f82a802f91d71a1 Mon Sep 17 00:00:00 2001 From: Jan Seredynski Date: Mon, 6 May 2024 17:12:34 +0200 Subject: [PATCH 02/33] Update risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/test.md Co-authored-by: Carlos Holguera --- .../android-data-unencrypted-external-frida/test.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/test.md index 3d331c88b2..da4d5bc804 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/test.md @@ -7,7 +7,7 @@ type: [dynamic] ## Overview -Android apps utilize a variety of APIs to obtain a file path and save a file. Collecting a comprehensive list of these APIs can be challenging, especially when an app employs a third-party framework, loads code at runtime, or incorporates native code. Therefore, dynamic testing might be the most effective approach to find writing to the external storage. +Android apps use a variety of APIs to obtain a file path and store a file. Collecting a comprehensive list of these APIs can be challenging, especially if an app uses a third-party framework, loads code at runtime, or includes native code. The most effective approach to testing applications that write to device memory is usually dynamic analysis, and specifically method tracing. ## Steps From dc5a4659b0778daa3cb4c90062aadf2d232f6ece Mon Sep 17 00:00:00 2001 From: Jan Seredynski Date: Tue, 5 Mar 2024 11:56:15 +0100 Subject: [PATCH 03/33] Fix spellings --- .../example-1/snippet.kt | 2 +- .../example-1/example.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/snippet.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/snippet.kt index 5662e44f8c..4b192083aa 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/snippet.kt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/snippet.kt @@ -1,4 +1,4 @@ -// On lower Android verions, you might need to add `WRITE_EXTERNAL_STORAGE` permission to the manifest to write to an external app-specific directory. +// On lower Android versions, you might need to add `WRITE_EXTERNAL_STORAGE` permission to the manifest to write to an external app-specific directory. val externalDirPath = getExternalFilesDir(null)!!.absolutePath val file: File = File("$externalDirPath/secret.json") diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md index 7dce265886..233d1f12d6 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md @@ -25,7 +25,7 @@ The rule has identified 1 location in the code file where a path to external sto ### Evaluation -Review each of the reported instances. In this case, it's only one instance. Line 9 shows the occurence of API that returns external storage location. Make sure to either: +Review each of the reported instances. In this case, it's only one instance. Line 9 shows the occurrence of API that returns external storage location. Make sure to either: - encrypt this file if necessary - move the file to the internal storage - keep the file in the same location if intended and secure From e0ba4e1655874936578d6e85fef6b9017a70d1fd Mon Sep 17 00:00:00 2001 From: Jan Seredynski Date: Tue, 7 May 2024 12:29:30 +0200 Subject: [PATCH 04/33] Update tests and examples --- .../example-1/example.md | 14 +- .../example-1/output.txt | 28 ++- .../example-1/run.sh | 10 +- .../example-1/script.js | 15 ++ .../test.md | 2 +- .../example-1/output.sarif | 44 ---- .../example-1/run.sh | 2 - ...oid-data-unencrypted-external-manifest.yml | 10 - .../test.md | 23 -- .../example-1/example.md | 2 +- .../example-1/output.sarif | 62 ++++- .../example-1/output.txt | 8 +- .../example-1/run.sh | 0 .../example-2}/AndroidManifest.xml | 0 .../example-2}/example.md | 4 +- .../example-2/output.sarif | 116 +++++++++ .../example-2}/output.txt | 6 +- .../example-2/run.sh | 2 + .../example-3/example.md | 30 +++ .../example-3/output.sarif | 232 ++++++++++++++++++ .../example-3/output.txt | 19 ++ .../example-3/run.sh | 2 + .../example-3/use-of-mediastore.kt | 23 ++ ...astg-android-data-unencrypted-external.yml | 46 ++-- .../test.md | 41 +++- 25 files changed, 608 insertions(+), 133 deletions(-) mode change 100644 => 100755 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/run.sh create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/script.js delete mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/output.sarif delete mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/run.sh delete mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/rules/mastg-android-data-unencrypted-external-manifest.yml delete mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/test.md mode change 100644 => 100755 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/run.sh rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/{android-data-unencrypted-external-static-manifest/example-1 => android-data-unencrypted-external-static/example-2}/AndroidManifest.xml (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/{android-data-unencrypted-external-static-manifest/example-1 => android-data-unencrypted-external-static/example-2}/example.md (83%) create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/output.sarif rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/{android-data-unencrypted-external-static-manifest/example-1 => android-data-unencrypted-external-static/example-2}/output.txt (67%) create mode 100755 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/run.sh create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/example.md create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/output.sarif create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/output.txt create mode 100755 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/run.sh create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/use-of-mediastore.kt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/example.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/example.md index f6c9a15ffb..f1a1358854 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/example.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/example.md @@ -1,30 +1,30 @@ --- platform: android title: File Tracing -tools: [frida-trace] +tools: [frida] code: [kotlin] --- ### Sample -The snippet below shows sample code that creates a file in external storage. You can put this code into your app and follow the steps to see a sample usage of `frida-trace` to identify a potential data leak. +The snippet below shows sample code that creates a file in external storage. You can put this code into your app and follow the steps below to identify a potential data leak. {{ snippet.kt }} ### Steps -Execute `frida-trace` against the sample app to trace all usage of file IO. +1. Update the Package ID of your app inside `run.sh` +2. Execute `run.sh` against the sample app to trace all usage of file IO. +3. Close the app once you finish testing {{ run.sh }} ### Observation -`frida-trace` has identified one file path in the external storage that the app opened. +The script will output the findings into `output.txt` {{ output.txt }} ### Evaluation -Review each of the reported instances by manually opening a file and inspecting its content. - -NOTE: If you want to test more file locations than only the file locations inside the external storage, remove `grep` from the script. +Review each warning in the output file and make sure you intended to store this file in the external storage. diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/output.txt index 25fcbad95b..a6961ee103 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/output.txt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/output.txt @@ -1 +1,27 @@ -638 ms open(path="/storage/emulated/0/Android/data/com.example/files/secret.json", oflag=0x241) +[WARNING] Opening a file from external storage at: /storage/emulated/0/Android/data/com.gs.owasp_storage_app1/files/secret.json +Invoked from: java.lang.Exception + at libcore.io.Linux.open(Native Method) + at libcore.io.ForwardingOs.open(ForwardingOs.java:167) + at libcore.io.BlockGuardOs.open(BlockGuardOs.java:252) + at libcore.io.ForwardingOs.open(ForwardingOs.java:167) + at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7581) + at libcore.io.IoBridge.open(IoBridge.java:482) + at java.io.FileOutputStream.(FileOutputStream.java:235) + at java.io.FileOutputStream.(FileOutputStream.java:186) + at com.gs.owasp_storage_app1.MainActivity.runOwasp(MainActivity.kt:155) + at com.gs.owasp_storage_app1.MainActivity.onCreate$lambda$1(MainActivity.kt:36) + at com.gs.owasp_storage_app1.MainActivity.$r8$lambda$He9NTWO6dCDqltooAd5-9ovuSZ8(Unknown Source:0) + at com.gs.owasp_storage_app1.MainActivity$$ExternalSyntheticLambda1.onClick(Unknown Source:2) + at android.view.View.performClick(View.java:7201) + at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1218) + at android.view.View.performClickInternal(View.java:7170) + at android.view.View.access$3500(View.java:806) + at android.view.View$PerformClick.run(View.java:27562) + at android.os.Handler.handleCallback(Handler.java:883) + at android.os.Handler.dispatchMessage(Handler.java:100) + at android.os.Looper.loop(Looper.java:214) + at android.app.ActivityThread.main(ActivityThread.java:7682) + at java.lang.reflect.Method.invoke(Native Method) + at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516) + at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950) + diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/run.sh old mode 100644 new mode 100755 index e3ae6321d7..f8fa2db63a --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/run.sh +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/run.sh @@ -1,13 +1,13 @@ #!/bin/bash -# SUMMARY: This script uses frida-trace to trace files that an app has opened since it spawned +# SUMMARY: This script uses frida to trace files that an app has opened since it spawned # The script filters the output of frida-trace to print only the paths belonging to external # storage but the the predefined list of external storage paths might not be complete. # A sample output is shown in "output.txt". If the output is empty, it indicates that no external # storage is used. -frida-trace \ +frida \ -U \ - -f com.example \ - -i "open" \ - | grep -E "(/sdcard|/storage)" + -f com.gs.owasp_storage_app2 \ + -l script.js \ + -o output.txt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/script.js b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/script.js new file mode 100644 index 0000000000..01b96c46b2 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/script.js @@ -0,0 +1,15 @@ +// Intercept libc`open to make sure we cover all Java's APIs +Interceptor.attach(Module.getExportByName(null, 'open'), { + onEnter(args) { + const external_paths = ['/sdcard', '/storage/emulated'] + const path = Memory.readCString(ptr(args[0])); + external_paths.forEach(external_path => { + if(path.indexOf(external_path) == 0){ + console.log('[WARNING] Opening a file from external storage at:', path) + Java.performNow(function() { + console.log("Invoked from: "+Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new())) + }); + } + }); + } +}); diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/test.md index da4d5bc804..221df627ee 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/test.md @@ -1,6 +1,6 @@ --- platform: android -title: Storing Data in External Locations +title: Data Stored to External Locations on Runtime apis: [Environment#getExternalStorageDirectory, Environment#getExternalStorageDirectory, Environment#getExternalFilesDir, Environment#getExternalCacheDir, SharedPreferences, FileOutPutStream] type: [dynamic] --- diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/output.sarif deleted file mode 100644 index 2042592a68..0000000000 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/output.sarif +++ /dev/null @@ -1,44 +0,0 @@ -{ - "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json", - "runs": [ - { - "invocations": [ - { - "executionSuccessful": true, - "toolExecutionNotifications": [] - } - ], - "results": [], - "tool": { - "driver": { - "name": "Semgrep OSS", - "rules": [ - { - "defaultConfiguration": { - "level": "warning" - }, - "fullDescription": { - "text": "[MASVS-STORAGE] Make sure you encrypt files in external storage if necessary" - }, - "help": { - "markdown": "[MASVS-STORAGE] Make sure you encrypt files in external storage if necessary", - "text": "[MASVS-STORAGE] Make sure you encrypt files in external storage if necessary" - }, - "id": "rules.mastg-android-data-unencrypted-external", - "name": "rules.mastg-android-data-unencrypted-external", - "properties": { - "precision": "very-high", - "tags": [] - }, - "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external" - } - } - ], - "semanticVersion": "1.63.0" - } - } - } - ], - "version": "2.1.0" -} \ No newline at end of file diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/run.sh deleted file mode 100644 index 463a8635d1..0000000000 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/run.sh +++ /dev/null @@ -1,2 +0,0 @@ -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external-manifest.yml ./AndroidManifest.xml --text -o output.txt -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external-manifest.yml ./AndroidManifest.xml --sarif -o output.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/rules/mastg-android-data-unencrypted-external-manifest.yml b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/rules/mastg-android-data-unencrypted-external-manifest.yml deleted file mode 100644 index 7d9390a94f..0000000000 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/rules/mastg-android-data-unencrypted-external-manifest.yml +++ /dev/null @@ -1,10 +0,0 @@ -rules: - - id: mastg-android-data-unencrypted-external-manifest - severity: WARNING - languages: - - generic - metadata: - summary: This rule looks for permissions that allows your app to write in External Storage - message: "[MASVS-STORAGE] Make sure you encrypt files in external storage if necessary" - patterns: - - pattern: WRITE_EXTERNAL_STORAGE diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/test.md deleted file mode 100644 index 687d5d080a..0000000000 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/test.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -platform: android -title: Declaration of the external storage permission -apis: [] -type: [static] ---- - -## Overview - -An app must declare an intent to write to external storage in order to save files in the public locations. - -## Steps - -1. Run a [static analysis](../../../../../techniques/android/MASTG-TECH-0014.md) tool on the app and look for a use of sensitive permissions. - - -## Observation - -The output shows that the manifest files declares `WRITE_EXTERNAL_STORAGE` permission at line 5. - -## Evaluation - -Inspect app's source code to make sure the data stored externally is secure. diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md index 233d1f12d6..50f6991a28 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md @@ -2,7 +2,7 @@ platform: android title: Find common APIs that return paths to External Storage locations tools: [semgrep] -code: [java] +code: [kotlin] --- ### Sample diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/output.sarif index 7583696973..9356e15fb3 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/output.sarif +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/output.sarif @@ -11,7 +11,7 @@ "results": [ { "fingerprints": { - "matchBasedId/v1": "7fff0cca477ae1b0a93a5b8e265d8a7471c4144464dcbbd55d7256be707b55568882a55bbac36d334816deb905d562cb7f9c4cee168fb02f8ca6f31936c62fb7_0" + "matchBasedId/v1": "86181ae035702aa50a67f6c5fcae0e9cd18f97887aa9e1ffcb70225f86d21062067e3925de964b722f4593b60fd959f1b9b0778f189a7183e0609be44faea0c5_0" }, "locations": [ { @@ -33,10 +33,10 @@ } ], "message": { - "text": "[MASVS-STORAGE] Make sure you encrypt files at these locations if necessary" + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" }, "properties": {}, - "ruleId": "rules.mastg-android-data-unencrypted-external" + "ruleId": "rules.mastg-android-data-unencrypted-external-api" } ], "tool": { @@ -48,20 +48,62 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure you encrypt files at these locations if necessary" + "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure you encrypt files at these locations if necessary", - "text": "[MASVS-STORAGE] Make sure you encrypt files at these locations if necessary" + "markdown": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary", + "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" }, - "id": "rules.mastg-android-data-unencrypted-external", - "name": "rules.mastg-android-data-unencrypted-external", + "id": "rules.mastg-android-data-unencrypted-external-manifest", + "name": "rules.mastg-android-data-unencrypted-external-manifest", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-manifest" + } + }, + { + "defaultConfiguration": { + "level": "warning" + }, + "fullDescription": { + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + }, + "help": { + "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + }, + "id": "rules.mastg-android-data-unencrypted-external-api", + "name": "rules.mastg-android-data-unencrypted-external-api", + "properties": { + "precision": "very-high", + "tags": [] + }, + "shortDescription": { + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-api" + } + }, + { + "defaultConfiguration": { + "level": "warning" + }, + "fullDescription": { + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + }, + "help": { + "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + }, + "id": "rules.mastg-android-data-unencrypted-external-mediastore", + "name": "rules.mastg-android-data-unencrypted-external-mediastore", + "properties": { + "precision": "very-high", + "tags": [] + }, + "shortDescription": { + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-mediastore" } } ], @@ -71,4 +113,4 @@ } ], "version": "2.1.0" -} \ No newline at end of file +} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/output.txt index f4672a559a..3cb80821b6 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/output.txt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/output.txt @@ -1,9 +1,11 @@ + + ┌────────────────┐ │ 1 Code Finding │ └────────────────┘ use-of-external-store.kt - rules.mastg-android-data-unencrypted-external 0m - [MASVS-STORAGE] Make sure you encrypt files at these locations if necessary - + ❯❱ rules.mastg-android-data-unencrypted-external-api + [MASVS-STORAGE] Make sure to encrypt files at these locations if necessary + 26┆ val externalDirPath = getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/run.sh old mode 100644 new mode 100755 diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/AndroidManifest.xml b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/AndroidManifest.xml similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/AndroidManifest.xml rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/AndroidManifest.xml diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/example.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/example.md similarity index 83% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/example.md rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/example.md index 41d92f39a2..9ea10c861e 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/example.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/example.md @@ -1,8 +1,8 @@ --- platform: android -title: Common APIs to return paths to External Storage +title: Find permissions that allows an app to write to locations shared with other apps tools: [semgrep] -code: [java] +code: [kotlin] --- ### Sample diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/output.sarif new file mode 100644 index 0000000000..7ed88f3db8 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/output.sarif @@ -0,0 +1,116 @@ +{ + "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json", + "runs": [ + { + "invocations": [ + { + "executionSuccessful": true, + "toolExecutionNotifications": [] + } + ], + "results": [ + { + "fingerprints": { + "matchBasedId/v1": "6aa4b8588a882dd4bcdb3d056b354663e9b7d6df919b1b9b26fd7f39f23b73467dd1a055148a14b9544c442214fcbb672a91534d0d59aa9d0ee720f2e2e668f4_0" + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "AndroidManifest.xml", + "uriBaseId": "%SRCROOT%" + }, + "region": { + "endColumn": 77, + "endLine": 5, + "snippet": { + "text": " " + }, + "startColumn": 55, + "startLine": 5 + } + } + } + ], + "message": { + "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + }, + "properties": {}, + "ruleId": "rules.mastg-android-data-unencrypted-external-manifest" + } + ], + "tool": { + "driver": { + "name": "Semgrep OSS", + "rules": [ + { + "defaultConfiguration": { + "level": "warning" + }, + "fullDescription": { + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + }, + "help": { + "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + }, + "id": "rules.mastg-android-data-unencrypted-external-mediastore", + "name": "rules.mastg-android-data-unencrypted-external-mediastore", + "properties": { + "precision": "very-high", + "tags": [] + }, + "shortDescription": { + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-mediastore" + } + }, + { + "defaultConfiguration": { + "level": "warning" + }, + "fullDescription": { + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + }, + "help": { + "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + }, + "id": "rules.mastg-android-data-unencrypted-external-api", + "name": "rules.mastg-android-data-unencrypted-external-api", + "properties": { + "precision": "very-high", + "tags": [] + }, + "shortDescription": { + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-api" + } + }, + { + "defaultConfiguration": { + "level": "warning" + }, + "fullDescription": { + "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + }, + "help": { + "markdown": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary", + "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + }, + "id": "rules.mastg-android-data-unencrypted-external-manifest", + "name": "rules.mastg-android-data-unencrypted-external-manifest", + "properties": { + "precision": "very-high", + "tags": [] + }, + "shortDescription": { + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-manifest" + } + } + ], + "semanticVersion": "1.63.0" + } + } + } + ], + "version": "2.1.0" +} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/output.txt similarity index 67% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/output.txt rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/output.txt index 0250a4b88f..34c6a72b0f 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static-manifest/example-1/output.txt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/output.txt @@ -5,7 +5,7 @@ └────────────────┘ AndroidManifest.xml - mrules.mastg-android-data-unencrypted-external - [MASVS-STORAGE] Make sure you encrypt files in external storage if necessary - + ❯❱ rules.mastg-android-data-unencrypted-external-manifest + [MASVS-STORAGE] Make sure to encrypt files in external storage if necessary + 5┆ diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/run.sh new file mode 100755 index 0000000000..a8b645d4eb --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/run.sh @@ -0,0 +1,2 @@ +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external.yml ./AndroidManifest.xml --text -o output.txt +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external.yml ./AndroidManifest.xml --sarif -o output.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/example.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/example.md new file mode 100644 index 0000000000..91ba9a9eac --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/example.md @@ -0,0 +1,30 @@ +--- +platform: android +title: Find MediaStore APIs that writes data to locations shared with other apps +tools: [semgrep] +code: [kotlin] +--- + +### Sample + +{{ use-of-mediastore.kt }} + +### Steps + +Let's run our semgrep rule against the sample code. + +{{ ../rules/mastg-android-data-unencrypted-external.yml }} + +{{ run.sh }} + +### Observation + +The rule has identified 5 locations in the code which refer to the same MediaStore use. + +{{ output.txt }} + +### Evaluation + +Review the reported instances and make sure to either: +- confirm you intended to make this data public +- store this data in a more strict storage type diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/output.sarif new file mode 100644 index 0000000000..f4f8e87c67 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/output.sarif @@ -0,0 +1,232 @@ +{ + "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json", + "runs": [ + { + "invocations": [ + { + "executionSuccessful": true, + "toolExecutionNotifications": [] + } + ], + "results": [ + { + "fingerprints": { + "matchBasedId/v1": "0863f3399c1ce2db808b0bc40f299ca16c02e7f2b20f894ae803e49e33a42c820871071aa041eef8f313ea699424e8ca6670bfa8df2baf9c7a1b731c2b283271_0" + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "use-of-mediastore.kt", + "uriBaseId": "%SRCROOT%" + }, + "region": { + "endColumn": 35, + "endLine": 4, + "snippet": { + "text": "import android.provider.MediaStore" + }, + "startColumn": 25, + "startLine": 4 + } + } + } + ], + "message": { + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + }, + "properties": {}, + "ruleId": "rules.mastg-android-data-unencrypted-external-mediastore" + }, + { + "fingerprints": { + "matchBasedId/v1": "0863f3399c1ce2db808b0bc40f299ca16c02e7f2b20f894ae803e49e33a42c820871071aa041eef8f313ea699424e8ca6670bfa8df2baf9c7a1b731c2b283271_1" + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "use-of-mediastore.kt", + "uriBaseId": "%SRCROOT%" + }, + "region": { + "endColumn": 41, + "endLine": 13, + "snippet": { + "text": " contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, \"sampleName\")" + }, + "startColumn": 31, + "startLine": 13 + } + } + } + ], + "message": { + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + }, + "properties": {}, + "ruleId": "rules.mastg-android-data-unencrypted-external-mediastore" + }, + { + "fingerprints": { + "matchBasedId/v1": "0863f3399c1ce2db808b0bc40f299ca16c02e7f2b20f894ae803e49e33a42c820871071aa041eef8f313ea699424e8ca6670bfa8df2baf9c7a1b731c2b283271_2" + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "use-of-mediastore.kt", + "uriBaseId": "%SRCROOT%" + }, + "region": { + "endColumn": 41, + "endLine": 14, + "snippet": { + "text": " contentValues.put(MediaStore.MediaColumns.MIME_TYPE, \"image/jpg\")" + }, + "startColumn": 31, + "startLine": 14 + } + } + } + ], + "message": { + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + }, + "properties": {}, + "ruleId": "rules.mastg-android-data-unencrypted-external-mediastore" + }, + { + "fingerprints": { + "matchBasedId/v1": "0863f3399c1ce2db808b0bc40f299ca16c02e7f2b20f894ae803e49e33a42c820871071aa041eef8f313ea699424e8ca6670bfa8df2baf9c7a1b731c2b283271_3" + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "use-of-mediastore.kt", + "uriBaseId": "%SRCROOT%" + }, + "region": { + "endColumn": 41, + "endLine": 15, + "snippet": { + "text": " contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)" + }, + "startColumn": 31, + "startLine": 15 + } + } + } + ], + "message": { + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + }, + "properties": {}, + "ruleId": "rules.mastg-android-data-unencrypted-external-mediastore" + }, + { + "fingerprints": { + "matchBasedId/v1": "0863f3399c1ce2db808b0bc40f299ca16c02e7f2b20f894ae803e49e33a42c820871071aa041eef8f313ea699424e8ca6670bfa8df2baf9c7a1b731c2b283271_4" + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "use-of-mediastore.kt", + "uriBaseId": "%SRCROOT%" + }, + "region": { + "endColumn": 43, + "endLine": 17, + "snippet": { + "text": " resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)" + }, + "startColumn": 33, + "startLine": 17 + } + } + } + ], + "message": { + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + }, + "properties": {}, + "ruleId": "rules.mastg-android-data-unencrypted-external-mediastore" + } + ], + "tool": { + "driver": { + "name": "Semgrep OSS", + "rules": [ + { + "defaultConfiguration": { + "level": "warning" + }, + "fullDescription": { + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + }, + "help": { + "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + }, + "id": "rules.mastg-android-data-unencrypted-external-api", + "name": "rules.mastg-android-data-unencrypted-external-api", + "properties": { + "precision": "very-high", + "tags": [] + }, + "shortDescription": { + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-api" + } + }, + { + "defaultConfiguration": { + "level": "warning" + }, + "fullDescription": { + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + }, + "help": { + "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + }, + "id": "rules.mastg-android-data-unencrypted-external-mediastore", + "name": "rules.mastg-android-data-unencrypted-external-mediastore", + "properties": { + "precision": "very-high", + "tags": [] + }, + "shortDescription": { + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-mediastore" + } + }, + { + "defaultConfiguration": { + "level": "warning" + }, + "fullDescription": { + "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + }, + "help": { + "markdown": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary", + "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + }, + "id": "rules.mastg-android-data-unencrypted-external-manifest", + "name": "rules.mastg-android-data-unencrypted-external-manifest", + "properties": { + "precision": "very-high", + "tags": [] + }, + "shortDescription": { + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-manifest" + } + } + ], + "semanticVersion": "1.63.0" + } + } + } + ], + "version": "2.1.0" +} \ No newline at end of file diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/output.txt new file mode 100644 index 0000000000..9926981295 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/output.txt @@ -0,0 +1,19 @@ + + +┌─────────────────┐ +│ 5 Code Findings │ +└─────────────────┘ + + use-of-mediastore.kt + ❯❱ rules.mastg-android-data-unencrypted-external-mediastore + [MASVS-STORAGE] Make sure to want this data to be shared with other apps + + 4┆ import android.provider.MediaStore + ⋮┆---------------------------------------- + 13┆ contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, "sampleName") + ⋮┆---------------------------------------- + 14┆ contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg") + ⋮┆---------------------------------------- + 15┆ contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES) + ⋮┆---------------------------------------- + 17┆ resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/run.sh new file mode 100755 index 0000000000..a9fa816c58 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/run.sh @@ -0,0 +1,2 @@ +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external.yml ./use-of-mediastore.kt --text -o output.txt +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external.yml ./use-of-mediastore.kt --sarif -o output.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/use-of-mediastore.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/use-of-mediastore.kt new file mode 100644 index 0000000000..71ffbd9bb9 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/use-of-mediastore.kt @@ -0,0 +1,23 @@ +import android.content.ContentValues +import android.content.Context +import android.os.Environment +import android.provider.MediaStore +import android.widget.Toast + +class ImageController { + + fun saveImageToMediaStore(context: Context) { + try { + val resolver = context.contentResolver + val contentValues = ContentValues() + contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, "sampleName") + contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg") + contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES) + val imageUri = + resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues) + /// ... + } catch (exception: Exception) { + Toast.makeText(context, exception.toString(), Toast.LENGTH_SHORT).show() + } + } +} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/rules/mastg-android-data-unencrypted-external.yml b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/rules/mastg-android-data-unencrypted-external.yml index 96ad04d373..a95ebd5468 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/rules/mastg-android-data-unencrypted-external.yml +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/rules/mastg-android-data-unencrypted-external.yml @@ -1,21 +1,39 @@ rules: - - id: mastg-android-data-unencrypted-external + - id: mastg-android-data-unencrypted-external-api severity: WARNING languages: - kotlin metadata: - summary: This rule looks for methods that returns locations to external storage - message: "[MASVS-STORAGE] Make sure you encrypt files at these locations if necessary" + summary: This rule looks for methods that returns locations to "external storage" which is shared with other apps + message: "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" pattern-either: - - patterns: - - pattern-either: - - pattern: getExternalFilesDir(...) - - pattern: getExternalStorageDirectory(...) - - pattern: getExternalStoragePublicDirectory(...) - - pattern: getExternalCacheDir(...) - - pattern: getDownloadCacheDirectory(...) - - pattern: Intent.ACTION_CREATE_DOCUMENT - - - + - pattern: getExternalFilesDir(...) + - pattern: getExternalStorageDirectory(...) + - pattern: getExternalStoragePublicDirectory(...) + - pattern: getExternalCacheDir(...) + - pattern: getDownloadCacheDirectory(...) + - pattern: Intent.ACTION_CREATE_DOCUMENT + - id: mastg-android-data-unencrypted-external-manifest + severity: WARNING + languages: + - generic + metadata: + summary: This rule scans for permissions that allows your app to write to external storage or shared storage + message: "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + pattern-either: + - pattern: WRITE_EXTERNAL_STORAGE + - pattern: MANAGE_EXTERNAL_STORAGE + - pattern: ACCESS_ALL_EXTERNAL_STORAGE + - pattern: requestLegacyExternalStorage="true" + - pattern: preserveLegacyExternalStorage="true" + - pattern: android:requestRawExternalStorageAccess="true" + - id: mastg-android-data-unencrypted-external-mediastore + severity: WARNING + languages: + - generic + metadata: + summary: This rule scans for uses of MediaStore API that writes data to the external storage. This data can be accessed by other apps. + message: "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + pattern-either: + - pattern: MediaStore diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/test.md index 4ab1b77137..427c2ec796 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/test.md @@ -1,25 +1,52 @@ --- platform: android -title: Usage of API to get to external storage locations -apis: [Environment#getExternalStoragePublicDirectory, Environment#getExternalStorageDirectory, Environment#getExternalFilesDir, Environment#getExternalCacheDir] +title: Use of app permissions and APIs to access storage locations shared with other apps +apis: [Environment#getExternalStoragePublicDirectory, Environment#getExternalStorageDirectory, Environment#getExternalFilesDir, Environment#getExternalCacheDir, MediaStore] type: [static] --- ## Overview -Developers can obtain paths to the external storage locations with `Environment.getExternal...` methods. This test searches for a set of APIs that are commonly used for obtaining external storage locations in source code. +This test searches for Manifest permissions and APIs that let your app write to locations which are shared with other apps. It means that a third-party app with a proper permissions may access data you write to these locations. Therefore, this test verifies whether an app: +* declares permissions required to write data to shared locations +* uses API to obtain location to shared locations +* uses MediaStore API + +Additionally, if the "external storage" is actually stored externally e.g. on an sd-card, it can be removed from the device and connected to a card reader to extract sensitive data. + +### Testing Manifest permissions + +An app must declare in the Manifest file an intention to write to shared locations. Below you can find a list of such manifest permissions: +* [WRITE_EXTERNAL_STORAGE](https://developer.android.com/reference/android/Manifest.permission#WRITE_EXTERNAL_STORAGE) - allows an app to write a file to the "external storage" which either resides on an external disk, or is internally emulated by the system. Regardless the actual storage origin, this permissions allows an app to write files to locations shared with other apps. This permission is deprecated starting from `target API 30` but can be preserved with [requestLegacyExternalStorage](https://developer.android.com/reference/android/R.attr#requestLegacyExternalStorage) and [preserveLegacyExternalStorage](https://developer.android.com/reference/android/R.attr#preserveLegacyExternalStorage). +* [MANAGE_EXTERNAL_STORAGE](https://developer.android.com/reference/android/Manifest.permission#MANAGE_EXTERNAL_STORAGE) - a successor permission of `WRITE_EXTERNAL_STORAGE`. It allows an an app to read and write files to shared locations. + +### Testing External Storage APIs + +There are APIs such as [[[getExternalStoragePublicDirectory]]](https://developer.android.com/reference/kotlin/android/os/Environment#getExternalStoragePublicDirectory(kotlin.String)) +that return paths to a shared locations that other apps can access. [Example 1](./example-1/example.md) illustrates a case where an app obtains a path to an "external" location and writes sensitive data to it. This location is Shared Storage Requiring No User Interaction, so a third-party app with proper permissions can read this sensitive data. + +#### External app-specific files + +A malicious app with proper permissions running on Android 10 or below can access data that you write to "external" [app-specific-directories](https://developer.android.com/training/data-storage/app-specific). + +### Testing MediaStore API + +If your app stores data with MediaStore API, a third-party app with proper permissions may read this data. ## Steps -1. Run a [static analysis](../../../../../techniques/android/MASTG-TECH-0014.md) tool on the app and look for uses of `getExternal...` API. +1. Run a [static analysis](../../../../../techniques/android/MASTG-TECH-0014.md) tool on an app to find whether your app uses storage locations shared with other apps and pinpoint the invocations of these APIs. ## Observation -The output should contain a **list of locations where paths to external storage are returned**. +The output should contain a list of permissions and locations where paths to external storage are returned. ## Evaluation -Inspect app's source code using the provided location information. +Inspect app's source code using the provided information. The test case fails if you find code that writes sensitive unencrypted to these locations. + +## References -The test case fails if you find code that writes sensitive unencrypted to these locations. +1. https://developer.android.com/training/data-storage/manage-all-files +2. https://developer.android.com/training/data-storage/shared/media From 7d230211f3a36fd22a58640bd6d639901361a1e6 Mon Sep 17 00:00:00 2001 From: Jan Seredynski Date: Tue, 7 May 2024 12:41:06 +0200 Subject: [PATCH 05/33] Update the title of a static test --- .../android-data-unencrypted-external-static/test.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/test.md index 427c2ec796..a5aba1cf33 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/test.md @@ -1,6 +1,6 @@ --- platform: android -title: Use of app permissions and APIs to access storage locations shared with other apps +title: Use of APIs to access External Storage Locations apis: [Environment#getExternalStoragePublicDirectory, Environment#getExternalStorageDirectory, Environment#getExternalFilesDir, Environment#getExternalCacheDir, MediaStore] type: [static] --- From d2df0dea24fd85ced28f41dc6e7df56d145c3cd8 Mon Sep 17 00:00:00 2001 From: Jan Seredynski Date: Tue, 7 May 2024 12:59:25 +0200 Subject: [PATCH 06/33] Update examples and fix spellings --- .../example-1/example.md | 2 +- .../android-data-unencrypted-external-frida/test.md | 12 +++++++----- .../example-1/example.md | 2 +- .../data-unencrypted-external/risk.md | 4 ++-- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/example.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/example.md index f1a1358854..237ba16850 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/example.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/example.md @@ -21,7 +21,7 @@ The snippet below shows sample code that creates a file in external storage. You ### Observation -The script will output the findings into `output.txt` +There is only one file written to the external storage - `/storage/emulated/0/Android/data/com.gs.owasp_storage_app1/files/secret.json`. Make sure you don't store unencrypted data there unintentionally. {{ output.txt }} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/test.md index 221df627ee..458f0bebc4 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/test.md @@ -7,17 +7,19 @@ type: [dynamic] ## Overview -Android apps use a variety of APIs to obtain a file path and store a file. Collecting a comprehensive list of these APIs can be challenging, especially if an app uses a third-party framework, loads code at runtime, or includes native code. The most effective approach to testing applications that write to device memory is usually dynamic analysis, and specifically method tracing. +Android apps use a variety of APIs to obtain a file path and store a file. Collecting a comprehensive list of these APIs can be challenging, especially if an app uses a third-party framework, loads code at runtime, or includes native code. The most effective approach to testing applications that write to device storage is usually dynamic analysis, and specifically method tracing. ## Steps -1. Install the app. +1. Make sure you have Frida installed -2. Execute a [method trace](https://mas.owasp.org/MASTG/techniques/android/MASTG-TECH-00xx/) to spawn an app and log all interactions with files. +2. Install the app. -3. Navigate to the screen of the mobile app that you want to analyse. +3. Execute a `run.sh` to spawn an app with Frida and log all interactions with files. -4. Close the app to stop `frida-trace` +4. Navigate to the screen of the mobile app that you want to analyse. + +5. Close the app to stop `frida` ## Observation diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md index 50f6991a28..9c2322dcd9 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md @@ -19,7 +19,7 @@ Let's run our semgrep rule against the sample code. ### Observation -The rule has identified 1 location in the code file where a path to external storage is retuened. Make sure you don't store unencrypted code there unintentionally. +The rule has identified 1 location in the code file where a path to external storage is retuened. Make sure you don't store unencrypted data there unintentionally. {{ output.txt }} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/risk.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/risk.md index b226a9a5ef..31f25a106e 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/risk.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/risk.md @@ -1,5 +1,5 @@ --- -title: Sensitive Data Stored Unencrypted in External Locations +title: Sensitive Data Stored in Shared Storage Requiring No User Interaction alias: data-unencrypted-external platform: [android] profiles: [L1, L2] @@ -41,6 +41,6 @@ This threat is primarily a concern for Android devices since they permit the use ## Mitigations -Sensitive data stored in the external storage should be encrypted, and any keys used for encryption methods should be protected by the device's hardware-backed keystore, where available. It is highly discouraged to include a cryptographic key inside the application. +Sensitive data stored in the external storage should be encrypted, and any keys used for encryption methods should be protected by the device's hardware-backed keystore, where available. It is highly discouraged to include a cryptographic key inside the application. You can also consider storing your files in the Private App Sandbox Storage. - [Android's EncryptedFile API wrapper for file encryption](https://developer.android.com/reference/androidx/security/crypto/EncryptedFile) From cc126f0ecba0bf3e9ed53e339685c2d5b6d76cf9 Mon Sep 17 00:00:00 2001 From: Jan Seredynski Date: Tue, 7 May 2024 15:38:11 +0200 Subject: [PATCH 07/33] Added rules from Olivier --- .../rules/mastg-android-data-unencrypted-external.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/rules/mastg-android-data-unencrypted-external.yml b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/rules/mastg-android-data-unencrypted-external.yml index a95ebd5468..b60cb602ab 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/rules/mastg-android-data-unencrypted-external.yml +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/rules/mastg-android-data-unencrypted-external.yml @@ -8,9 +8,12 @@ rules: message: "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" pattern-either: - pattern: getExternalFilesDir(...) + - pattern: getExternalFilesDirs(...) - pattern: getExternalStorageDirectory(...) - pattern: getExternalStoragePublicDirectory(...) - pattern: getExternalCacheDir(...) + - pattern: getExternalCacheDirs(...) + - pattern: getExternalMediaDirs(...) - pattern: getDownloadCacheDirectory(...) - pattern: Intent.ACTION_CREATE_DOCUMENT - id: mastg-android-data-unencrypted-external-manifest From 3cb96d2027053185492350414ceefbb5425f5dbf Mon Sep 17 00:00:00 2001 From: Jan Seredynski Date: Mon, 3 Jun 2024 14:53:16 +0200 Subject: [PATCH 08/33] Apply suggestions from code review Co-authored-by: Carlos Holguera --- .../example-1/example.md | 6 ++-- .../example-1/snippet.kt | 25 ++++++++++++---- .../example-1/example.md | 7 ++--- .../example-1/run.sh | 4 +-- .../example-2/run.sh | 4 +-- ...astg-android-data-unencrypted-external.yml | 20 ++++++------- .../test.md | 30 +++++++++++-------- .../data-unencrypted-external/risk.md | 4 +-- 8 files changed, 59 insertions(+), 41 deletions(-) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/example.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/example.md index 237ba16850..1af093cbec 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/example.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/example.md @@ -7,7 +7,7 @@ code: [kotlin] ### Sample -The snippet below shows sample code that creates a file in external storage. You can put this code into your app and follow the steps below to identify a potential data leak. +The snippet below shows sample code that creates a file in external storage. {{ snippet.kt }} @@ -21,10 +21,10 @@ The snippet below shows sample code that creates a file in external storage. You ### Observation -There is only one file written to the external storage - `/storage/emulated/0/Android/data/com.gs.owasp_storage_app1/files/secret.json`. Make sure you don't store unencrypted data there unintentionally. +There is only one file written to the external storage - `/storage/emulated/0/Android/data/org.owasp.mastestapp/files/secret.json`. {{ output.txt }} ### Evaluation -Review each warning in the output file and make sure you intended to store this file in the external storage. +This test fails since the file contains a password. diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/snippet.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/snippet.kt index 4b192083aa..7e39ac520b 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/snippet.kt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/snippet.kt @@ -1,7 +1,22 @@ -// On lower Android versions, you might need to add `WRITE_EXTERNAL_STORAGE` permission to the manifest to write to an external app-specific directory. +package org.owasp.mastestapp + +import android.content.Context +import android.os.Environment +import android.os.Environment.getExternalStoragePublicDirectory +import java.io.File +import java.io.FileOutputStream + +class MastgTest (private val context: Context){ + + fun mastgTest(): String { + val secret1 = "{\"password\":\"12345\"}\n" + val externalDirPath = getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + val file1 = File("$externalDirPath/secrets.json") + FileOutputStream(file1).use { fos -> + fos.write(secret1.toByteArray()) + } + + return "Secrets written to $file1:\n\n$secret1" + } -val externalDirPath = getExternalFilesDir(null)!!.absolutePath -val file: File = File("$externalDirPath/secret.json") -FileOutputStream(file).use { fos -> - fos.write("password:123".toByteArray()) } diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md index 9c2322dcd9..fdb338b3f6 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md @@ -19,14 +19,11 @@ Let's run our semgrep rule against the sample code. ### Observation -The rule has identified 1 location in the code file where a path to external storage is retuened. Make sure you don't store unencrypted data there unintentionally. +The rule has identified one location in the code file where a path to external storage is returned. {{ output.txt }} ### Evaluation -Review each of the reported instances. In this case, it's only one instance. Line 9 shows the occurrence of API that returns external storage location. Make sure to either: -- encrypt this file if necessary -- move the file to the internal storage -- keep the file in the same location if intended and secure +Review the decompiled code at the location specified in the output (file and line number). This test fails because the file written by this instance contains sensitive data, specifically a password. diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/run.sh index a8623be3ec..5336943a7e 100755 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/run.sh +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/run.sh @@ -1,2 +1,2 @@ -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external.yml ./use-of-external-store.kt --text -o output.txt -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external.yml ./use-of-external-store.kt --sarif -o output.sarif +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external.yml ./MastgTest_reversed.java --text -o output.txt +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external.yml ./MastgTest_reversed.java --sarif -o output.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/run.sh index a8b645d4eb..aaf1e2c714 100755 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/run.sh +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/run.sh @@ -1,2 +1,2 @@ -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external.yml ./AndroidManifest.xml --text -o output.txt -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external.yml ./AndroidManifest.xml --sarif -o output.sarif +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external.yml ./AndroidManifest_reversed.xml --text -o output.txt +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external.yml ./AndroidManifest_reversed.xml --sarif -o output.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/rules/mastg-android-data-unencrypted-external.yml b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/rules/mastg-android-data-unencrypted-external.yml index b60cb602ab..f6b3db4915 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/rules/mastg-android-data-unencrypted-external.yml +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/rules/mastg-android-data-unencrypted-external.yml @@ -2,19 +2,19 @@ rules: - id: mastg-android-data-unencrypted-external-api severity: WARNING languages: - - kotlin + - java metadata: summary: This rule looks for methods that returns locations to "external storage" which is shared with other apps message: "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" pattern-either: - - pattern: getExternalFilesDir(...) - - pattern: getExternalFilesDirs(...) - - pattern: getExternalStorageDirectory(...) - - pattern: getExternalStoragePublicDirectory(...) - - pattern: getExternalCacheDir(...) - - pattern: getExternalCacheDirs(...) - - pattern: getExternalMediaDirs(...) - - pattern: getDownloadCacheDirectory(...) + - pattern: $X.getExternalFilesDir(...) + - pattern: $X.getExternalFilesDirs(...) + - pattern: $X.getExternalStorageDirectory(...) + - pattern: $X.getExternalStoragePublicDirectory(...) + - pattern: $X.getExternalCacheDir(...) + - pattern: $X.getExternalCacheDirs(...) + - pattern: $X.getExternalMediaDirs(...) + - pattern: $X.getDownloadCacheDirectory(...) - pattern: Intent.ACTION_CREATE_DOCUMENT - id: mastg-android-data-unencrypted-external-manifest severity: WARNING @@ -33,7 +33,7 @@ rules: - id: mastg-android-data-unencrypted-external-mediastore severity: WARNING languages: - - generic + - java metadata: summary: This rule scans for uses of MediaStore API that writes data to the external storage. This data can be accessed by other apps. message: "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/test.md index a5aba1cf33..8ccb592ab6 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/test.md @@ -7,23 +7,28 @@ type: [static] ## Overview -This test searches for Manifest permissions and APIs that let your app write to locations which are shared with other apps. It means that a third-party app with a proper permissions may access data you write to these locations. Therefore, this test verifies whether an app: -* declares permissions required to write data to shared locations -* uses API to obtain location to shared locations -* uses MediaStore API +This test looks for Android manifest permissions and APIs that allow an app to write to locations that are shared with other apps. This means that a third-party app with the proper permissions may be able to access data written to these locations. Therefore, this test verifies whether an app: -Additionally, if the "external storage" is actually stored externally e.g. on an sd-card, it can be removed from the device and connected to a card reader to extract sensitive data. +- declares permissions required to write data to shared locations +- uses API to obtain location to shared locations +- uses MediaStore API + +Additionally, if the "external storage" is actually stored externally, e.g. on an SD card, it can be removed from the device and inserted into a card reader to extract sensitive data. ### Testing Manifest permissions An app must declare in the Manifest file an intention to write to shared locations. Below you can find a list of such manifest permissions: -* [WRITE_EXTERNAL_STORAGE](https://developer.android.com/reference/android/Manifest.permission#WRITE_EXTERNAL_STORAGE) - allows an app to write a file to the "external storage" which either resides on an external disk, or is internally emulated by the system. Regardless the actual storage origin, this permissions allows an app to write files to locations shared with other apps. This permission is deprecated starting from `target API 30` but can be preserved with [requestLegacyExternalStorage](https://developer.android.com/reference/android/R.attr#requestLegacyExternalStorage) and [preserveLegacyExternalStorage](https://developer.android.com/reference/android/R.attr#preserveLegacyExternalStorage). -* [MANAGE_EXTERNAL_STORAGE](https://developer.android.com/reference/android/Manifest.permission#MANAGE_EXTERNAL_STORAGE) - a successor permission of `WRITE_EXTERNAL_STORAGE`. It allows an an app to read and write files to shared locations. + +- [WRITE_EXTERNAL_STORAGE](https://developer.android.com/reference/android/Manifest.permission#WRITE_EXTERNAL_STORAGE): allows an app to write a file to the "external storage", regardless of the actual storage origin (external disk or internally emulated by the system). + - This permission is **deprecated since Android 11.0 (API level 30)** but can be preserved with [requestLegacyExternalStorage](https://developer.android.com/reference/android/R.attr#requestLegacyExternalStorage) and [preserveLegacyExternalStorage](https://developer.android.com/reference/android/R.attr#preserveLegacyExternalStorage). + - If the app declares a minSdkVersion of 19 or higher, you don't need to declare this permission to read and write files in your application-specific directories returned by [Context.getExternalFilesDir(String)](https://developer.android.com/reference/android/content/Context#getExternalFilesDir(java.lang.String)) and [Context.getExternalCacheDir()](https://developer.android.com/reference/android/content/Context#getExternalCacheDir()). + - On Android 4.4 (API level 19) or higher, your app doesn't need to request any storage-related permissions to access app-specific directories within external storage. The files stored in these directories are removed when your app is uninstalled. See . + - On devices that run Android 9 (API level 28) or lower, your app can access the app-specific files that belong to other apps, provided that your app has the appropriate storage permissions. To give users more control over their files and to limit file clutter, apps that target Android 10 (API level 29) and higher are given scoped access into external storage, or [scoped storage](https://developer.android.com/training/data-storage#scoped-storage), by default. When scoped storage is enabled, apps cannot access the app-specific directories that belong to other apps. +- [MANAGE_EXTERNAL_STORAGE](https://developer.android.com/reference/android/Manifest.permission#MANAGE_EXTERNAL_STORAGE): a successor permission of `WRITE_EXTERNAL_STORAGE`. It allows an an app to read and write files to shared locations special app access called ["All files access"](https://developer.android.com/preview/privacy/storage#all-files-access). This permission only applies to apps target Android 11.0 (API level 30) and its usage is restricted by Google Play unless the app satisfies [certain requirements](https://support.google.com/googleplay/android-developer/answer/10467955). ### Testing External Storage APIs -There are APIs such as [[[getExternalStoragePublicDirectory]]](https://developer.android.com/reference/kotlin/android/os/Environment#getExternalStoragePublicDirectory(kotlin.String)) -that return paths to a shared locations that other apps can access. [Example 1](./example-1/example.md) illustrates a case where an app obtains a path to an "external" location and writes sensitive data to it. This location is Shared Storage Requiring No User Interaction, so a third-party app with proper permissions can read this sensitive data. +There are APIs such as [`getExternalStoragePublicDirectory`](https://developer.android.com/reference/kotlin/android/os/Environment#getExternalStoragePublicDirectory(kotlin.String)) that return paths to a shared location that other apps can access. [Demo 1](demo-1/demo.md) illustrates a case where an app obtains a path to an "external" location and writes sensitive data to it. This location is Shared Storage Requiring No User Interaction, so a third-party app with proper permissions can read this sensitive data. #### External app-specific files @@ -35,7 +40,7 @@ If your app stores data with MediaStore API, a third-party app with proper permi ## Steps -1. Run a [static analysis](../../../../../techniques/android/MASTG-TECH-0014.md) tool on an app to find whether your app uses storage locations shared with other apps and pinpoint the invocations of these APIs. +1. Run a [static analysis](../../../../../techniques/android/MASTG-TECH-0014.md) tool on the app to find if it uses storage locations shared with other apps, and identify the calls to those APIs and the relevant permissions. ## Observation @@ -48,5 +53,6 @@ Inspect app's source code using the provided information. The test case fails if ## References -1. https://developer.android.com/training/data-storage/manage-all-files -2. https://developer.android.com/training/data-storage/shared/media +- [Manage all files on a storage device](https://developer.android.com/training/data-storage/manage-all-files) +- [Access media files from shared storage](https://developer.android.com/training/data-storage/shared/media) + diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/risk.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/risk.md index 31f25a106e..07ed81a678 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/risk.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/risk.md @@ -1,6 +1,6 @@ --- -title: Sensitive Data Stored in Shared Storage Requiring No User Interaction -alias: data-unencrypted-external +title: Sensitive Data Stored Unencrypted in Shared Storage Requiring No User Interaction +alias: data-unencrypted-shared-storage-no-user-interaction platform: [android] profiles: [L1, L2] mappings: From dfb01ff6610053345240a8ca2a46867ccd718e89 Mon Sep 17 00:00:00 2001 From: Jan Seredynski Date: Mon, 3 Jun 2024 15:08:10 +0200 Subject: [PATCH 09/33] Rename Sample to Demo --- .../demo-1/demo.md} | 2 +- .../demo-1}/output.txt | 0 .../demo-1}/run.sh | 0 .../demo-1}/script.js | 0 .../demo-1}/snippet.kt | 0 .../test.md | 0 .../demo-1/demo.md} | 2 +- .../demo-1}/output.sarif | 0 .../demo-1}/output.txt | 0 .../demo-1}/run.sh | 0 .../demo-1}/use-of-external-store.kt | 0 .../demo-2}/AndroidManifest.xml | 0 .../demo-2/demo.md} | 2 +- .../demo-2}/output.sarif | 0 .../demo-2}/output.txt | 0 .../demo-2}/run.sh | 0 .../demo-3/demo.md} | 2 +- .../demo-3}/output.sarif | 0 .../demo-3}/output.txt | 0 .../demo-3}/run.sh | 0 .../demo-3}/use-of-mediastore.kt | 0 .../rules/mastg-android-data-unencrypted-external.yml | 0 .../test.md | 0 .../risk.md | 0 24 files changed, 4 insertions(+), 4 deletions(-) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-frida/example-1/example.md => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/demo.md} (98%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-frida/example-1 => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1}/output.txt (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-frida/example-1 => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1}/run.sh (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-frida/example-1 => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1}/script.js (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-frida/example-1 => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1}/snippet.kt (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-frida => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida}/test.md (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md} (98%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-static/example-1 => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1}/output.sarif (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-static/example-1 => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1}/output.txt (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-static/example-1 => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1}/run.sh (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-static/example-1 => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1}/use-of-external-store.kt (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-static/example-2 => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2}/AndroidManifest.xml (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-static/example-2/example.md => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md} (98%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-static/example-2 => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2}/output.sarif (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-static/example-2 => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2}/output.txt (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-static/example-2 => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2}/run.sh (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-static/example-3/example.md => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md} (98%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-static/example-3 => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3}/output.sarif (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-static/example-3 => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3}/output.txt (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-static/example-3 => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3}/run.sh (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-static/example-3 => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3}/use-of-mediastore.kt (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-static => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static}/rules/mastg-android-data-unencrypted-external.yml (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external/android-data-unencrypted-external-static => data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static}/test.md (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/{data-unencrypted-external => data-unencrypted-shared-storage-no-user-interaction}/risk.md (100%) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/example.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/demo.md similarity index 98% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/example.md rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/demo.md index 1af093cbec..b7aea37f17 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/example.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/demo.md @@ -5,7 +5,7 @@ tools: [frida] code: [kotlin] --- -### Sample +### Demo The snippet below shows sample code that creates a file in external storage. diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/output.txt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/output.txt rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/output.txt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/run.sh similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/run.sh rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/run.sh diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/script.js b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/script.js similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/script.js rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/script.js diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/snippet.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/snippet.kt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/example-1/snippet.kt rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/snippet.kt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/test.md similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-frida/test.md rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/test.md diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md similarity index 98% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md index fdb338b3f6..1f1c850421 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/example.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md @@ -5,7 +5,7 @@ tools: [semgrep] code: [kotlin] --- -### Sample +### Demo {{ use-of-external-store.kt }} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/output.sarif rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.txt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/output.txt rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.txt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/run.sh rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/use-of-external-store.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/use-of-external-store.kt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-1/use-of-external-store.kt rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/use-of-external-store.kt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/AndroidManifest.xml b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/AndroidManifest.xml similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/AndroidManifest.xml rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/AndroidManifest.xml diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/example.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md similarity index 98% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/example.md rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md index 9ea10c861e..2809557e76 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/example.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md @@ -5,7 +5,7 @@ tools: [semgrep] code: [kotlin] --- -### Sample +### Demo {{ use-of-external-store.kt }} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/output.sarif rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/output.txt rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-2/run.sh rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/example.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md similarity index 98% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/example.md rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md index 91ba9a9eac..c34e3deb33 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/example.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md @@ -5,7 +5,7 @@ tools: [semgrep] code: [kotlin] --- -### Sample +### Demo {{ use-of-mediastore.kt }} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.sarif similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/output.sarif rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.txt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/output.txt rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.txt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/run.sh similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/run.sh rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/run.sh diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/use-of-mediastore.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/use-of-mediastore.kt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/example-3/use-of-mediastore.kt rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/use-of-mediastore.kt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/rules/mastg-android-data-unencrypted-external.yml b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-external.yml similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/rules/mastg-android-data-unencrypted-external.yml rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-external.yml diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/android-data-unencrypted-external-static/test.md rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/risk.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/risk.md similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-external/risk.md rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/risk.md From badad99ee2d431a5ba154ad17565fd821d03735c Mon Sep 17 00:00:00 2001 From: Jan Seredynski Date: Mon, 3 Jun 2024 15:31:19 +0200 Subject: [PATCH 10/33] Update demo-2 with a reversed manifest file --- .../demo-2/AndroidManifest.xml | 8 ++--- .../demo-2/AndroidManifest_reversed.xml | 34 ++++++++++++++++++ .../demo-2/demo.md | 8 ++--- .../demo-2/output.sarif | 36 +++++++++---------- .../demo-2/output.txt | 6 ++-- .../demo-3/demo.md | 2 +- ...ed-shared-storage-no-user-interaction.yml} | 0 7 files changed, 64 insertions(+), 30 deletions(-) create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/AndroidManifest_reversed.xml rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/{mastg-android-data-unencrypted-external.yml => mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml} (100%) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/AndroidManifest.xml b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/AndroidManifest.xml index 67c0372dea..9d1a99b7b9 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/AndroidManifest.xml +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/AndroidManifest.xml @@ -2,8 +2,7 @@ - - + + android:exported="true" + android:theme="@style/Theme.MASTestApp"> diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/AndroidManifest_reversed.xml b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/AndroidManifest_reversed.xml new file mode 100644 index 0000000000..dffe8e6411 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/AndroidManifest_reversed.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md index 2809557e76..35cce25088 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md @@ -2,24 +2,24 @@ platform: android title: Find permissions that allows an app to write to locations shared with other apps tools: [semgrep] -code: [kotlin] +code: [xml] --- ### Demo -{{ use-of-external-store.kt }} +{{ AndroidManifest_reversed.xml }} ### Steps Let's run our semgrep rule against the sample manifest file. -{{ ../rules/mastg-android-data-unencrypted-external-manifest.yml }} +{{ ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml }} {{ run.sh }} ### Observation -The rule has identified that the manifest file declares `WRITE_EXTERNAL_STORAGE` permission at line 9. +The rule has identified that the manifest file declares `MANAGE_EXTERNAL_STORAGE` permission. {{ output.txt }} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif index 7ed88f3db8..487c15b97a 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif @@ -11,23 +11,23 @@ "results": [ { "fingerprints": { - "matchBasedId/v1": "6aa4b8588a882dd4bcdb3d056b354663e9b7d6df919b1b9b26fd7f39f23b73467dd1a055148a14b9544c442214fcbb672a91534d0d59aa9d0ee720f2e2e668f4_0" + "matchBasedId/v1": "2b2ee4534454b35a0c8626a956eaf30a07b616097ca262d4f67128446dfb9fd17683ce8480f92ec0ebb0aa0830bcd81c298817c107317b8482db1e7f5c49629d_0" }, "locations": [ { "physicalLocation": { "artifactLocation": { - "uri": "AndroidManifest.xml", + "uri": "AndroidManifest_reversed.xml", "uriBaseId": "%SRCROOT%" }, "region": { - "endColumn": 77, - "endLine": 5, + "endColumn": 78, + "endLine": 2, "snippet": { - "text": " " + "text": " " }, "startColumn": 55, - "startLine": 5 + "startLine": 2 } } } @@ -69,20 +69,20 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + "markdown": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary", + "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" }, - "id": "rules.mastg-android-data-unencrypted-external-api", - "name": "rules.mastg-android-data-unencrypted-external-api", + "id": "rules.mastg-android-data-unencrypted-external-manifest", + "name": "rules.mastg-android-data-unencrypted-external-manifest", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-api" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-manifest" } }, { @@ -90,20 +90,20 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary", - "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" }, - "id": "rules.mastg-android-data-unencrypted-external-manifest", - "name": "rules.mastg-android-data-unencrypted-external-manifest", + "id": "rules.mastg-android-data-unencrypted-external-api", + "name": "rules.mastg-android-data-unencrypted-external-api", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-manifest" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-api" } } ], diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt index 34c6a72b0f..d4a1cf42a0 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt @@ -3,9 +3,9 @@ ┌────────────────┐ │ 1 Code Finding │ └────────────────┘ - - AndroidManifest.xml + + AndroidManifest_reversed.xml ❯❱ rules.mastg-android-data-unencrypted-external-manifest [MASVS-STORAGE] Make sure to encrypt files in external storage if necessary - 5┆ + 2┆ diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md index c34e3deb33..fc2ba3f960 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md @@ -13,7 +13,7 @@ code: [kotlin] Let's run our semgrep rule against the sample code. -{{ ../rules/mastg-android-data-unencrypted-external.yml }} +{{ ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml }} {{ run.sh }} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-external.yml b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-external.yml rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml From 5e5c8dcfeb1cdebef46461f586d3419911a56300 Mon Sep 17 00:00:00 2001 From: Jan Seredynski Date: Tue, 4 Jun 2024 13:16:17 +0200 Subject: [PATCH 11/33] Mention iOS in Risks --- .../risk.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/risk.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/risk.md index 07ed81a678..b940d4c844 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/risk.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/risk.md @@ -12,9 +12,9 @@ mappings: ## Overview -Apps frequently opt to store data in the external storage due to its larger capacity and the ability to share files with other apps. However, this convenience comes with a potential drawback. Data stored on external devices like SD cards can be accessed not only by other apps on the device, given the right permissions, but also if the external storage is physically removed. This means that files meant to be private might unintentionally become public. Even if the external storage is emulated by the system, the risk arises from improper file permissions or the misuse of APIs for saving files. In such cases, files become vulnerable to unauthorized modifications and deletions, posing a security threat to the application. +Apps frequently opt to store data in the external storage due to its larger capacity. However, this convenience comes with a potential security drawback. Once a malicious app is granted the relevant permissions, it can access this data without user consent or interaction at any time. Additionally, external storage like SD cards can be physically removed and read by a malicious actor. Even if the external storage is emulated by the system, the risk arises from improper file permissions or the misuse of APIs for saving files. In such cases, the files become vulnerable to unauthorized access, modifications and deletions, posing a security threat to the application. -Developers may consider switching to the internal storage if they need more privacy and security. However, if the external storage is the most suitable for the app, it's a good practise to encrypt data stored in the external storage. Below you can find potential security impacts and mitigations linked to the use of the external storage. +Developers may consider switching to Private Storage or Shared Storage Requiring User Interaction if they need more privacy and security. However, if the external storage is the most suitable for the app, it's a good practise to encrypt data stored in the external storage. Below you can find potential security impacts and mitigations linked to the use of the external storage. ## Impact @@ -38,6 +38,7 @@ This threat is primarily a concern for Android devices since they permit the use - **Encryption Used is Insufficient**: Sensitive data is encrypted but the encryption is not considered to be strong. - **Reuse of encryption key**: The encryption key is shared between two devices owned by a single user, enabling the process of data cloning between these devices in the external storage. +On iOS, apps cannot directly write to or read from the arbitrary locations, as compared to desktop operating system or Android. iOS maintains strict sandboxing rules, meaning apps can only access their own sandboxed file directories. ## Mitigations From ac00a3639e852aa78cec7860d90a4b50be8cbde9 Mon Sep 17 00:00:00 2001 From: Jan Seredynski Date: Tue, 4 Jun 2024 13:17:01 +0200 Subject: [PATCH 12/33] Update Demos with the MASTestApp --- .../demo-1/MastgTest.kt | 31 ++++ .../demo-1/output.txt | 82 ++++++++-- .../demo-1/run.sh | 2 +- .../demo-1/snippet.kt | 22 --- .../demo-1/MastgTest.kt | 39 +++++ .../demo-1/MastgTest_reversed.java | 46 ++++++ .../demo-1/demo.md | 4 +- .../demo-1/output.sarif | 81 +++++++--- .../demo-1/output.txt | 24 +-- .../demo-1/run.sh | 4 +- .../demo-1/use-of-external-store.kt | 35 ---- .../demo-2/demo.md | 2 +- .../demo-2/output.sarif | 42 ++--- .../demo-2/output.txt | 2 +- .../demo-2/run.sh | 4 +- .../demo-3/MastgTest.kt | 39 +++++ .../demo-3/MastgTest_reversed.java | 59 +++++++ .../demo-3/demo.md | 4 +- .../demo-3/output.sarif | 153 ++++-------------- .../demo-3/output.txt | 18 +-- .../demo-3/run.sh | 4 +- .../demo-3/use-of-mediastore.kt | 23 --- ...ted-shared-storage-no-user-interaction.yml | 10 +- 23 files changed, 427 insertions(+), 303 deletions(-) create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/MastgTest.kt delete mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/snippet.kt create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest.kt create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest_reversed.java delete mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/use-of-external-store.kt create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest.kt create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest_reversed.java delete mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/use-of-mediastore.kt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/MastgTest.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/MastgTest.kt new file mode 100644 index 0000000000..a210d84420 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/MastgTest.kt @@ -0,0 +1,31 @@ +package org.owasp.mastestapp + +import android.content.Context +import android.os.Environment +import android.util.Log +import java.io.File +import java.io.FileOutputStream +import java.io.IOException + +class MastgTest (private val context: Context){ + + fun mastgTest(): String { + + val externalStorageDir = Environment.getExternalStorageDirectory() + + val fileName = File(externalStorageDir, "secret.txt") + val fileContent = "Secret not using scoped storage" + + try { + FileOutputStream(fileName).use { output -> + output.write(fileContent.toByteArray()) + Log.d("WriteExternalStorage", "File written to external storage successfully.") + } + } catch (e: IOException) { + Log.e("WriteExternalStorage", "Error writing file to external storage", e) + return "ERROR!!\n\nError writing file to external storage. Do you have the MANAGE_EXTERNAL_STORAGE permission in the manifest and it's granted in 'All files access'?" + } + + return "SUCCESS!!\n\nFile $fileName with content $fileContent saved to $externalStorageDir" + } +} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/output.txt index a6961ee103..1a04f14a14 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/output.txt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/output.txt @@ -1,27 +1,75 @@ -[WARNING] Opening a file from external storage at: /storage/emulated/0/Android/data/com.gs.owasp_storage_app1/files/secret.json +[WARNING] Opening a file from external storage at: /storage/emulated/0/secret.txt Invoked from: java.lang.Exception at libcore.io.Linux.open(Native Method) at libcore.io.ForwardingOs.open(ForwardingOs.java:167) at libcore.io.BlockGuardOs.open(BlockGuardOs.java:252) at libcore.io.ForwardingOs.open(ForwardingOs.java:167) - at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7581) + at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7255) at libcore.io.IoBridge.open(IoBridge.java:482) at java.io.FileOutputStream.(FileOutputStream.java:235) at java.io.FileOutputStream.(FileOutputStream.java:186) - at com.gs.owasp_storage_app1.MainActivity.runOwasp(MainActivity.kt:155) - at com.gs.owasp_storage_app1.MainActivity.onCreate$lambda$1(MainActivity.kt:36) - at com.gs.owasp_storage_app1.MainActivity.$r8$lambda$He9NTWO6dCDqltooAd5-9ovuSZ8(Unknown Source:0) - at com.gs.owasp_storage_app1.MainActivity$$ExternalSyntheticLambda1.onClick(Unknown Source:2) - at android.view.View.performClick(View.java:7201) - at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1218) - at android.view.View.performClickInternal(View.java:7170) - at android.view.View.access$3500(View.java:806) - at android.view.View$PerformClick.run(View.java:27562) - at android.os.Handler.handleCallback(Handler.java:883) - at android.os.Handler.dispatchMessage(Handler.java:100) - at android.os.Looper.loop(Looper.java:214) - at android.app.ActivityThread.main(ActivityThread.java:7682) + at org.owasp.mastestapp.MastgTest.mastgTest(MastgTest.kt:20) + at org.owasp.mastestapp.MainActivityKt$MyScreenContent$1$1$1.invoke(MainActivity.kt:73) + at org.owasp.mastestapp.MainActivityKt$MyScreenContent$1$1$1.invoke(MainActivity.kt:71) + at androidx.compose.foundation.ClickablePointerInputNode$pointerInput$3.invoke-k-4lQ0M(Clickable.kt:987) + at androidx.compose.foundation.ClickablePointerInputNode$pointerInput$3.invoke(Clickable.kt:981) + at androidx.compose.foundation.gestures.TapGestureDetectorKt$detectTapAndPress$2$1.invokeSuspend(TapGestureDetector.kt:255) + at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) + at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:177) + at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:166) + at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:474) + at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:508) + at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:497) + at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.kt:368) + at androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNodeImpl$PointerEventHandlerCoroutine.offerPointerEvent(SuspendingPointerInputFilter.kt:665) + at androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNodeImpl.dispatchPointerEvent(SuspendingPointerInputFilter.kt:544) + at androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNodeImpl.onPointerEvent-H0pRuoY(SuspendingPointerInputFilter.kt:566) + at androidx.compose.foundation.AbstractClickablePointerInputNode.onPointerEvent-H0pRuoY(Clickable.kt:947) + at androidx.compose.foundation.AbstractClickableNode.onPointerEvent-H0pRuoY(Clickable.kt:795) + at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:317) + at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:303) + at androidx.compose.ui.input.pointer.NodeParent.dispatchMainEventPass(HitPathTracker.kt:185) + at androidx.compose.ui.input.pointer.HitPathTracker.dispatchChanges(HitPathTracker.kt:104) + at androidx.compose.ui.input.pointer.PointerInputEventProcessor.process-BIzXfog(PointerInputEventProcessor.kt:113) + at androidx.compose.ui.platform.AndroidComposeView.sendMotionEvent-8iAsVTc(AndroidComposeView.android.kt:1576) + at androidx.compose.ui.platform.AndroidComposeView.handleMotionEvent-8iAsVTc(AndroidComposeView.android.kt:1527) + at androidx.compose.ui.platform.AndroidComposeView.dispatchTouchEvent(AndroidComposeView.android.kt:1466) + at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3060) + at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2755) + at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3060) + at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2755) + at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3060) + at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2755) + at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3060) + at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2755) + at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:465) + at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1849) + at android.app.Activity.dispatchTouchEvent(Activity.java:3993) + at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:423) + at android.view.View.dispatchPointerEvent(View.java:13674) + at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5482) + at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5285) + at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4788) + at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4841) + at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4807) + at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4947) + at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4815) + at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:5004) + at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4788) + at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4841) + at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4807) + at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4815) + at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4788) + at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:7505) + at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:7474) + at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7435) + at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7630) + at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:188) + at android.os.MessageQueue.nativePollOnce(Native Method) + at android.os.MessageQueue.next(MessageQueue.java:336) + at android.os.Looper.loop(Looper.java:174) + at android.app.ActivityThread.main(ActivityThread.java:7356) at java.lang.reflect.Method.invoke(Native Method) - at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516) - at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950) + at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) + at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/run.sh index f8fa2db63a..aaa0e8bc32 100755 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/run.sh +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/run.sh @@ -8,6 +8,6 @@ frida \ -U \ - -f com.gs.owasp_storage_app2 \ + -f org.owasp.mastestapp \ -l script.js \ -o output.txt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/snippet.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/snippet.kt deleted file mode 100644 index 7e39ac520b..0000000000 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/snippet.kt +++ /dev/null @@ -1,22 +0,0 @@ -package org.owasp.mastestapp - -import android.content.Context -import android.os.Environment -import android.os.Environment.getExternalStoragePublicDirectory -import java.io.File -import java.io.FileOutputStream - -class MastgTest (private val context: Context){ - - fun mastgTest(): String { - val secret1 = "{\"password\":\"12345\"}\n" - val externalDirPath = getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) - val file1 = File("$externalDirPath/secrets.json") - FileOutputStream(file1).use { fos -> - fos.write(secret1.toByteArray()) - } - - return "Secrets written to $file1:\n\n$secret1" - } - -} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest.kt new file mode 100644 index 0000000000..07d1137fb8 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest.kt @@ -0,0 +1,39 @@ +package org.owasp.mastestapp + +import android.content.ContentValues +import android.util.Log +import android.content.Context +import android.os.Environment +import android.provider.MediaStore +import java.io.OutputStream + +class MastgTest (private val context: Context){ + + fun mastgTest(): String { + try { + val resolver = context.contentResolver + val contentValues = ContentValues().apply { + put(MediaStore.MediaColumns.DISPLAY_NAME, "secretFile.txt") + put(MediaStore.MediaColumns.MIME_TYPE, "text/plain") + put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS) + } + val textUri = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues) + + textUri?.let { + val outputStream: OutputStream? = resolver.openOutputStream(it) + outputStream?.use { + it.write("Secret data".toByteArray()) + it.flush() + } + Log.d("MediaStore", "File written to external storage successfully.") + return "SUCCESS!!\n\nMediaStore inserted to $textUri" + } ?: run { + Log.e("MediaStore", "Error inserting URI to MediaStore.") + return "FAILURE!!\n\nMediaStore couldn't insert data." + } + } catch (exception: Exception) { + Log.e("MediaStore", "Error writing file to URI from MediaStore", exception) + return "FAILURE!!\n\nMediaStore couldn't insert data." + } + } +} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest_reversed.java b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest_reversed.java new file mode 100644 index 0000000000..20e9290d9a --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest_reversed.java @@ -0,0 +1,46 @@ +package org.owasp.mastestapp; + +import android.content.Context; +import android.os.Environment; +import android.util.Log; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import kotlin.Metadata; +import kotlin.io.CloseableKt; +import kotlin.jvm.internal.Intrinsics; +import kotlin.text.Charsets; + +/* compiled from: MastgTest.kt */ +@Metadata(d1 = {"\u0000\u0018\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0000\b\u0007\u0018\u00002\u00020\u0001B\r\u0012\u0006\u0010\u0002\u001a\u00020\u0003¢\u0006\u0002\u0010\u0004J\u0006\u0010\u0005\u001a\u00020\u0006R\u000e\u0010\u0002\u001a\u00020\u0003X\u0082\u0004¢\u0006\u0002\n\u0000¨\u0006\u0007"}, d2 = {"Lorg/owasp/mastestapp/MastgTest;", "", "context", "Landroid/content/Context;", "(Landroid/content/Context;)V", "mastgTest", "", "app_debug"}, k = 1, mv = {1, 9, 0}, xi = 48) +/* loaded from: classes4.dex */ +public final class MastgTest { + public static final int $stable = 8; + private final Context context; + + public MastgTest(Context context) { + Intrinsics.checkNotNullParameter(context, "context"); + this.context = context; + } + + public final String mastgTest() { + File externalStorageDir = Environment.getExternalStorageDirectory(); + File fileName = new File(externalStorageDir, "secret.txt"); + try { + FileOutputStream fileOutputStream = new FileOutputStream(fileName); + try { + FileOutputStream output = fileOutputStream; + byte[] bytes = "Secret not using scoped storage".getBytes(Charsets.UTF_8); + Intrinsics.checkNotNullExpressionValue(bytes, "this as java.lang.String).getBytes(charset)"); + output.write(bytes); + Log.d("WriteExternalStorage", "File written to external storage successfully."); + CloseableKt.closeFinally(fileOutputStream, null); + return "File " + fileName + " with content Secret not using scoped storage saved to " + externalStorageDir; + } finally { + } + } catch (IOException e) { + Log.e("WriteExternalStorage", "Error writing file to external storage", e); + return "Error writing file to external storage. Do you have the MANAGE_EXTERNAL_STORAGE permission in the manifest and it's granted?"; + } + } +} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md index 1f1c850421..6358b27609 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md @@ -7,11 +7,11 @@ code: [kotlin] ### Demo -{{ use-of-external-store.kt }} +{{ MastgTest.kt }} ### Steps -Let's run our semgrep rule against the sample code. +Let's run our semgrep rule against the reversed java code. {{ ../rules/mastg-android-data-unencrypted-external.yml }} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif index 9356e15fb3..8f7b939cb9 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif @@ -11,23 +11,23 @@ "results": [ { "fingerprints": { - "matchBasedId/v1": "86181ae035702aa50a67f6c5fcae0e9cd18f97887aa9e1ffcb70225f86d21062067e3925de964b722f4593b60fd959f1b9b0778f189a7183e0609be44faea0c5_0" + "matchBasedId/v1": "e1a40a9ec09f82c43cc5a422b90cb75783cb8a85bce0b16f5c908d5af667c2c0de7c720e7e480b6b09b8bb7ae7203deea639a4e5f2a7581e51461e08b414320b_0" }, "locations": [ { "physicalLocation": { "artifactLocation": { - "uri": "use-of-external-store.kt", + "uri": "MastgTest_reversed.java", "uriBaseId": "%SRCROOT%" }, "region": { - "endColumn": 101, - "endLine": 26, + "endColumn": 76, + "endLine": 27, "snippet": { - "text": " val externalDirPath = getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)" + "text": " File externalStorageDir = Environment.getExternalStorageDirectory();" }, "startColumn": 35, - "startLine": 26 + "startLine": 27 } } } @@ -36,7 +36,36 @@ "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" }, "properties": {}, - "ruleId": "rules.mastg-android-data-unencrypted-external-api" + "ruleId": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api" + }, + { + "fingerprints": { + "matchBasedId/v1": "01f2f74dc636d3094cd1abf9dbe8ebc57a4cd0a35a2cd5c851659dcd3c0693019211e4dcf3d8803b1a9a99dcf44401fdc9a739b10960c965f0262d2495ba5b1f_0" + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "MastgTest_reversed.java", + "uriBaseId": "%SRCROOT%" + }, + "region": { + "endColumn": 100, + "endLine": 43, + "snippet": { + "text": " return \"Error writing file to external storage. Do you have the MANAGE_EXTERNAL_STORAGE permission in the manifest and it's granted?\";" + }, + "startColumn": 77, + "startLine": 43 + } + } + } + ], + "message": { + "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + }, + "properties": {}, + "ruleId": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest" } ], "tool": { @@ -48,20 +77,20 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary", - "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" }, - "id": "rules.mastg-android-data-unencrypted-external-manifest", - "name": "rules.mastg-android-data-unencrypted-external-manifest", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-manifest" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" } }, { @@ -69,20 +98,20 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + "markdown": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary", + "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" }, - "id": "rules.mastg-android-data-unencrypted-external-api", - "name": "rules.mastg-android-data-unencrypted-external-api", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-api" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest" } }, { @@ -90,20 +119,20 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" }, - "id": "rules.mastg-android-data-unencrypted-external-mediastore", - "name": "rules.mastg-android-data-unencrypted-external-mediastore", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-mediastore" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api" } } ], @@ -113,4 +142,4 @@ } ], "version": "2.1.0" -} +} \ No newline at end of file diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.txt index 3cb80821b6..3f5b59b43a 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.txt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.txt @@ -1,11 +1,17 @@ - - -┌────────────────┐ -│ 1 Code Finding │ -└────────────────┘ - - use-of-external-store.kt - ❯❱ rules.mastg-android-data-unencrypted-external-api + + +┌─────────────────┐ +│ 2 Code Findings │ +└─────────────────┘ + + MastgTest_reversed.java + ❯❱ rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api [MASVS-STORAGE] Make sure to encrypt files at these locations if necessary - 26┆ val externalDirPath = getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + 27┆ File externalStorageDir = Environment.getExternalStorageDirectory(); + + ❯❱ rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest + [MASVS-STORAGE] Make sure to encrypt files in external storage if necessary + + 43┆ return "Error writing file to external storage. Do you have the MANAGE_EXTERNAL_STORAGE + permission in the manifest and it's granted?"; diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh index 5336943a7e..a0886a14ee 100755 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh @@ -1,2 +1,2 @@ -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external.yml ./MastgTest_reversed.java --text -o output.txt -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external.yml ./MastgTest_reversed.java --sarif -o output.sarif +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml ./MastgTest_reversed.java --text -o output.txt +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml ./MastgTest_reversed.java --sarif -o output.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/use-of-external-store.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/use-of-external-store.kt deleted file mode 100644 index fe01e440c1..0000000000 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/use-of-external-store.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.example - -import android.content.Intent -import android.os.Bundle -import android.os.Environment -import android.os.Environment.getDownloadCacheDirectory -import android.os.Environment.getExternalStorageDirectory -import android.os.Environment.getExternalStoragePublicDirectory -import android.view.View -import android.widget.Button -import androidx.appcompat.app.AppCompatActivity -import java.io.File -import java.io.FileOutputStream -import java.io.IOException - -class MainActivity : AppCompatActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - setContentView(R.layout.activity_main) - saveDatabase() - } - - fun saveDatabase(){ - try { - val externalDirPath = getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) - val file: File = File("$externalDirPath/download.json") - FileOutputStream(file).use { fos -> - fos.write("password:12345".toByteArray()) - } - } catch (e: IOException) { - e.printStackTrace() - } - } -} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md index 35cce25088..867e13b53b 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md @@ -7,7 +7,7 @@ code: [xml] ### Demo -{{ AndroidManifest_reversed.xml }} +{{ AndroidManifest.xml }} ### Steps diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif index 487c15b97a..7801a5662d 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif @@ -11,7 +11,7 @@ "results": [ { "fingerprints": { - "matchBasedId/v1": "2b2ee4534454b35a0c8626a956eaf30a07b616097ca262d4f67128446dfb9fd17683ce8480f92ec0ebb0aa0830bcd81c298817c107317b8482db1e7f5c49629d_0" + "matchBasedId/v1": "4f4da620f6961a9f5dc3861a6ead2be3dac9f043e8beff0c84200108663f19c8083459d308024a924a78f3301bb886eaac9699eee70be6a890110bca7aec4267_0" }, "locations": [ { @@ -36,7 +36,7 @@ "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" }, "properties": {}, - "ruleId": "rules.mastg-android-data-unencrypted-external-manifest" + "ruleId": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest" } ], "tool": { @@ -48,20 +48,20 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" }, - "id": "rules.mastg-android-data-unencrypted-external-mediastore", - "name": "rules.mastg-android-data-unencrypted-external-mediastore", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-mediastore" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api" } }, { @@ -69,20 +69,20 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary", - "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" }, - "id": "rules.mastg-android-data-unencrypted-external-manifest", - "name": "rules.mastg-android-data-unencrypted-external-manifest", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-manifest" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" } }, { @@ -90,20 +90,20 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + "markdown": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary", + "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" }, - "id": "rules.mastg-android-data-unencrypted-external-api", - "name": "rules.mastg-android-data-unencrypted-external-api", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-api" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest" } } ], @@ -113,4 +113,4 @@ } ], "version": "2.1.0" -} +} \ No newline at end of file diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt index d4a1cf42a0..ed9143c160 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt @@ -5,7 +5,7 @@ └────────────────┘ AndroidManifest_reversed.xml - ❯❱ rules.mastg-android-data-unencrypted-external-manifest + ❯❱ rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest [MASVS-STORAGE] Make sure to encrypt files in external storage if necessary 2┆ diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh index aaf1e2c714..3d4a4d5b0e 100755 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh @@ -1,2 +1,2 @@ -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external.yml ./AndroidManifest_reversed.xml --text -o output.txt -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external.yml ./AndroidManifest_reversed.xml --sarif -o output.sarif +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml ./AndroidManifest_reversed.xml --text -o output.txt +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml ./AndroidManifest_reversed.xml --sarif -o output.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest.kt new file mode 100644 index 0000000000..07d1137fb8 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest.kt @@ -0,0 +1,39 @@ +package org.owasp.mastestapp + +import android.content.ContentValues +import android.util.Log +import android.content.Context +import android.os.Environment +import android.provider.MediaStore +import java.io.OutputStream + +class MastgTest (private val context: Context){ + + fun mastgTest(): String { + try { + val resolver = context.contentResolver + val contentValues = ContentValues().apply { + put(MediaStore.MediaColumns.DISPLAY_NAME, "secretFile.txt") + put(MediaStore.MediaColumns.MIME_TYPE, "text/plain") + put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS) + } + val textUri = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues) + + textUri?.let { + val outputStream: OutputStream? = resolver.openOutputStream(it) + outputStream?.use { + it.write("Secret data".toByteArray()) + it.flush() + } + Log.d("MediaStore", "File written to external storage successfully.") + return "SUCCESS!!\n\nMediaStore inserted to $textUri" + } ?: run { + Log.e("MediaStore", "Error inserting URI to MediaStore.") + return "FAILURE!!\n\nMediaStore couldn't insert data." + } + } catch (exception: Exception) { + Log.e("MediaStore", "Error writing file to URI from MediaStore", exception) + return "FAILURE!!\n\nMediaStore couldn't insert data." + } + } +} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest_reversed.java b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest_reversed.java new file mode 100644 index 0000000000..759d77f6e2 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest_reversed.java @@ -0,0 +1,59 @@ +package org.owasp.mastestapp; + +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.net.Uri; +import android.os.Environment; +import android.provider.MediaStore; +import android.util.Log; +import java.io.OutputStream; +import kotlin.Metadata; +import kotlin.Unit; +import kotlin.io.CloseableKt; +import kotlin.jvm.internal.Intrinsics; +import kotlin.text.Charsets; +/* compiled from: MastgTest.kt */ +@Metadata(d1 = {"\u0000\u0018\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0000\b\u0007\u0018\u00002\u00020\u0001B\r\u0012\u0006\u0010\u0002\u001a\u00020\u0003¢\u0006\u0002\u0010\u0004J\u0006\u0010\u0005\u001a\u00020\u0006R\u000e\u0010\u0002\u001a\u00020\u0003X\u0082\u0004¢\u0006\u0002\n\u0000¨\u0006\u0007"}, d2 = {"Lorg/owasp/mastestapp/MastgTest;", "", "context", "Landroid/content/Context;", "(Landroid/content/Context;)V", "mastgTest", "", "app_debug"}, k = 1, mv = {1, 9, 0}, xi = 48) +/* loaded from: classes4.dex */ +public final class MastgTest { + public static final int $stable = 8; + private final Context context; + + public MastgTest(Context context) { + Intrinsics.checkNotNullParameter(context, "context"); + this.context = context; + } + + public final String mastgTest() { + try { + ContentResolver resolver = this.context.getContentResolver(); + ContentValues contentValues = new ContentValues(); + contentValues.put("_display_name", "secretFile.txt"); + contentValues.put("mime_type", "text/plain"); + contentValues.put("relative_path", Environment.DIRECTORY_DOCUMENTS); + Uri textUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues); + if (textUri != null) { + OutputStream outputStream = resolver.openOutputStream(textUri); + if (outputStream != null) { + OutputStream outputStream2 = outputStream; + OutputStream it = outputStream2; + byte[] bytes = "Secret data".getBytes(Charsets.UTF_8); + Intrinsics.checkNotNullExpressionValue(bytes, "this as java.lang.String).getBytes(charset)"); + it.write(bytes); + it.flush(); + Unit unit = Unit.INSTANCE; + CloseableKt.closeFinally(outputStream2, null); + } + Log.d("MediaStore", "File written to external storage successfully."); + return "SUCCESS!!\n\nMediaStore inserted to " + textUri; + } + MastgTest mastgTest = this; + Log.e("MediaStore", "Error inserting URI to MediaStore."); + return "FAILURE!!\n\nMediaStore couldn't insert data."; + } catch (Exception exception) { + Log.e("MediaStore", "Error writing file to URI from MediaStore", exception); + return "FAILURE!!\n\nMediaStore couldn't insert data."; + } + } +} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md index fc2ba3f960..7c6627100c 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md @@ -7,7 +7,7 @@ code: [kotlin] ### Demo -{{ use-of-mediastore.kt }} +{{ MastgTest.kt }} ### Steps @@ -19,7 +19,7 @@ Let's run our semgrep rule against the sample code. ### Observation -The rule has identified 5 locations in the code which refer to the same MediaStore use. +The rule has identified 2 locations that indicate a use of MediaStore API. {{ output.txt }} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.sarif index f4f8e87c67..f029710522 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.sarif +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.sarif @@ -11,23 +11,23 @@ "results": [ { "fingerprints": { - "matchBasedId/v1": "0863f3399c1ce2db808b0bc40f299ca16c02e7f2b20f894ae803e49e33a42c820871071aa041eef8f313ea699424e8ca6670bfa8df2baf9c7a1b731c2b283271_0" + "matchBasedId/v1": "c36527e4d1432461d345286b77b11e18d4bc76ece67d3e5392ab76eb4976bab00649247144e1944dae61e29e3582016beff405e036a93eb2201c817f616b0693_0" }, "locations": [ { "physicalLocation": { "artifactLocation": { - "uri": "use-of-mediastore.kt", + "uri": "MastgTest_reversed.java", "uriBaseId": "%SRCROOT%" }, "region": { "endColumn": 35, - "endLine": 4, + "endLine": 8, "snippet": { - "text": "import android.provider.MediaStore" + "text": "import android.provider.MediaStore;" }, - "startColumn": 25, - "startLine": 4 + "startColumn": 1, + "startLine": 8 } } } @@ -36,27 +36,27 @@ "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" }, "properties": {}, - "ruleId": "rules.mastg-android-data-unencrypted-external-mediastore" + "ruleId": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" }, { "fingerprints": { - "matchBasedId/v1": "0863f3399c1ce2db808b0bc40f299ca16c02e7f2b20f894ae803e49e33a42c820871071aa041eef8f313ea699424e8ca6670bfa8df2baf9c7a1b731c2b283271_1" + "matchBasedId/v1": "b1be13cd80a4d0596fe97464b74b86cac6feaf5f27d3a7a077ec36ba3faf862f95d0b1d7f41c5c67693c97d1dfb0c25cec088009dc5513b07af76f0fec1b1c1d_0" }, "locations": [ { "physicalLocation": { "artifactLocation": { - "uri": "use-of-mediastore.kt", + "uri": "MastgTest_reversed.java", "uriBaseId": "%SRCROOT%" }, "region": { - "endColumn": 41, - "endLine": 13, + "endColumn": 53, + "endLine": 35, "snippet": { - "text": " contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, \"sampleName\")" + "text": " Uri textUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);" }, - "startColumn": 31, - "startLine": 13 + "startColumn": 43, + "startLine": 35 } } } @@ -65,94 +65,7 @@ "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" }, "properties": {}, - "ruleId": "rules.mastg-android-data-unencrypted-external-mediastore" - }, - { - "fingerprints": { - "matchBasedId/v1": "0863f3399c1ce2db808b0bc40f299ca16c02e7f2b20f894ae803e49e33a42c820871071aa041eef8f313ea699424e8ca6670bfa8df2baf9c7a1b731c2b283271_2" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "use-of-mediastore.kt", - "uriBaseId": "%SRCROOT%" - }, - "region": { - "endColumn": 41, - "endLine": 14, - "snippet": { - "text": " contentValues.put(MediaStore.MediaColumns.MIME_TYPE, \"image/jpg\")" - }, - "startColumn": 31, - "startLine": 14 - } - } - } - ], - "message": { - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" - }, - "properties": {}, - "ruleId": "rules.mastg-android-data-unencrypted-external-mediastore" - }, - { - "fingerprints": { - "matchBasedId/v1": "0863f3399c1ce2db808b0bc40f299ca16c02e7f2b20f894ae803e49e33a42c820871071aa041eef8f313ea699424e8ca6670bfa8df2baf9c7a1b731c2b283271_3" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "use-of-mediastore.kt", - "uriBaseId": "%SRCROOT%" - }, - "region": { - "endColumn": 41, - "endLine": 15, - "snippet": { - "text": " contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)" - }, - "startColumn": 31, - "startLine": 15 - } - } - } - ], - "message": { - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" - }, - "properties": {}, - "ruleId": "rules.mastg-android-data-unencrypted-external-mediastore" - }, - { - "fingerprints": { - "matchBasedId/v1": "0863f3399c1ce2db808b0bc40f299ca16c02e7f2b20f894ae803e49e33a42c820871071aa041eef8f313ea699424e8ca6670bfa8df2baf9c7a1b731c2b283271_4" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "use-of-mediastore.kt", - "uriBaseId": "%SRCROOT%" - }, - "region": { - "endColumn": 43, - "endLine": 17, - "snippet": { - "text": " resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)" - }, - "startColumn": 33, - "startLine": 17 - } - } - } - ], - "message": { - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" - }, - "properties": {}, - "ruleId": "rules.mastg-android-data-unencrypted-external-mediastore" + "ruleId": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" } ], "tool": { @@ -164,20 +77,20 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" }, - "id": "rules.mastg-android-data-unencrypted-external-api", - "name": "rules.mastg-android-data-unencrypted-external-api", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-api" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" } }, { @@ -185,20 +98,20 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + "markdown": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary", + "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" }, - "id": "rules.mastg-android-data-unencrypted-external-mediastore", - "name": "rules.mastg-android-data-unencrypted-external-mediastore", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-mediastore" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest" } }, { @@ -206,20 +119,20 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary", - "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" }, - "id": "rules.mastg-android-data-unencrypted-external-manifest", - "name": "rules.mastg-android-data-unencrypted-external-manifest", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-external-manifest" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api" } } ], diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.txt index 9926981295..41192fc7b4 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.txt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.txt @@ -1,19 +1,13 @@ ┌─────────────────┐ -│ 5 Code Findings │ +│ 2 Code Findings │ └─────────────────┘ - - use-of-mediastore.kt - ❯❱ rules.mastg-android-data-unencrypted-external-mediastore + + MastgTest_reversed.java + ❯❱ rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore [MASVS-STORAGE] Make sure to want this data to be shared with other apps - 4┆ import android.provider.MediaStore + 8┆ import android.provider.MediaStore; ⋮┆---------------------------------------- - 13┆ contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, "sampleName") - ⋮┆---------------------------------------- - 14┆ contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg") - ⋮┆---------------------------------------- - 15┆ contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES) - ⋮┆---------------------------------------- - 17┆ resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues) + 35┆ Uri textUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues); diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/run.sh index a9fa816c58..a0886a14ee 100755 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/run.sh +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/run.sh @@ -1,2 +1,2 @@ -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external.yml ./use-of-mediastore.kt --text -o output.txt -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-external.yml ./use-of-mediastore.kt --sarif -o output.sarif +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml ./MastgTest_reversed.java --text -o output.txt +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml ./MastgTest_reversed.java --sarif -o output.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/use-of-mediastore.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/use-of-mediastore.kt deleted file mode 100644 index 71ffbd9bb9..0000000000 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/use-of-mediastore.kt +++ /dev/null @@ -1,23 +0,0 @@ -import android.content.ContentValues -import android.content.Context -import android.os.Environment -import android.provider.MediaStore -import android.widget.Toast - -class ImageController { - - fun saveImageToMediaStore(context: Context) { - try { - val resolver = context.contentResolver - val contentValues = ContentValues() - contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, "sampleName") - contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg") - contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES) - val imageUri = - resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues) - /// ... - } catch (exception: Exception) { - Toast.makeText(context, exception.toString(), Toast.LENGTH_SHORT).show() - } - } -} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml index f6b3db4915..11400d77f1 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml @@ -1,5 +1,5 @@ rules: - - id: mastg-android-data-unencrypted-external-api + - id: mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api severity: WARNING languages: - java @@ -16,7 +16,7 @@ rules: - pattern: $X.getExternalMediaDirs(...) - pattern: $X.getDownloadCacheDirectory(...) - pattern: Intent.ACTION_CREATE_DOCUMENT - - id: mastg-android-data-unencrypted-external-manifest + - id: mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest severity: WARNING languages: - generic @@ -30,7 +30,7 @@ rules: - pattern: requestLegacyExternalStorage="true" - pattern: preserveLegacyExternalStorage="true" - pattern: android:requestRawExternalStorageAccess="true" - - id: mastg-android-data-unencrypted-external-mediastore + - id: mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore severity: WARNING languages: - java @@ -38,5 +38,5 @@ rules: summary: This rule scans for uses of MediaStore API that writes data to the external storage. This data can be accessed by other apps. message: "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" pattern-either: - - pattern: MediaStore - + - pattern: import android.provider.MediaStore + - pattern: $X.MediaStore From 44b625b8f042f159f67654be5278eeb4e16a9a33 Mon Sep 17 00:00:00 2001 From: Jan Seredynski Date: Tue, 4 Jun 2024 13:18:34 +0200 Subject: [PATCH 13/33] Update demo-1 --- .../demo-1/MastgTest.kt | 44 ++++++++----------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest.kt index 07d1137fb8..a210d84420 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest.kt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest.kt @@ -1,39 +1,31 @@ package org.owasp.mastestapp -import android.content.ContentValues -import android.util.Log import android.content.Context import android.os.Environment -import android.provider.MediaStore -import java.io.OutputStream +import android.util.Log +import java.io.File +import java.io.FileOutputStream +import java.io.IOException class MastgTest (private val context: Context){ fun mastgTest(): String { - try { - val resolver = context.contentResolver - val contentValues = ContentValues().apply { - put(MediaStore.MediaColumns.DISPLAY_NAME, "secretFile.txt") - put(MediaStore.MediaColumns.MIME_TYPE, "text/plain") - put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS) - } - val textUri = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues) - textUri?.let { - val outputStream: OutputStream? = resolver.openOutputStream(it) - outputStream?.use { - it.write("Secret data".toByteArray()) - it.flush() - } - Log.d("MediaStore", "File written to external storage successfully.") - return "SUCCESS!!\n\nMediaStore inserted to $textUri" - } ?: run { - Log.e("MediaStore", "Error inserting URI to MediaStore.") - return "FAILURE!!\n\nMediaStore couldn't insert data." + val externalStorageDir = Environment.getExternalStorageDirectory() + + val fileName = File(externalStorageDir, "secret.txt") + val fileContent = "Secret not using scoped storage" + + try { + FileOutputStream(fileName).use { output -> + output.write(fileContent.toByteArray()) + Log.d("WriteExternalStorage", "File written to external storage successfully.") } - } catch (exception: Exception) { - Log.e("MediaStore", "Error writing file to URI from MediaStore", exception) - return "FAILURE!!\n\nMediaStore couldn't insert data." + } catch (e: IOException) { + Log.e("WriteExternalStorage", "Error writing file to external storage", e) + return "ERROR!!\n\nError writing file to external storage. Do you have the MANAGE_EXTERNAL_STORAGE permission in the manifest and it's granted in 'All files access'?" } + + return "SUCCESS!!\n\nFile $fileName with content $fileContent saved to $externalStorageDir" } } From bdcea8707768ad3103a52b065d3785b1fd3428c4 Mon Sep 17 00:00:00 2001 From: Jan Seredynski Date: Wed, 5 Jun 2024 11:12:21 +0200 Subject: [PATCH 14/33] Add a new demo and refactor existing demos --- .../demo-1/MastgTest.kt | 44 +++++-- .../demo-1/demo.md | 4 +- .../demo-1/output.txt | 74 ++++++++++- .../demo-1/script.js | 12 ++ .../demo-1/demo.md | 8 +- .../demo-1/output.sarif | 61 ++++++--- .../demo-1/output.txt | 2 +- .../demo-2/MastgTest.kt | 30 +++++ .../demo-2/MastgTest_reversed.java | 41 +++++++ .../demo-2/demo.md | 14 +-- .../demo-2/output.sarif | 63 ++++++---- .../demo-2/output.txt | 13 +- .../demo-2/run.sh | 4 +- .../demo-3/demo.md | 4 +- .../{demo-2 => demo-4}/AndroidManifest.xml | 0 .../AndroidManifest_reversed.xml | 0 .../demo-4/demo.md | 29 +++++ .../demo-4/output.sarif | 116 ++++++++++++++++++ .../demo-4/output.txt | 11 ++ .../demo-4/run.sh | 2 + ...ted-shared-storage-no-user-interaction.yml | 18 ++- 21 files changed, 471 insertions(+), 79 deletions(-) create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest.kt create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest_reversed.java rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/{demo-2 => demo-4}/AndroidManifest.xml (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/{demo-2 => demo-4}/AndroidManifest_reversed.xml (100%) create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/demo.md create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/output.sarif create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/output.txt create mode 100755 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/run.sh diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/MastgTest.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/MastgTest.kt index a210d84420..d9641f0f46 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/MastgTest.kt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/MastgTest.kt @@ -1,20 +1,26 @@ package org.owasp.mastestapp import android.content.Context -import android.os.Environment import android.util.Log import java.io.File import java.io.FileOutputStream import java.io.IOException +import android.content.ContentValues +import android.os.Environment +import android.provider.MediaStore +import java.io.OutputStream class MastgTest (private val context: Context){ fun mastgTest(): String { - - val externalStorageDir = Environment.getExternalStorageDirectory() - + mastgTestApi() + mastgTestMediaStore() + return "SUCCESS!!\n\nFiles have been written with API and MediaStore" + } + fun mastgTestApi() { + val externalStorageDir = context.getExternalFilesDir(null) val fileName = File(externalStorageDir, "secret.txt") - val fileContent = "Secret not using scoped storage" + val fileContent = "Secret may use scoped storage depending on Android version" try { FileOutputStream(fileName).use { output -> @@ -23,9 +29,33 @@ class MastgTest (private val context: Context){ } } catch (e: IOException) { Log.e("WriteExternalStorage", "Error writing file to external storage", e) - return "ERROR!!\n\nError writing file to external storage. Do you have the MANAGE_EXTERNAL_STORAGE permission in the manifest and it's granted in 'All files access'?" } + } - return "SUCCESS!!\n\nFile $fileName with content $fileContent saved to $externalStorageDir" + fun mastgTestMediaStore() { + try { + val resolver = context.contentResolver + var randomNum = (0..100).random().toString() + val contentValues = ContentValues().apply { + put(MediaStore.MediaColumns.DISPLAY_NAME, "secretFile$randomNum.txt") + put(MediaStore.MediaColumns.MIME_TYPE, "text/plain") + put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS) + } + val textUri = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues) + + textUri?.let { + val outputStream: OutputStream? = resolver.openOutputStream(it) + outputStream?.use { + it.write("Secret data".toByteArray()) + it.flush() + } + Log.d("MediaStore", "File written to external storage successfully.") + } ?: run { + Log.e("MediaStore", "Error inserting URI to MediaStore.") + } + } catch (exception: Exception) { + Log.e("MediaStore", "Error writing file to URI from MediaStore", exception) + } } } + diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/demo.md index b7aea37f17..0aac64e20d 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/demo.md @@ -5,11 +5,11 @@ tools: [frida] code: [kotlin] --- -### Demo +### Sample The snippet below shows sample code that creates a file in external storage. -{{ snippet.kt }} +{{ MastgTest.kt }} ### Steps diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/output.txt index 1a04f14a14..7a7d577005 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/output.txt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/output.txt @@ -1,4 +1,4 @@ -[WARNING] Opening a file from external storage at: /storage/emulated/0/secret.txt +[WARNING] Opening a file from external storage at: /storage/emulated/0/Android/data/org.owasp.mastestapp/files/secret.txt Invoked from: java.lang.Exception at libcore.io.Linux.open(Native Method) at libcore.io.ForwardingOs.open(ForwardingOs.java:167) @@ -8,7 +8,77 @@ Invoked from: java.lang.Exception at libcore.io.IoBridge.open(IoBridge.java:482) at java.io.FileOutputStream.(FileOutputStream.java:235) at java.io.FileOutputStream.(FileOutputStream.java:186) - at org.owasp.mastestapp.MastgTest.mastgTest(MastgTest.kt:20) + at org.owasp.mastestapp.MastgTest.mastgTestApi(MastgTest.kt:26) + at org.owasp.mastestapp.MastgTest.mastgTest(MastgTest.kt:16) + at org.owasp.mastestapp.MainActivityKt$MyScreenContent$1$1$1.invoke(MainActivity.kt:73) + at org.owasp.mastestapp.MainActivityKt$MyScreenContent$1$1$1.invoke(MainActivity.kt:71) + at androidx.compose.foundation.ClickablePointerInputNode$pointerInput$3.invoke-k-4lQ0M(Clickable.kt:987) + at androidx.compose.foundation.ClickablePointerInputNode$pointerInput$3.invoke(Clickable.kt:981) + at androidx.compose.foundation.gestures.TapGestureDetectorKt$detectTapAndPress$2$1.invokeSuspend(TapGestureDetector.kt:255) + at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) + at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:177) + at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:166) + at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:474) + at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:508) + at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:497) + at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.kt:368) + at androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNodeImpl$PointerEventHandlerCoroutine.offerPointerEvent(SuspendingPointerInputFilter.kt:665) + at androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNodeImpl.dispatchPointerEvent(SuspendingPointerInputFilter.kt:544) + at androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNodeImpl.onPointerEvent-H0pRuoY(SuspendingPointerInputFilter.kt:566) + at androidx.compose.foundation.AbstractClickablePointerInputNode.onPointerEvent-H0pRuoY(Clickable.kt:947) + at androidx.compose.foundation.AbstractClickableNode.onPointerEvent-H0pRuoY(Clickable.kt:795) + at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:317) + at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:303) + at androidx.compose.ui.input.pointer.NodeParent.dispatchMainEventPass(HitPathTracker.kt:185) + at androidx.compose.ui.input.pointer.HitPathTracker.dispatchChanges(HitPathTracker.kt:104) + at androidx.compose.ui.input.pointer.PointerInputEventProcessor.process-BIzXfog(PointerInputEventProcessor.kt:113) + at androidx.compose.ui.platform.AndroidComposeView.sendMotionEvent-8iAsVTc(AndroidComposeView.android.kt:1576) + at androidx.compose.ui.platform.AndroidComposeView.handleMotionEvent-8iAsVTc(AndroidComposeView.android.kt:1527) + at androidx.compose.ui.platform.AndroidComposeView.dispatchTouchEvent(AndroidComposeView.android.kt:1466) + at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3060) + at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2755) + at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3060) + at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2755) + at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3060) + at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2755) + at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3060) + at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2755) + at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:465) + at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1849) + at android.app.Activity.dispatchTouchEvent(Activity.java:3993) + at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:423) + at android.view.View.dispatchPointerEvent(View.java:13674) + at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5482) + at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5285) + at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4788) + at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4841) + at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4807) + at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4947) + at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4815) + at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:5004) + at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4788) + at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4841) + at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4807) + at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4815) + at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4788) + at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:7505) + at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:7474) + at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7435) + at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7630) + at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:188) + at android.os.MessageQueue.nativePollOnce(Native Method) + at android.os.MessageQueue.next(MessageQueue.java:336) + at android.os.Looper.loop(Looper.java:174) + at android.app.ActivityThread.main(ActivityThread.java:7356) + at java.lang.reflect.Method.invoke(Native Method) + at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) + at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) + +[WARNING] Opening a file with MediaStore at: content://media/external/downloads/27 +Invoked from: java.lang.Exception + at android.content.ContentResolver.insert(Native Method) + at org.owasp.mastestapp.MastgTest.mastgTestMediaStore(MastgTest.kt:44) + at org.owasp.mastestapp.MastgTest.mastgTest(MastgTest.kt:17) at org.owasp.mastestapp.MainActivityKt$MyScreenContent$1$1$1.invoke(MainActivity.kt:73) at org.owasp.mastestapp.MainActivityKt$MyScreenContent$1$1$1.invoke(MainActivity.kt:71) at androidx.compose.foundation.ClickablePointerInputNode$pointerInput$3.invoke-k-4lQ0M(Clickable.kt:987) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/script.js b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/script.js index 01b96c46b2..e125fdd428 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/script.js +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/script.js @@ -13,3 +13,15 @@ Interceptor.attach(Module.getExportByName(null, 'open'), { }); } }); + +Java.perform(function() { + let ContentResolver = Java.use("android.content.ContentResolver"); + ContentResolver["insert"].implementation = function (uri, values) { + var result = this["insert"](uri, values); + console.log('[WARNING] Opening a file with MediaStore at:', result) + Java.performNow(function() { + console.log("Invoked from: "+Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new())) + }); + return result + }; +}) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md index 6358b27609..e98fed4f65 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md @@ -1,19 +1,19 @@ --- platform: android -title: Find common APIs that return paths to External Storage locations +title: Find common APIs that return paths to Public External Storage locations tools: [semgrep] code: [kotlin] --- -### Demo +### Sample -{{ MastgTest.kt }} +{{ MastgTest_reversed.java }} ### Steps Let's run our semgrep rule against the reversed java code. -{{ ../rules/mastg-android-data-unencrypted-external.yml }} +{{ ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml }} {{ run.sh }} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif index 8f7b939cb9..66c1eef8d8 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif @@ -11,7 +11,7 @@ "results": [ { "fingerprints": { - "matchBasedId/v1": "e1a40a9ec09f82c43cc5a422b90cb75783cb8a85bce0b16f5c908d5af667c2c0de7c720e7e480b6b09b8bb7ae7203deea639a4e5f2a7581e51461e08b414320b_0" + "matchBasedId/v1": "08d14b1ca14fd823ee947dd5068ba82e1185bb48d76fa44a2f2f14193c45ab9975bc8bf4e1af53120204c6c3b7edfda9d6ef9a04bc14e600baa636dfeebfb62d_0" }, "locations": [ { @@ -36,7 +36,7 @@ "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" }, "properties": {}, - "ruleId": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api" + "ruleId": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public" }, { "fingerprints": { @@ -77,20 +77,20 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + "markdown": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions", + "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped" } }, { @@ -98,20 +98,20 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary", - "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public" } }, { @@ -119,20 +119,41 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" + } + }, + { + "defaultConfiguration": { + "level": "warning" + }, + "fullDescription": { + "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + }, + "help": { + "markdown": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary", + "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + }, + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest", + "properties": { + "precision": "very-high", + "tags": [] + }, + "shortDescription": { + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest" } } ], diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.txt index 3f5b59b43a..686be30746 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.txt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.txt @@ -5,7 +5,7 @@ └─────────────────┘ MastgTest_reversed.java - ❯❱ rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api + ❯❱ rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public [MASVS-STORAGE] Make sure to encrypt files at these locations if necessary 27┆ File externalStorageDir = Environment.getExternalStorageDirectory(); diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest.kt new file mode 100644 index 0000000000..b4fd6ea03f --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest.kt @@ -0,0 +1,30 @@ +package org.owasp.mastestapp + +import android.content.Context +import android.util.Log +import java.io.File +import java.io.FileOutputStream +import java.io.IOException + +class MastgTest (private val context: Context){ + + fun mastgTest(): String { + + val externalStorageDir = context.getExternalFilesDir(null) + + val fileName = File(externalStorageDir, "secret.txt") + val fileContent = "Secret may use scoped storage depending on Android version" + + try { + FileOutputStream(fileName).use { output -> + output.write(fileContent.toByteArray()) + Log.d("WriteExternalStorage", "File written to external storage successfully.") + } + } catch (e: IOException) { + Log.e("WriteExternalStorage", "Error writing file to external storage", e) + return "ERROR!!\n\nError writing file to external storage" + } + + return "SUCCESS!!\n\nFile $fileName with content $fileContent saved to $externalStorageDir" + } +} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest_reversed.java b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest_reversed.java new file mode 100644 index 0000000000..66ef18ed21 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest_reversed.java @@ -0,0 +1,41 @@ +package org.owasp.mastestapp; + +import android.content.Context; +import android.util.Log; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import kotlin.Metadata; +import kotlin.io.CloseableKt; +import kotlin.jvm.internal.Intrinsics; +import kotlin.text.Charsets; +/* compiled from: MastgTest.kt */ +@Metadata(d1 = {"\u0000\u0018\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0000\b\u0007\u0018\u00002\u00020\u0001B\r\u0012\u0006\u0010\u0002\u001a\u00020\u0003¢\u0006\u0002\u0010\u0004J\u0006\u0010\u0005\u001a\u00020\u0006R\u000e\u0010\u0002\u001a\u00020\u0003X\u0082\u0004¢\u0006\u0002\n\u0000¨\u0006\u0007"}, d2 = {"Lorg/owasp/mastestapp/MastgTest;", "", "context", "Landroid/content/Context;", "(Landroid/content/Context;)V", "mastgTest", "", "app_debug"}, k = 1, mv = {1, 9, 0}, xi = 48) +/* loaded from: classes4.dex */ +public final class MastgTest { + public static final int $stable = 8; + private final Context context; + + public MastgTest(Context context) { + Intrinsics.checkNotNullParameter(context, "context"); + this.context = context; + } + + public final String mastgTest() { + File externalStorageDir = this.context.getExternalFilesDir(null); + File fileName = new File(externalStorageDir, "secret.txt"); + try { + FileOutputStream fileOutputStream = new FileOutputStream(fileName); + FileOutputStream output = fileOutputStream; + byte[] bytes = "Secret may use scoped storage depending on Android version".getBytes(Charsets.UTF_8); + Intrinsics.checkNotNullExpressionValue(bytes, "this as java.lang.String).getBytes(charset)"); + output.write(bytes); + Log.d("WriteExternalStorage", "File written to external storage successfully."); + CloseableKt.closeFinally(fileOutputStream, null); + return "SUCCESS!!\n\nFile " + fileName + " with content Secret may use scoped storage depending on Android version saved to " + externalStorageDir; + } catch (IOException e) { + Log.e("WriteExternalStorage", "Error writing file to external storage", e); + return "ERROR!!\n\nError writing file to external storage"; + } + } +} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md index 867e13b53b..7e4be22903 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md @@ -1,17 +1,17 @@ --- platform: android -title: Find permissions that allows an app to write to locations shared with other apps +title: Find common APIs that return paths to Scoped External Storage locations tools: [semgrep] -code: [xml] +code: [kotlin] --- -### Demo +### Sample -{{ AndroidManifest.xml }} +{{ MastgTest_reversed.java }} ### Steps -Let's run our semgrep rule against the sample manifest file. +Let's run our semgrep rule against the reversed java code. {{ ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml }} @@ -19,11 +19,11 @@ Let's run our semgrep rule against the sample manifest file. ### Observation -The rule has identified that the manifest file declares `MANAGE_EXTERNAL_STORAGE` permission. +The rule has identified one location in the code file where a path to scoped external storage is returned. {{ output.txt }} ### Evaluation -Review your code to make sure you don't store sensitive unencrypted data in the external storage unintentionally. +Review the decompiled code at the location specified in the output (file and line number). This test fails because the file written by this instance contains sensitive data, specifically a password. diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif index 7801a5662d..2b6958ba87 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif @@ -11,32 +11,32 @@ "results": [ { "fingerprints": { - "matchBasedId/v1": "4f4da620f6961a9f5dc3861a6ead2be3dac9f043e8beff0c84200108663f19c8083459d308024a924a78f3301bb886eaac9699eee70be6a890110bca7aec4267_0" + "matchBasedId/v1": "4f302b675b47e4b5cc507cc6322f5cfe3fd8bbedb85aa283764d89b22cccc004539df972ea0c655da7f55bbdafc75ddd47c08ce605d0dee0f02bff04d3d3aa66_0" }, "locations": [ { "physicalLocation": { "artifactLocation": { - "uri": "AndroidManifest_reversed.xml", + "uri": "MastgTest_reversed.java", "uriBaseId": "%SRCROOT%" }, "region": { - "endColumn": 78, - "endLine": 2, + "endColumn": 73, + "endLine": 25, "snippet": { - "text": " " + "text": " File externalStorageDir = this.context.getExternalFilesDir(null);" }, - "startColumn": 55, - "startLine": 2 + "startColumn": 35, + "startLine": 25 } } } ], "message": { - "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" }, "properties": {}, - "ruleId": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest" + "ruleId": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped" } ], "tool": { @@ -48,20 +48,20 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" } }, { @@ -69,20 +69,41 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + "markdown": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions", + "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped" + } + }, + { + "defaultConfiguration": { + "level": "warning" + }, + "fullDescription": { + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + }, + "help": { + "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + }, + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public", + "properties": { + "precision": "very-high", + "tags": [] + }, + "shortDescription": { + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public" } }, { diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt index ed9143c160..a149fab232 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt @@ -3,9 +3,10 @@ ┌────────────────┐ │ 1 Code Finding │ └────────────────┘ - - AndroidManifest_reversed.xml - ❯❱ rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest - [MASVS-STORAGE] Make sure to encrypt files in external storage if necessary - - 2┆ + + MastgTest_reversed.java + ❯❱ rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped + [MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given + relevant permissions + + 25┆ File externalStorageDir = this.context.getExternalFilesDir(null); diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh index 3d4a4d5b0e..a0886a14ee 100755 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh @@ -1,2 +1,2 @@ -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml ./AndroidManifest_reversed.xml --text -o output.txt -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml ./AndroidManifest_reversed.xml --sarif -o output.sarif +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml ./MastgTest_reversed.java --text -o output.txt +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml ./MastgTest_reversed.java --sarif -o output.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md index 7c6627100c..1575dbdc6b 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md @@ -5,9 +5,9 @@ tools: [semgrep] code: [kotlin] --- -### Demo +### Sample -{{ MastgTest.kt }} +{{ MastgTest_reversed.java }} ### Steps diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/AndroidManifest.xml b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/AndroidManifest.xml similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/AndroidManifest.xml rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/AndroidManifest.xml diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/AndroidManifest_reversed.xml b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/AndroidManifest_reversed.xml similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/AndroidManifest_reversed.xml rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/AndroidManifest_reversed.xml diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/demo.md new file mode 100644 index 0000000000..1f06eaf8a5 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/demo.md @@ -0,0 +1,29 @@ +--- +platform: android +title: Find permissions that allows an app to write to locations shared with other apps +tools: [semgrep] +code: [xml] +--- + +### Sample + +{{ AndroidManifest_reversed.xml }} + +### Steps + +Let's run our semgrep rule against the sample manifest file. + +{{ ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml }} + +{{ run.sh }} + +### Observation + +The rule has identified that the manifest file declares `MANAGE_EXTERNAL_STORAGE` permission. + +{{ output.txt }} + +### Evaluation + +Review your code to make sure you don't store sensitive unencrypted data in the external storage unintentionally. + diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/output.sarif new file mode 100644 index 0000000000..7801a5662d --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/output.sarif @@ -0,0 +1,116 @@ +{ + "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json", + "runs": [ + { + "invocations": [ + { + "executionSuccessful": true, + "toolExecutionNotifications": [] + } + ], + "results": [ + { + "fingerprints": { + "matchBasedId/v1": "4f4da620f6961a9f5dc3861a6ead2be3dac9f043e8beff0c84200108663f19c8083459d308024a924a78f3301bb886eaac9699eee70be6a890110bca7aec4267_0" + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "AndroidManifest_reversed.xml", + "uriBaseId": "%SRCROOT%" + }, + "region": { + "endColumn": 78, + "endLine": 2, + "snippet": { + "text": " " + }, + "startColumn": 55, + "startLine": 2 + } + } + } + ], + "message": { + "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + }, + "properties": {}, + "ruleId": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest" + } + ], + "tool": { + "driver": { + "name": "Semgrep OSS", + "rules": [ + { + "defaultConfiguration": { + "level": "warning" + }, + "fullDescription": { + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + }, + "help": { + "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + }, + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api", + "properties": { + "precision": "very-high", + "tags": [] + }, + "shortDescription": { + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api" + } + }, + { + "defaultConfiguration": { + "level": "warning" + }, + "fullDescription": { + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + }, + "help": { + "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + }, + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", + "properties": { + "precision": "very-high", + "tags": [] + }, + "shortDescription": { + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" + } + }, + { + "defaultConfiguration": { + "level": "warning" + }, + "fullDescription": { + "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + }, + "help": { + "markdown": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary", + "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + }, + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest", + "properties": { + "precision": "very-high", + "tags": [] + }, + "shortDescription": { + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest" + } + } + ], + "semanticVersion": "1.63.0" + } + } + } + ], + "version": "2.1.0" +} \ No newline at end of file diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/output.txt new file mode 100644 index 0000000000..ed9143c160 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/output.txt @@ -0,0 +1,11 @@ + + +┌────────────────┐ +│ 1 Code Finding │ +└────────────────┘ + + AndroidManifest_reversed.xml + ❯❱ rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest + [MASVS-STORAGE] Make sure to encrypt files in external storage if necessary + + 2┆ diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/run.sh new file mode 100755 index 0000000000..3d4a4d5b0e --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/run.sh @@ -0,0 +1,2 @@ +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml ./AndroidManifest_reversed.xml --text -o output.txt +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml ./AndroidManifest_reversed.xml --sarif -o output.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml index 11400d77f1..f6fa40834e 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml @@ -1,5 +1,5 @@ rules: - - id: mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api + - id: mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public severity: WARNING languages: - java @@ -7,15 +7,23 @@ rules: summary: This rule looks for methods that returns locations to "external storage" which is shared with other apps message: "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" pattern-either: - - pattern: $X.getExternalFilesDir(...) - - pattern: $X.getExternalFilesDirs(...) - pattern: $X.getExternalStorageDirectory(...) - pattern: $X.getExternalStoragePublicDirectory(...) + - pattern: $X.getDownloadCacheDirectory(...) + - pattern: Intent.ACTION_CREATE_DOCUMENT + - id: mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped + severity: WARNING + languages: + - java + metadata: + summary: This rule looks for methods that returns locations to "scoped external storage" + message: "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" + pattern-either: + - pattern: $X.getExternalFilesDir(...) + - pattern: $X.getExternalFilesDirs(...) - pattern: $X.getExternalCacheDir(...) - pattern: $X.getExternalCacheDirs(...) - pattern: $X.getExternalMediaDirs(...) - - pattern: $X.getDownloadCacheDirectory(...) - - pattern: Intent.ACTION_CREATE_DOCUMENT - id: mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest severity: WARNING languages: From 1d0dbb6e2980ae2703ce9e0e14aaea507eab0d46 Mon Sep 17 00:00:00 2001 From: Jan Seredynski Date: Wed, 5 Jun 2024 13:52:55 +0200 Subject: [PATCH 15/33] Add a demo with listing all files --- .../demo-1/MastgTest.kt | 0 .../demo-1/demo.md | 32 ++++++++++ .../demo-1/new_files.txt | 2 + .../demo-1/new_files/secret.txt | 1 + .../demo-1/new_files/secretFile75.txt | 1 + .../demo-1/run_after.sh | 10 +++ .../demo-1/run_before.sh | 6 ++ .../test.md | 39 ++++++++++++ .../demo-1/MastgTest.kt | 61 +++++++++++++++++++ .../demo-1/demo.md | 2 +- .../demo-1/output.txt | 0 .../demo-1/run.sh | 0 .../demo-1/script.js | 0 .../test.md | 0 14 files changed, 153 insertions(+), 1 deletion(-) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/{android-data-unencrypted-shared-storage-no-user-interaction-frida => android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff}/demo-1/MastgTest.kt (100%) create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files.txt create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secret.txt create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secretFile75.txt create mode 100755 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_after.sh create mode 100755 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_before.sh create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/MastgTest.kt rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/{android-data-unencrypted-shared-storage-no-user-interaction-frida => android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida}/demo-1/demo.md (95%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/{android-data-unencrypted-shared-storage-no-user-interaction-frida => android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida}/demo-1/output.txt (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/{android-data-unencrypted-shared-storage-no-user-interaction-frida => android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida}/demo-1/run.sh (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/{android-data-unencrypted-shared-storage-no-user-interaction-frida => android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida}/demo-1/script.js (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/{android-data-unencrypted-shared-storage-no-user-interaction-frida => android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida}/test.md (100%) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/MastgTest.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/MastgTest.kt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/MastgTest.kt rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/MastgTest.kt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md new file mode 100644 index 0000000000..f49ac197a7 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md @@ -0,0 +1,32 @@ +--- +platform: android +title: Listing files inside External Storage +tools: [adb] +code: [kotlin] +--- + +### Sample + +The snippet below shows sample code that creates a file in external storage. + +{{ MastgTest.kt }} + +### Steps + +1. Install an app on your device +2. Execute `run_before.sh` +3. Open an app and excercise it to trigger file creations +4. Execute `run_after.sh` +5. Close the app once you finish testing + +{{ run.sh }} + +### Observation + +There is a list of all created files inside `new_files.txt`. Their content is inside `./new_files/` directory. + +{{ output.txt }} + +### Evaluation + +This test fails because the file contains a secretFile.txt. diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files.txt new file mode 100644 index 0000000000..7d684fc233 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files.txt @@ -0,0 +1,2 @@ +/sdcard/Android/data/org.owasp.mastestapp/files/secret.txt +/sdcard/Download/secretFile75.txt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secret.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secret.txt new file mode 100644 index 0000000000..8f257b57c8 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secret.txt @@ -0,0 +1 @@ +Secret may use scoped storage depending on Android version \ No newline at end of file diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secretFile75.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secretFile75.txt new file mode 100644 index 0000000000..bbb2c78f5b --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secretFile75.txt @@ -0,0 +1 @@ +Secret data \ No newline at end of file diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_after.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_after.sh new file mode 100755 index 0000000000..031462c4e3 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_after.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# SUMMARY: List all files created after the creation date of a file created in run_before + +adb shell "find /sdcard/ -type f -newer /data/local/tmp/test_start" > new_files.txt +adb shell "rm /data/local/tmp/test_start" +mkdir -p new_files +while read -r line; do + adb pull "$line" ./new_files/ +done < new_files.txt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_before.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_before.sh new file mode 100755 index 0000000000..0390be1498 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_before.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# SUMMARY: This script creates a dummy file to mark a timestamp that we can use later +# on to identify files created during the app excercising + +adb shell "touch /data/local/tmp/test_start" diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md new file mode 100644 index 0000000000..a9503a6f99 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md @@ -0,0 +1,39 @@ +--- +platform: android +title: Listing Files Stored to External Locations on Runtime +apis: [Environment#getExternalStorageDirectory, Environment#getExternalStorageDirectory, Environment#getExternalFilesDir, Environment#getExternalCacheDir, SharedPreferences, FileOutPutStream] +type: [dynamic] +--- + +## Overview + +Comparing the list of all files in the shared and external storage before and after excersising the app may reveal sensitive files stored unintentionally. + +## Steps + +1. Make sure you have ADB installed + +2. Install the app. + +3. Execute `run_before.sh` before opening the app to mark the timestamp. + +4. Excercise the app + +5. Execute `run_after.sh` to list all the files created by the app in the external storage. + + +## Observation + +The **output** contains a list of files that were created during the excersising the app app. + +## Evaluation + +The test case fails if the files found above are not encrypted and leak sensitive data. + +For example, the following output shows sample files that should be manually inspected. + +```shell +/storage/emulated/0/Android/data/com.example/keys.json +/storage/emulated/0/Android/data/com.example/files/config.xml +/sdcard/secret.txt" +``` diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/MastgTest.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/MastgTest.kt new file mode 100644 index 0000000000..d9641f0f46 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/MastgTest.kt @@ -0,0 +1,61 @@ +package org.owasp.mastestapp + +import android.content.Context +import android.util.Log +import java.io.File +import java.io.FileOutputStream +import java.io.IOException +import android.content.ContentValues +import android.os.Environment +import android.provider.MediaStore +import java.io.OutputStream + +class MastgTest (private val context: Context){ + + fun mastgTest(): String { + mastgTestApi() + mastgTestMediaStore() + return "SUCCESS!!\n\nFiles have been written with API and MediaStore" + } + fun mastgTestApi() { + val externalStorageDir = context.getExternalFilesDir(null) + val fileName = File(externalStorageDir, "secret.txt") + val fileContent = "Secret may use scoped storage depending on Android version" + + try { + FileOutputStream(fileName).use { output -> + output.write(fileContent.toByteArray()) + Log.d("WriteExternalStorage", "File written to external storage successfully.") + } + } catch (e: IOException) { + Log.e("WriteExternalStorage", "Error writing file to external storage", e) + } + } + + fun mastgTestMediaStore() { + try { + val resolver = context.contentResolver + var randomNum = (0..100).random().toString() + val contentValues = ContentValues().apply { + put(MediaStore.MediaColumns.DISPLAY_NAME, "secretFile$randomNum.txt") + put(MediaStore.MediaColumns.MIME_TYPE, "text/plain") + put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS) + } + val textUri = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues) + + textUri?.let { + val outputStream: OutputStream? = resolver.openOutputStream(it) + outputStream?.use { + it.write("Secret data".toByteArray()) + it.flush() + } + Log.d("MediaStore", "File written to external storage successfully.") + } ?: run { + Log.e("MediaStore", "Error inserting URI to MediaStore.") + } + } catch (exception: Exception) { + Log.e("MediaStore", "Error writing file to URI from MediaStore", exception) + } + } +} + diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/demo.md similarity index 95% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/demo.md rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/demo.md index 0aac64e20d..3be4148a47 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/demo.md @@ -1,6 +1,6 @@ --- platform: android -title: File Tracing +title: File Tracing with Frida tools: [frida] code: [kotlin] --- diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/output.txt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/output.txt rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/output.txt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/run.sh similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/run.sh rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/run.sh diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/script.js b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/script.js similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/demo-1/script.js rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/script.js diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-frida/test.md rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md From 9ad1169491e63cb81a5d117377885f6402784b11 Mon Sep 17 00:00:00 2001 From: Jan Seredynski Date: Wed, 5 Jun 2024 13:57:40 +0200 Subject: [PATCH 16/33] Fix the spelling errors --- .../demo-1/demo.md | 2 +- .../demo-1/run_before.sh | 2 +- .../test.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md index f49ac197a7..cac645199d 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md @@ -15,7 +15,7 @@ The snippet below shows sample code that creates a file in external storage. 1. Install an app on your device 2. Execute `run_before.sh` -3. Open an app and excercise it to trigger file creations +3. Open an app and exercise it to trigger file creations 4. Execute `run_after.sh` 5. Close the app once you finish testing diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_before.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_before.sh index 0390be1498..4187c12ac6 100755 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_before.sh +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_before.sh @@ -1,6 +1,6 @@ #!/bin/bash # SUMMARY: This script creates a dummy file to mark a timestamp that we can use later -# on to identify files created during the app excercising +# on to identify files created during the app exercising adb shell "touch /data/local/tmp/test_start" diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md index a9503a6f99..50a91777dc 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md @@ -17,7 +17,7 @@ Comparing the list of all files in the shared and external storage before and af 3. Execute `run_before.sh` before opening the app to mark the timestamp. -4. Excercise the app +4. Exercise the app 5. Execute `run_after.sh` to list all the files created by the app in the external storage. From e8fab33b04cd787363227d66bd8a01e2ee474a90 Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Fri, 7 Jun 2024 10:46:45 +0200 Subject: [PATCH 17/33] fix md lint issues --- .../test.md | 1 - .../test.md | 3 +-- .../demo-1/demo.md | 1 - .../demo-2/demo.md | 1 - .../demo-3/demo.md | 1 + .../demo-4/demo.md | 1 - .../test.md | 4 +--- 7 files changed, 3 insertions(+), 9 deletions(-) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md index 50a91777dc..463f3b3b0a 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md @@ -21,7 +21,6 @@ Comparing the list of all files in the shared and external storage before and af 5. Execute `run_after.sh` to list all the files created by the app in the external storage. - ## Observation The **output** contains a list of files that were created during the excersising the app app. diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md index 458f0bebc4..30138ef9e6 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md @@ -17,11 +17,10 @@ Android apps use a variety of APIs to obtain a file path and store a file. Colle 3. Execute a `run.sh` to spawn an app with Frida and log all interactions with files. -4. Navigate to the screen of the mobile app that you want to analyse. +4. Navigate to the screen of the mobile app that you want to analyse. 5. Close the app to stop `frida` - ## Observation The **method trace output** contains a list of file locations that your app interacts with. You may need to use [adb shell](https://mas.owasp.org/MASTG/techniques/android/MASTG-TECH-0002/) to inspect these files manually. diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md index e98fed4f65..2837b932d8 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md @@ -26,4 +26,3 @@ The rule has identified one location in the code file where a path to external s ### Evaluation Review the decompiled code at the location specified in the output (file and line number). This test fails because the file written by this instance contains sensitive data, specifically a password. - diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md index 7e4be22903..d536410840 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md @@ -26,4 +26,3 @@ The rule has identified one location in the code file where a path to scoped ext ### Evaluation Review the decompiled code at the location specified in the output (file and line number). This test fails because the file written by this instance contains sensitive data, specifically a password. - diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md index 1575dbdc6b..0e735e0830 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md @@ -26,5 +26,6 @@ The rule has identified 2 locations that indicate a use of MediaStore API. ### Evaluation Review the reported instances and make sure to either: + - confirm you intended to make this data public - store this data in a more strict storage type diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/demo.md index 1f06eaf8a5..9dc018fc59 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/demo.md @@ -26,4 +26,3 @@ The rule has identified that the manifest file declares `MANAGE_EXTERNAL_STORAGE ### Evaluation Review your code to make sure you don't store sensitive unencrypted data in the external storage unintentionally. - diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md index 8ccb592ab6..e03607d48b 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md @@ -10,7 +10,7 @@ type: [static] This test looks for Android manifest permissions and APIs that allow an app to write to locations that are shared with other apps. This means that a third-party app with the proper permissions may be able to access data written to these locations. Therefore, this test verifies whether an app: - declares permissions required to write data to shared locations -- uses API to obtain location to shared locations +- uses API to obtain location to shared locations - uses MediaStore API Additionally, if the "external storage" is actually stored externally, e.g. on an SD card, it can be removed from the device and inserted into a card reader to extract sensitive data. @@ -42,7 +42,6 @@ If your app stores data with MediaStore API, a third-party app with proper permi 1. Run a [static analysis](../../../../../techniques/android/MASTG-TECH-0014.md) tool on the app to find if it uses storage locations shared with other apps, and identify the calls to those APIs and the relevant permissions. - ## Observation The output should contain a list of permissions and locations where paths to external storage are returned. @@ -55,4 +54,3 @@ Inspect app's source code using the provided information. The test case fails if - [Manage all files on a storage device](https://developer.android.com/training/data-storage/manage-all-files) - [Access media files from shared storage](https://developer.android.com/training/data-storage/shared/media) - From e8093a9b275858b7e8121cdaa43be0bd5d1afc35 Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Fri, 7 Jun 2024 10:51:41 +0200 Subject: [PATCH 18/33] fix md lint issues --- .../risk.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/risk.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/risk.md index b940d4c844..1fd9d4c08c 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/risk.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/risk.md @@ -16,18 +16,16 @@ Apps frequently opt to store data in the external storage due to its larger capa Developers may consider switching to Private Storage or Shared Storage Requiring User Interaction if they need more privacy and security. However, if the external storage is the most suitable for the app, it's a good practise to encrypt data stored in the external storage. Below you can find potential security impacts and mitigations linked to the use of the external storage. - ## Impact - **Loss of confidentiality**: An attacker can extract sensitive data stored externally, such as personal information and media like photos, documents, and audio files. - **Loss of secure material**: An attacker can extract passwords, cryptographic keys, and session tokens to facilitate additional attacks, such as identity theft or account takeover. -- **Modification of app's behaviour**: An attacker can tamper with data used by the app, altering the app's logic. For example, they could modify a database describing the state of premium features or inject a malicious payload to enable further attacks such as SQL injection and Path Traversal. +- **Modification of app's behaviour**: An attacker can tamper with data used by the app, altering the app's logic. For example, they could modify a database describing the state of premium features or inject a malicious payload to enable further attacks such as SQL injection and Path Traversal. - **Modification of downloaded code**: An app can download new functionality from the Internet and store the executable code in external storage before loading it into the process. An attacker can modify this code before it is used by the app. - ## Modes of Introduction This threat is primarily a concern for Android devices since they permit the use of external storage. Even if a device lacks physical external storage, Android emulates it to provide access to the external storage API. From d79b2d84110c892f86a8351d3e03b9ba26393c4f Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Sat, 15 Jun 2024 12:00:19 +0200 Subject: [PATCH 19/33] update rules to remove false positive separating manifest from apis. re-run with NO_COLOR to avoid bad characters --- .../demo-1/demo.md | 2 +- .../demo-1/output.sarif | 76 ++++--------------- .../demo-1/output.txt | 26 +++---- .../demo-1/run.sh | 4 +- .../demo-2/demo.md | 2 +- .../demo-2/output.sarif | 35 ++------- .../demo-2/output.txt | 12 +-- .../demo-2/run.sh | 4 +- .../demo-3/demo.md | 2 +- .../demo-3/output.sarif | 38 +++++----- .../demo-3/output.txt | 10 +-- .../demo-3/run.sh | 4 +- .../demo-4/demo.md | 2 +- .../demo-4/output.sarif | 44 +---------- .../demo-4/output.txt | 10 +-- .../demo-4/run.sh | 4 +- ...ared-storage-no-user-interaction-apis.yml} | 14 ---- ...d-storage-no-user-interaction-manifest.yml | 15 ++++ 18 files changed, 93 insertions(+), 211 deletions(-) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/{mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml => mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml} (71%) create mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest.yml diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md index 2837b932d8..675f5548b3 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md @@ -13,7 +13,7 @@ code: [kotlin] Let's run our semgrep rule against the reversed java code. -{{ ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml }} +{{ ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml }} {{ run.sh }} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif index 66c1eef8d8..1c4105c8cc 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif @@ -37,62 +37,12 @@ }, "properties": {}, "ruleId": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public" - }, - { - "fingerprints": { - "matchBasedId/v1": "01f2f74dc636d3094cd1abf9dbe8ebc57a4cd0a35a2cd5c851659dcd3c0693019211e4dcf3d8803b1a9a99dcf44401fdc9a739b10960c965f0262d2495ba5b1f_0" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "MastgTest_reversed.java", - "uriBaseId": "%SRCROOT%" - }, - "region": { - "endColumn": 100, - "endLine": 43, - "snippet": { - "text": " return \"Error writing file to external storage. Do you have the MANAGE_EXTERNAL_STORAGE permission in the manifest and it's granted?\";" - }, - "startColumn": 77, - "startLine": 43 - } - } - } - ], - "message": { - "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" - }, - "properties": {}, - "ruleId": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest" } ], "tool": { "driver": { "name": "Semgrep OSS", "rules": [ - { - "defaultConfiguration": { - "level": "warning" - }, - "fullDescription": { - "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" - }, - "help": { - "markdown": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions", - "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" - }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped", - "properties": { - "precision": "very-high", - "tags": [] - }, - "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped" - } - }, { "defaultConfiguration": { "level": "warning" @@ -119,20 +69,20 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + "markdown": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions", + "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped" } }, { @@ -140,24 +90,24 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary", - "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" } } ], - "semanticVersion": "1.63.0" + "semanticVersion": "1.56.0" } } } diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.txt index 686be30746..6ba66f2e44 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.txt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.txt @@ -1,17 +1,11 @@ - - -┌─────────────────┐ -│ 2 Code Findings │ -└─────────────────┘ - - MastgTest_reversed.java - ❯❱ rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public - [MASVS-STORAGE] Make sure to encrypt files at these locations if necessary - + + +┌────────────────┐ +│ 1 Code Finding │ +└────────────────┘ + + MastgTest_reversed.java + rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public + [MASVS-STORAGE] Make sure to encrypt files at these locations if necessary + 27┆ File externalStorageDir = Environment.getExternalStorageDirectory(); - - ❯❱ rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest - [MASVS-STORAGE] Make sure to encrypt files in external storage if necessary - - 43┆ return "Error writing file to external storage. Do you have the MANAGE_EXTERNAL_STORAGE - permission in the manifest and it's granted?"; diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh index a0886a14ee..e8aa8fc78e 100755 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh @@ -1,2 +1,2 @@ -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml ./MastgTest_reversed.java --text -o output.txt -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml ./MastgTest_reversed.java --sarif -o output.sarif +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml ./MastgTest_reversed.java --text -o output.txt +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml ./MastgTest_reversed.java --sarif -o output.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md index d536410840..a604051df6 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md @@ -13,7 +13,7 @@ code: [kotlin] Let's run our semgrep rule against the reversed java code. -{{ ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml }} +{{ ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml }} {{ run.sh }} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif index 2b6958ba87..f8aa61a357 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif @@ -43,27 +43,6 @@ "driver": { "name": "Semgrep OSS", "rules": [ - { - "defaultConfiguration": { - "level": "warning" - }, - "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" - }, - "help": { - "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" - }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", - "properties": { - "precision": "very-high", - "tags": [] - }, - "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" - } - }, { "defaultConfiguration": { "level": "warning" @@ -111,24 +90,24 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary", - "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" } } ], - "semanticVersion": "1.63.0" + "semanticVersion": "1.56.0" } } } diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt index a149fab232..e0b6951351 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt @@ -3,10 +3,10 @@ ┌────────────────┐ │ 1 Code Finding │ └────────────────┘ - - MastgTest_reversed.java - ❯❱ rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped - [MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given - relevant permissions - + + MastgTest_reversed.java + rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped + [MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below + given relevant permissions + 25┆ File externalStorageDir = this.context.getExternalFilesDir(null); diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh index a0886a14ee..e8aa8fc78e 100755 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh @@ -1,2 +1,2 @@ -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml ./MastgTest_reversed.java --text -o output.txt -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml ./MastgTest_reversed.java --sarif -o output.sarif +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml ./MastgTest_reversed.java --text -o output.txt +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml ./MastgTest_reversed.java --sarif -o output.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md index 0e735e0830..76db5ce2ca 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md @@ -13,7 +13,7 @@ code: [kotlin] Let's run our semgrep rule against the sample code. -{{ ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml }} +{{ ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml }} {{ run.sh }} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.sarif index f029710522..4e4124efd6 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.sarif +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.sarif @@ -77,20 +77,20 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public" } }, { @@ -98,20 +98,20 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary", - "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + "markdown": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions", + "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped" } }, { @@ -119,24 +119,24 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" } } ], - "semanticVersion": "1.63.0" + "semanticVersion": "1.56.0" } } } diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.txt index 41192fc7b4..22fa62a1b6 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.txt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.txt @@ -3,11 +3,11 @@ ┌─────────────────┐ │ 2 Code Findings │ └─────────────────┘ - - MastgTest_reversed.java - ❯❱ rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore - [MASVS-STORAGE] Make sure to want this data to be shared with other apps - + + MastgTest_reversed.java + rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore + [MASVS-STORAGE] Make sure to want this data to be shared with other apps + 8┆ import android.provider.MediaStore; ⋮┆---------------------------------------- 35┆ Uri textUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues); diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/run.sh index a0886a14ee..e8aa8fc78e 100755 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/run.sh +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/run.sh @@ -1,2 +1,2 @@ -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml ./MastgTest_reversed.java --text -o output.txt -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml ./MastgTest_reversed.java --sarif -o output.sarif +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml ./MastgTest_reversed.java --text -o output.txt +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml ./MastgTest_reversed.java --sarif -o output.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/demo.md index 9dc018fc59..a956e57820 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/demo.md @@ -13,7 +13,7 @@ code: [xml] Let's run our semgrep rule against the sample manifest file. -{{ ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml }} +{{ ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest.yml }} {{ run.sh }} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/output.sarif index 7801a5662d..abb5409f0e 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/output.sarif +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/output.sarif @@ -43,48 +43,6 @@ "driver": { "name": "Semgrep OSS", "rules": [ - { - "defaultConfiguration": { - "level": "warning" - }, - "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" - }, - "help": { - "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" - }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api", - "properties": { - "precision": "very-high", - "tags": [] - }, - "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api" - } - }, - { - "defaultConfiguration": { - "level": "warning" - }, - "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" - }, - "help": { - "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" - }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", - "properties": { - "precision": "very-high", - "tags": [] - }, - "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" - } - }, { "defaultConfiguration": { "level": "warning" @@ -107,7 +65,7 @@ } } ], - "semanticVersion": "1.63.0" + "semanticVersion": "1.56.0" } } } diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/output.txt index ed9143c160..53d518b06c 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/output.txt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/output.txt @@ -3,9 +3,9 @@ ┌────────────────┐ │ 1 Code Finding │ └────────────────┘ - - AndroidManifest_reversed.xml - ❯❱ rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest - [MASVS-STORAGE] Make sure to encrypt files in external storage if necessary - + + AndroidManifest_reversed.xml + rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest + [MASVS-STORAGE] Make sure to encrypt files in external storage if necessary + 2┆ diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/run.sh index 3d4a4d5b0e..5301017a9f 100755 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/run.sh +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/run.sh @@ -1,2 +1,2 @@ -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml ./AndroidManifest_reversed.xml --text -o output.txt -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml ./AndroidManifest_reversed.xml --sarif -o output.sarif +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest.yml ./AndroidManifest_reversed.xml --text -o output.txt +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest.yml ./AndroidManifest_reversed.xml --sarif -o output.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml similarity index 71% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml index f6fa40834e..a736efaac4 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction.yml +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml @@ -24,20 +24,6 @@ rules: - pattern: $X.getExternalCacheDir(...) - pattern: $X.getExternalCacheDirs(...) - pattern: $X.getExternalMediaDirs(...) - - id: mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest - severity: WARNING - languages: - - generic - metadata: - summary: This rule scans for permissions that allows your app to write to external storage or shared storage - message: "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" - pattern-either: - - pattern: WRITE_EXTERNAL_STORAGE - - pattern: MANAGE_EXTERNAL_STORAGE - - pattern: ACCESS_ALL_EXTERNAL_STORAGE - - pattern: requestLegacyExternalStorage="true" - - pattern: preserveLegacyExternalStorage="true" - - pattern: android:requestRawExternalStorageAccess="true" - id: mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore severity: WARNING languages: diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest.yml b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest.yml new file mode 100644 index 0000000000..93fa6dc9a5 --- /dev/null +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest.yml @@ -0,0 +1,15 @@ +rules: + - id: mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest + severity: WARNING + languages: + - generic + metadata: + summary: This rule scans for permissions that allows your app to write to external storage or shared storage + message: "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" + pattern-either: + - pattern: WRITE_EXTERNAL_STORAGE + - pattern: MANAGE_EXTERNAL_STORAGE + - pattern: ACCESS_ALL_EXTERNAL_STORAGE + - pattern: requestLegacyExternalStorage="true" + - pattern: preserveLegacyExternalStorage="true" + - pattern: android:requestRawExternalStorageAccess="true" From e17a6381d3edd4bf1414474258ca0af7fae1edb5 Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Sat, 15 Jun 2024 12:04:05 +0200 Subject: [PATCH 20/33] minor corrections in android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff and renamed output file to output.txt to follow convention --- .../demo-1/MastgTest.kt | 1 + .../demo-1/demo.md | 2 +- .../demo-1/{new_files.txt => output.txt} | 0 .../demo-1/run_after.sh | 4 ++-- .../test.md | 6 +++--- 5 files changed, 7 insertions(+), 6 deletions(-) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/{new_files.txt => output.txt} (100%) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/MastgTest.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/MastgTest.kt index d9641f0f46..932b2daa69 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/MastgTest.kt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/MastgTest.kt @@ -17,6 +17,7 @@ class MastgTest (private val context: Context){ mastgTestMediaStore() return "SUCCESS!!\n\nFiles have been written with API and MediaStore" } + fun mastgTestApi() { val externalStorageDir = context.getExternalFilesDir(null) val fileName = File(externalStorageDir, "secret.txt") diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md index cac645199d..50cbb5d0cd 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md @@ -23,7 +23,7 @@ The snippet below shows sample code that creates a file in external storage. ### Observation -There is a list of all created files inside `new_files.txt`. Their content is inside `./new_files/` directory. +There is a list of all created files inside `output.txt`. Their content is inside the `./new_files/` directory. {{ output.txt }} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/output.txt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files.txt rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/output.txt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_after.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_after.sh index 031462c4e3..ecd2a03b0b 100755 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_after.sh +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_after.sh @@ -2,9 +2,9 @@ # SUMMARY: List all files created after the creation date of a file created in run_before -adb shell "find /sdcard/ -type f -newer /data/local/tmp/test_start" > new_files.txt +adb shell "find /sdcard/ -type f -newer /data/local/tmp/test_start" > output.txt adb shell "rm /data/local/tmp/test_start" mkdir -p new_files while read -r line; do adb pull "$line" ./new_files/ -done < new_files.txt +done < output.txt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md index 463f3b3b0a..ff9fe2bbf8 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md @@ -11,19 +11,19 @@ Comparing the list of all files in the shared and external storage before and af ## Steps -1. Make sure you have ADB installed +1. Make sure you have ADB installed. 2. Install the app. 3. Execute `run_before.sh` before opening the app to mark the timestamp. -4. Exercise the app +4. Exercise the app. 5. Execute `run_after.sh` to list all the files created by the app in the external storage. ## Observation -The **output** contains a list of files that were created during the excersising the app app. +The **output** contains a list of files that were created during the excersising the app. ## Evaluation From e7c29029b355ed86a63a52dca1a2dd683358149a Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Fri, 21 Jun 2024 08:36:57 +0200 Subject: [PATCH 21/33] merge demo-4 into demo-1 --- .../{demo-4 => demo-1}/AndroidManifest.xml | 0 .../AndroidManifest_reversed.xml | 0 .../demo-1/demo.md | 20 +++++++++-- .../demo-1/output.sarif | 36 +++++++++---------- .../output.sarif => demo-1/output2.sarif} | 0 .../{demo-4/output.txt => demo-1/output2.txt} | 0 .../demo-1/run.sh | 3 ++ .../demo-4/demo.md | 28 --------------- .../demo-4/run.sh | 2 -- 9 files changed, 38 insertions(+), 51 deletions(-) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/{demo-4 => demo-1}/AndroidManifest.xml (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/{demo-4 => demo-1}/AndroidManifest_reversed.xml (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/{demo-4/output.sarif => demo-1/output2.sarif} (100%) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/{demo-4/output.txt => demo-1/output2.txt} (100%) delete mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/demo.md delete mode 100755 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/run.sh diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/AndroidManifest.xml b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/AndroidManifest.xml similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/AndroidManifest.xml rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/AndroidManifest.xml diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/AndroidManifest_reversed.xml b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/AndroidManifest_reversed.xml similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/AndroidManifest_reversed.xml rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/AndroidManifest_reversed.xml diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md index 675f5548b3..47ee611981 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md @@ -2,27 +2,41 @@ platform: android title: Find common APIs that return paths to Public External Storage locations tools: [semgrep] -code: [kotlin] +code: [kotlin, xml] --- ### Sample +The snippet below shows sample code that creates a file in external storage. + {{ MastgTest_reversed.java }} +This requires special app access called ["All files access"](https://developer.android.com/preview/privacy/storage#all-files-access), so the following permission must be declared in the manifest file. + +{{ AndroidManifest_reversed.xml }} + ### Steps Let's run our semgrep rule against the reversed java code. {{ ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml }} +And another one against the sample manifest file. + +{{ ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest.yml }} + {{ run.sh }} ### Observation -The rule has identified one location in the code file where a path to external storage is returned. +The rule has identified one location in the code file where an API, `getExternalStorageDirectory`, is used to write to external storage. {{ output.txt }} +The rule has also identified that the manifest file declares `MANAGE_EXTERNAL_STORAGE` permission. + +{{ output2.txt }} + ### Evaluation -Review the decompiled code at the location specified in the output (file and line number). This test fails because the file written by this instance contains sensitive data, specifically a password. +After reviewing the decompiled code at the location specified in the output (file and line number) we can conclude that the test fails because the file written by this instance contains sensitive data, specifically a password. diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif index 1c4105c8cc..032f8270c3 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif @@ -48,20 +48,20 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" + "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", + "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" } }, { @@ -69,20 +69,20 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" }, "help": { - "markdown": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions", - "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" + "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", + "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public" } }, { @@ -90,20 +90,20 @@ "level": "warning" }, "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" }, "help": { - "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" + "markdown": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions", + "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", + "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped", + "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped", "properties": { "precision": "very-high", "tags": [] }, "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" + "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped" } } ], diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output2.sarif similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/output.sarif rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output2.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/output.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output2.txt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/output.txt rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output2.txt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh index e8aa8fc78e..76f29308aa 100755 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh @@ -1,2 +1,5 @@ NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml ./MastgTest_reversed.java --text -o output.txt NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml ./MastgTest_reversed.java --sarif -o output.sarif + +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest.yml ./AndroidManifest_reversed.xml --text -o output2.txt +NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest.yml ./AndroidManifest_reversed.xml --sarif -o output2.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/demo.md deleted file mode 100644 index a956e57820..0000000000 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/demo.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -platform: android -title: Find permissions that allows an app to write to locations shared with other apps -tools: [semgrep] -code: [xml] ---- - -### Sample - -{{ AndroidManifest_reversed.xml }} - -### Steps - -Let's run our semgrep rule against the sample manifest file. - -{{ ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest.yml }} - -{{ run.sh }} - -### Observation - -The rule has identified that the manifest file declares `MANAGE_EXTERNAL_STORAGE` permission. - -{{ output.txt }} - -### Evaluation - -Review your code to make sure you don't store sensitive unencrypted data in the external storage unintentionally. diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/run.sh deleted file mode 100755 index 5301017a9f..0000000000 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-4/run.sh +++ /dev/null @@ -1,2 +0,0 @@ -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest.yml ./AndroidManifest_reversed.xml --text -o output.txt -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest.yml ./AndroidManifest_reversed.xml --sarif -o output.sarif From 769257c4a801655ee8ff1d35db917bec65cef2dc Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Fri, 21 Jun 2024 11:13:41 +0200 Subject: [PATCH 22/33] updated kotlin samples to include a password-like and API key-like strings --- .../demo-1/MastgTest.kt | 4 ++-- .../demo-1/new_files/secret.txt | 2 +- .../demo-1/new_files/secretFile75.txt | 2 +- .../demo-1/MastgTest.kt | 4 ++-- .../demo-2/MastgTest.kt | 2 +- .../demo-2/MastgTest_reversed.java | 4 ++-- .../demo-3/MastgTest.kt | 2 +- .../demo-3/MastgTest_reversed.java | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/MastgTest.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/MastgTest.kt index 932b2daa69..a8e29022e9 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/MastgTest.kt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/MastgTest.kt @@ -21,7 +21,7 @@ class MastgTest (private val context: Context){ fun mastgTestApi() { val externalStorageDir = context.getExternalFilesDir(null) val fileName = File(externalStorageDir, "secret.txt") - val fileContent = "Secret may use scoped storage depending on Android version" + val fileContent = "secr3tPa$$W0rd\n" try { FileOutputStream(fileName).use { output -> @@ -47,7 +47,7 @@ class MastgTest (private val context: Context){ textUri?.let { val outputStream: OutputStream? = resolver.openOutputStream(it) outputStream?.use { - it.write("Secret data".toByteArray()) + it.write("MAS_API_KEY=8767086b9f6f976g-a8df76\n".toByteArray()) it.flush() } Log.d("MediaStore", "File written to external storage successfully.") diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secret.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secret.txt index 8f257b57c8..f5d3c92de6 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secret.txt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secret.txt @@ -1 +1 @@ -Secret may use scoped storage depending on Android version \ No newline at end of file +secr3tPa$$W0rd \ No newline at end of file diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secretFile75.txt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secretFile75.txt index bbb2c78f5b..5f17246f1a 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secretFile75.txt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secretFile75.txt @@ -1 +1 @@ -Secret data \ No newline at end of file +MAS_API_KEY=8767086b9f6f976g-a8df76 \ No newline at end of file diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/MastgTest.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/MastgTest.kt index d9641f0f46..ac2eb255ed 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/MastgTest.kt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/MastgTest.kt @@ -20,7 +20,7 @@ class MastgTest (private val context: Context){ fun mastgTestApi() { val externalStorageDir = context.getExternalFilesDir(null) val fileName = File(externalStorageDir, "secret.txt") - val fileContent = "Secret may use scoped storage depending on Android version" + val fileContent = "secr3tPa$$W0rd\n" try { FileOutputStream(fileName).use { output -> @@ -46,7 +46,7 @@ class MastgTest (private val context: Context){ textUri?.let { val outputStream: OutputStream? = resolver.openOutputStream(it) outputStream?.use { - it.write("Secret data".toByteArray()) + it.write("MAS_API_KEY=8767086b9f6f976g-a8df76\n".toByteArray()) it.flush() } Log.d("MediaStore", "File written to external storage successfully.") diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest.kt index b4fd6ea03f..6c210660a3 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest.kt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest.kt @@ -13,7 +13,7 @@ class MastgTest (private val context: Context){ val externalStorageDir = context.getExternalFilesDir(null) val fileName = File(externalStorageDir, "secret.txt") - val fileContent = "Secret may use scoped storage depending on Android version" + val fileContent = "secr3tPa$$W0rd\n" try { FileOutputStream(fileName).use { output -> diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest_reversed.java b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest_reversed.java index 66ef18ed21..3c97d2a650 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest_reversed.java +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest_reversed.java @@ -27,12 +27,12 @@ public final String mastgTest() { try { FileOutputStream fileOutputStream = new FileOutputStream(fileName); FileOutputStream output = fileOutputStream; - byte[] bytes = "Secret may use scoped storage depending on Android version".getBytes(Charsets.UTF_8); + byte[] bytes = "secr3tPa$$W0rd\n".getBytes(Charsets.UTF_8); Intrinsics.checkNotNullExpressionValue(bytes, "this as java.lang.String).getBytes(charset)"); output.write(bytes); Log.d("WriteExternalStorage", "File written to external storage successfully."); CloseableKt.closeFinally(fileOutputStream, null); - return "SUCCESS!!\n\nFile " + fileName + " with content Secret may use scoped storage depending on Android version saved to " + externalStorageDir; + return "SUCCESS!!\n\nFile " + fileName + " with content secr3tPa$$W0rd\n saved to " + externalStorageDir; } catch (IOException e) { Log.e("WriteExternalStorage", "Error writing file to external storage", e); return "ERROR!!\n\nError writing file to external storage"; diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest.kt b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest.kt index 07d1137fb8..c9a875fdb8 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest.kt +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest.kt @@ -22,7 +22,7 @@ class MastgTest (private val context: Context){ textUri?.let { val outputStream: OutputStream? = resolver.openOutputStream(it) outputStream?.use { - it.write("Secret data".toByteArray()) + it.write("MAS_API_KEY=8767086b9f6f976g-a8df76\n".toByteArray()) it.flush() } Log.d("MediaStore", "File written to external storage successfully.") diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest_reversed.java b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest_reversed.java index 759d77f6e2..67789df039 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest_reversed.java +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest_reversed.java @@ -38,7 +38,7 @@ public final String mastgTest() { if (outputStream != null) { OutputStream outputStream2 = outputStream; OutputStream it = outputStream2; - byte[] bytes = "Secret data".getBytes(Charsets.UTF_8); + byte[] bytes = "MAS_API_KEY=8767086b9f6f976g-a8df76\n".getBytes(Charsets.UTF_8); Intrinsics.checkNotNullExpressionValue(bytes, "this as java.lang.String).getBytes(charset)"); it.write(bytes); it.flush(); From 709bfd424c0d2578fdad78c969f612d95002207d Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Fri, 21 Jun 2024 11:37:44 +0200 Subject: [PATCH 23/33] Minor update to the risk mitigations paragraph. --- .../risk.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/risk.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/risk.md index 1fd9d4c08c..fba68f3b01 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/risk.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/risk.md @@ -40,6 +40,4 @@ On iOS, apps cannot directly write to or read from the arbitrary locations, as c ## Mitigations -Sensitive data stored in the external storage should be encrypted, and any keys used for encryption methods should be protected by the device's hardware-backed keystore, where available. It is highly discouraged to include a cryptographic key inside the application. You can also consider storing your files in the Private App Sandbox Storage. - -- [Android's EncryptedFile API wrapper for file encryption](https://developer.android.com/reference/androidx/security/crypto/EncryptedFile) +Sensitive data stored in the external storage should be encrypted, and any keys used for data encryption should be protected by the device's hardware-backed keystore, where available. It is highly discouraged to include cryptographic keys hardcoded inside the application. You can also consider storing your files in the [private app sandbox or internal storage](https://developer.android.com/training/data-storage/app-specific#internal) and using [Android's EncryptedFile API wrapper for file encryption](https://developer.android.com/reference/androidx/security/crypto/EncryptedFile). From 77ddf31226a0d135dc0b1014157f6630fb495c1d Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Fri, 21 Jun 2024 11:39:36 +0200 Subject: [PATCH 24/33] Updated tests titles and consolidated content. Additional content regarding external storage removed as we will include it in the Android Data Storage chapter. --- .../test.md | 13 +---- .../test.md | 18 +++---- .../test.md | 48 ++++++------------- 3 files changed, 22 insertions(+), 57 deletions(-) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md index ff9fe2bbf8..a16eba3f39 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md @@ -1,13 +1,12 @@ --- platform: android -title: Listing Files Stored to External Locations on Runtime -apis: [Environment#getExternalStorageDirectory, Environment#getExternalStorageDirectory, Environment#getExternalFilesDir, Environment#getExternalCacheDir, SharedPreferences, FileOutPutStream] +title: Files Written to External Storage type: [dynamic] --- ## Overview -Comparing the list of all files in the shared and external storage before and after excersising the app may reveal sensitive files stored unintentionally. +The goal of this test is to simply retrieve the files and inspect them regardless of the APIs used to write them. Therefore, we'll use a simple approach that consists of getting the list of all files in the shared and external storage before and after the app is exercised, and then comparing them, as this may reveal sensitive files that were unintentionally stored. ## Steps @@ -28,11 +27,3 @@ The **output** contains a list of files that were created during the excersising ## Evaluation The test case fails if the files found above are not encrypted and leak sensitive data. - -For example, the following output shows sample files that should be manually inspected. - -```shell -/storage/emulated/0/Android/data/com.example/keys.json -/storage/emulated/0/Android/data/com.example/files/config.xml -/sdcard/secret.txt" -``` diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md index 30138ef9e6..ad728cbf3e 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md @@ -1,7 +1,7 @@ --- platform: android -title: Data Stored to External Locations on Runtime -apis: [Environment#getExternalStorageDirectory, Environment#getExternalStorageDirectory, Environment#getExternalFilesDir, Environment#getExternalCacheDir, SharedPreferences, FileOutPutStream] +title: Runtime Use of APIs to Access External Storage +apis: [Environment#getExternalStorageDirectory, Environment#getExternalStorageDirectory, Environment#getExternalFilesDir, Environment#getExternalCacheDir, FileOutPutStream] type: [dynamic] --- @@ -11,7 +11,7 @@ Android apps use a variety of APIs to obtain a file path and store a file. Colle ## Steps -1. Make sure you have Frida installed +1. Make sure you have Frida installed. 2. Install the app. @@ -19,20 +19,14 @@ Android apps use a variety of APIs to obtain a file path and store a file. Colle 4. Navigate to the screen of the mobile app that you want to analyse. -5. Close the app to stop `frida` +5. Close the app to stop Frida. ## Observation -The **method trace output** contains a list of file locations that your app interacts with. You may need to use [adb shell](https://mas.owasp.org/MASTG/techniques/android/MASTG-TECH-0002/) to inspect these files manually. +The **method trace output** contains a list of file locations that your app interacts with. ## Evaluation The test case fails if the files found above are not encrypted and leak sensitive data. -For example, the following output shows sample files that should be manually inspected. - -```shell -/storage/emulated/0/Android/data/com.example/keys.json -/storage/emulated/0/Android/data/com.example/files/config.xml -/sdcard/secret.txt" -``` +You can inspect those files manually using [adb shell](https://mas.owasp.org/MASTG/techniques/android/MASTG-TECH-0002/) to retrieve them from the device. diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md index e03607d48b..1a48c9d3ea 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md @@ -1,54 +1,34 @@ --- platform: android -title: Use of APIs to access External Storage Locations -apis: [Environment#getExternalStoragePublicDirectory, Environment#getExternalStorageDirectory, Environment#getExternalFilesDir, Environment#getExternalCacheDir, MediaStore] +title: References to APIs and Permissions for Accessing External Storage +apis: [Environment#getExternalStoragePublicDirectory, Environment#getExternalStorageDirectory, Environment#getExternalFilesDir, Environment#getExternalCacheDir, MediaStore, WRITE_EXTERNAL_STORAGE, MANAGE_EXTERNAL_STORAGE] type: [static] --- ## Overview -This test looks for Android manifest permissions and APIs that allow an app to write to locations that are shared with other apps. This means that a third-party app with the proper permissions may be able to access data written to these locations. Therefore, this test verifies whether an app: +This test uses static analysis to look for uses of [APIs allowing an app to write to locations that are shared with other apps](../../../../../Document/0x05d-Testing-Data-Storage.md#external-storage) such as the external storage APIs or the `MediaStore` API as well as the relevant Android manifest storage-related permissions. -- declares permissions required to write data to shared locations -- uses API to obtain location to shared locations -- uses MediaStore API - -Additionally, if the "external storage" is actually stored externally, e.g. on an SD card, it can be removed from the device and inserted into a card reader to extract sensitive data. - -### Testing Manifest permissions - -An app must declare in the Manifest file an intention to write to shared locations. Below you can find a list of such manifest permissions: - -- [WRITE_EXTERNAL_STORAGE](https://developer.android.com/reference/android/Manifest.permission#WRITE_EXTERNAL_STORAGE): allows an app to write a file to the "external storage", regardless of the actual storage origin (external disk or internally emulated by the system). - - This permission is **deprecated since Android 11.0 (API level 30)** but can be preserved with [requestLegacyExternalStorage](https://developer.android.com/reference/android/R.attr#requestLegacyExternalStorage) and [preserveLegacyExternalStorage](https://developer.android.com/reference/android/R.attr#preserveLegacyExternalStorage). - - If the app declares a minSdkVersion of 19 or higher, you don't need to declare this permission to read and write files in your application-specific directories returned by [Context.getExternalFilesDir(String)](https://developer.android.com/reference/android/content/Context#getExternalFilesDir(java.lang.String)) and [Context.getExternalCacheDir()](https://developer.android.com/reference/android/content/Context#getExternalCacheDir()). - - On Android 4.4 (API level 19) or higher, your app doesn't need to request any storage-related permissions to access app-specific directories within external storage. The files stored in these directories are removed when your app is uninstalled. See . - - On devices that run Android 9 (API level 28) or lower, your app can access the app-specific files that belong to other apps, provided that your app has the appropriate storage permissions. To give users more control over their files and to limit file clutter, apps that target Android 10 (API level 29) and higher are given scoped access into external storage, or [scoped storage](https://developer.android.com/training/data-storage#scoped-storage), by default. When scoped storage is enabled, apps cannot access the app-specific directories that belong to other apps. -- [MANAGE_EXTERNAL_STORAGE](https://developer.android.com/reference/android/Manifest.permission#MANAGE_EXTERNAL_STORAGE): a successor permission of `WRITE_EXTERNAL_STORAGE`. It allows an an app to read and write files to shared locations special app access called ["All files access"](https://developer.android.com/preview/privacy/storage#all-files-access). This permission only applies to apps target Android 11.0 (API level 30) and its usage is restricted by Google Play unless the app satisfies [certain requirements](https://support.google.com/googleplay/android-developer/answer/10467955). - -### Testing External Storage APIs - -There are APIs such as [`getExternalStoragePublicDirectory`](https://developer.android.com/reference/kotlin/android/os/Environment#getExternalStoragePublicDirectory(kotlin.String)) that return paths to a shared location that other apps can access. [Demo 1](demo-1/demo.md) illustrates a case where an app obtains a path to an "external" location and writes sensitive data to it. This location is Shared Storage Requiring No User Interaction, so a third-party app with proper permissions can read this sensitive data. - -#### External app-specific files - -A malicious app with proper permissions running on Android 10 or below can access data that you write to "external" [app-specific-directories](https://developer.android.com/training/data-storage/app-specific). - -### Testing MediaStore API - -If your app stores data with MediaStore API, a third-party app with proper permissions may read this data. +This static test is great for identifying all code locations where the app is writing data to shared storage. However, it does not provide the actual data being written, and in some cases, the actual path in the device storage where the data is being written. Therefore, it is recommended to combine this test with others that take a dynamic approach, as this will provide a more complete view of the data being written to shared storage. ## Steps -1. Run a [static analysis](../../../../../techniques/android/MASTG-TECH-0014.md) tool on the app to find if it uses storage locations shared with other apps, and identify the calls to those APIs and the relevant permissions. +1. Run a [static analysis](../../../../../techniques/android/MASTG-TECH-0014.md) tool on the reverse engineered app calls to any external storage APIs and Android manifest storage permissions. ## Observation -The output should contain a list of permissions and locations where paths to external storage are returned. +The output should contain a list of APIs and storage-related permissions used to write to shared storage and their code locations. ## Evaluation -Inspect app's source code using the provided information. The test case fails if you find code that writes sensitive unencrypted to these locations. +Inspect the app's Android manifest and reverse engineered code using the information provided. + +The test case fails if: + +- the app has the proper permissions declared in the Android manifest (e.g. `WRITE_EXTERNAL_STORAGE`, `MANAGE_EXTERNAL_STORAGE`, etc.) +- **and** the data being written to shared storage is sensitive and not encrypted. + +To determine the latter, you may need to carefully review the reversed code and/or combine this test with others that take a dynamic approach, as this will provide a more complete view of the data being written to shared storage. ## References From 247a928f66b6a27a228035217c29e3f94b6599c4 Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Fri, 21 Jun 2024 12:22:30 +0200 Subject: [PATCH 25/33] Consolidated tests sections and linked to relevant techniques. --- .../test.md | 17 ++++++++--------- .../test.md | 4 ++-- .../test.md | 5 +++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md index a16eba3f39..7f2d896b12 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md @@ -6,19 +6,16 @@ type: [dynamic] ## Overview -The goal of this test is to simply retrieve the files and inspect them regardless of the APIs used to write them. Therefore, we'll use a simple approach that consists of getting the list of all files in the shared and external storage before and after the app is exercised, and then comparing them, as this may reveal sensitive files that were unintentionally stored. +The goal of this test is to retrieve the files written to the external storage and inspect them regardless of the APIs used to write them. It uses a simple approach based on [file retrieval from the device storage](../../../../../techniques/android/MASTG-TECH-0002.md) before and after the app is exercised to identify the files created during the app's execution and to check if they contain sensitive data. ## Steps -1. Make sure you have ADB installed. - -2. Install the app. - -3. Execute `run_before.sh` before opening the app to mark the timestamp. - +1. Make sure you have [adb](../../../../../tools/android/MASTG-TOOL-0004.md) installed. +2. [Install the app](../../../../../techniques/android/MASTG-TECH-0005.md). +3. Before running the app, [get the current list of files](../../../../../techniques/android/MASTG-TECH-0002.md) in the external storage. 4. Exercise the app. - -5. Execute `run_after.sh` to list all the files created by the app in the external storage. +5. After running the app, retrieve the list of files in the external storage again. +6. Calculate the difference between the two lists. ## Observation @@ -27,3 +24,5 @@ The **output** contains a list of files that were created during the excersising ## Evaluation The test case fails if the files found above are not encrypted and leak sensitive data. + +To confirm this, you can [reverse engineer the app](../../../../../techniques/android/MASTG-TECH-0017.md) and [inspect the code](../../../../../techniques/android/MASTG-TECH-0023.md). diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md index ad728cbf3e..ef3caa054b 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md @@ -7,7 +7,7 @@ type: [dynamic] ## Overview -Android apps use a variety of APIs to obtain a file path and store a file. Collecting a comprehensive list of these APIs can be challenging, especially if an app uses a third-party framework, loads code at runtime, or includes native code. The most effective approach to testing applications that write to device storage is usually dynamic analysis, and specifically method tracing. +Android apps use a variety of APIs to obtain a file path and store a file. Collecting a comprehensive list of these APIs can be challenging, especially if an app uses a third-party framework, loads code at runtime, or includes native code. The most effective approach to testing applications that write to device storage is usually dynamic analysis, and specifically [method tracing](../../../../../techniques/android/MASTG-TECH-0033.md). ## Steps @@ -29,4 +29,4 @@ The **method trace output** contains a list of file locations that your app inte The test case fails if the files found above are not encrypted and leak sensitive data. -You can inspect those files manually using [adb shell](https://mas.owasp.org/MASTG/techniques/android/MASTG-TECH-0002/) to retrieve them from the device. +To confirm this, you can manually inspect the files using [adb shell](https://mas.owasp.org/MASTG/techniques/android/MASTG-TECH-0002/) to retrieve them from the device, and [reverse engineer the app](../../../../../techniques/android/MASTG-TECH-0017.md) and [inspect the code](../../../../../techniques/android/MASTG-TECH-0023.md). diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md index 1a48c9d3ea..e756ce783a 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md @@ -13,7 +13,8 @@ This static test is great for identifying all code locations where the app is wr ## Steps -1. Run a [static analysis](../../../../../techniques/android/MASTG-TECH-0014.md) tool on the reverse engineered app calls to any external storage APIs and Android manifest storage permissions. +1. [Reverse engineer the app](../../../../../techniques/android/MASTG-TECH-0017.md). +2. Run a [static analysis](../../../../../techniques/android/MASTG-TECH-0014.md) tool on the reverse engineered app targeting calls to any external storage APIs and Android manifest storage permissions. ## Observation @@ -28,7 +29,7 @@ The test case fails if: - the app has the proper permissions declared in the Android manifest (e.g. `WRITE_EXTERNAL_STORAGE`, `MANAGE_EXTERNAL_STORAGE`, etc.) - **and** the data being written to shared storage is sensitive and not encrypted. -To determine the latter, you may need to carefully review the reversed code and/or combine this test with others that take a dynamic approach, as this will provide a more complete view of the data being written to shared storage. +To determine the latter, you may need to carefully [review the reversed code](../../../../../techniques/android/MASTG-TECH-0023.md) and/or combine this test with others that take a dynamic approach, as this will provide a more complete view of the data being written to shared storage. ## References From 858b4bdf24186138da2bf81f28591bbdec08b986 Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Fri, 21 Jun 2024 12:51:09 +0200 Subject: [PATCH 26/33] Consolidated demos sections and titles. Added more details to the observation in android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/demo.md --- .../demo-1/demo.md | 28 +++++++++++++------ .../demo-1/demo.md | 27 +++++++++++++----- .../demo-1/demo.md | 10 +++++-- .../demo-2/demo.md | 10 +++++-- .../demo-3/demo.md | 13 +++++---- 5 files changed, 61 insertions(+), 27 deletions(-) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md index 50cbb5d0cd..bf0c4ea45e 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md @@ -1,32 +1,42 @@ --- platform: android -title: Listing files inside External Storage +title: File System Snapshots from External Storage tools: [adb] code: [kotlin] --- ### Sample -The snippet below shows sample code that creates a file in external storage. +The snippet below shows sample code that creates two files in the external storage using the `getExternalFilesDir` method and the `MediaStore` API. {{ MastgTest.kt }} ### Steps -1. Install an app on your device -2. Execute `run_before.sh` -3. Open an app and exercise it to trigger file creations -4. Execute `run_after.sh` -5. Close the app once you finish testing +1. Install an app on your device. +2. Execute `run_before.sh`. +3. Open an app and exercise it to trigger file creations. +4. Execute `run_after.sh`. +5. Close the app once you finish testing. {{ run.sh }} ### Observation -There is a list of all created files inside `output.txt`. Their content is inside the `./new_files/` directory. +There is a list of all created files inside `output.txt`. {{ output.txt }} +Their content is inside the `./new_files/` directory and contains: + +A password: + +{{ secret.txt }} + +And an API key: + +{{ secretFile75.txt }} + ### Evaluation -This test fails because the file contains a secretFile.txt. +This test fails because the files are not encrypted and contain sensitive data (a password and an API key). You can further confirm this by reverse engineering the app and inspecting the code. diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/demo.md index 3be4148a47..f8ae6ccaf6 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/demo.md @@ -1,30 +1,43 @@ --- platform: android -title: File Tracing with Frida +title: External Storage APIs Tracing with Frida tools: [frida] code: [kotlin] --- ### Sample -The snippet below shows sample code that creates a file in external storage. +The snippet below shows sample code that creates two files in the external storage using the `getExternalFilesDir` method and the `MediaStore` API. {{ MastgTest.kt }} ### Steps -1. Update the Package ID of your app inside `run.sh` -2. Execute `run.sh` against the sample app to trace all usage of file IO. -3. Close the app once you finish testing +1. Ensure the app is running on the target device. +2. Execute `run.sh`. +3. Close the app once you finish testing. + +The `run.sh` script will inject a Frida script called `script.js`. {{ run.sh }} +The Frida script will hook and log calls to `open` and `android.content.ContentResolver.insert`. + +{{ script.js }} + ### Observation -There is only one file written to the external storage - `/storage/emulated/0/Android/data/org.owasp.mastestapp/files/secret.json`. +In the output you can see the paths and the relevant stack trace which helps to identify the actual APIs used to write to external storage and their respective callers. {{ output.txt }} +There are two files written to the external storage: + +- `/storage/emulated/0/Android/data/org.owasp.mastestapp/files/secret.txt` written using `java.io.FileOutputStream` from `org.owasp.mastestapp.MastgTest.mastgTestApi(MastgTest.kt:26)` +- `content://media/external/downloads/27` written using `android.content.ContentResolver.insert` from `org.owasp.mastestapp.MastgTest.mastgTestMediaStore(MastgTest.kt:44)` + +Note that the calls via `ContentResolver.insert` do not write directly to the file system, but to the `MediaStore` content provider, and therefore we can't see the actual file path, instead we see the `content://` URI. + ### Evaluation -This test fails since the file contains a password. +This test fails because the files are not encrypted and contain sensitive data (a password and an API key). You can further confirm this by reverse engineering the app and inspecting the code as well as retrieving the files from the device. diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md index 47ee611981..912b85886a 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md @@ -1,17 +1,21 @@ --- platform: android -title: Find common APIs that return paths to Public External Storage locations +title: App Writing to External Storage without Scoped Storage Restrictions tools: [semgrep] code: [kotlin, xml] --- ### Sample -The snippet below shows sample code that creates a file in external storage. +The snippet below shows sample code that creates a file in external storage without using scoped storage APIs. The `getExternalStorageDirectory` API returns a path to the root of the shared external storage (e.g. `/storage/emulated/0`). + +{{ MastgTest.kt }} {{ MastgTest_reversed.java }} -This requires special app access called ["All files access"](https://developer.android.com/preview/privacy/storage#all-files-access), so the following permission must be declared in the manifest file. +This requires special app access called ["All files access"](https://developer.android.com/preview/privacy/storage#all-files-access), so the `MANAGE_EXTERNAL_STORAGE` permission must be declared in the manifest file. + +{{ AndroidManifest.xml }} {{ AndroidManifest_reversed.xml }} diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md index a604051df6..deb8e985d8 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md @@ -1,12 +1,16 @@ --- platform: android -title: Find common APIs that return paths to Scoped External Storage locations +title: App Writing to External Storage with Scoped Storage Restrictions tools: [semgrep] code: [kotlin] --- ### Sample +The snippet below shows sample code that creates a file in external storage using the `getExternalFilesDir` API which returns a path to the app's external files directory (e.g. `/storage/emulated/0/Android/data/org.owasp.mastestapp/files`) and does not require any permissions to access. Scoped storage applies since the app targets Android 12 (API level 31) which is higher than Android 10 (API level 29). + +{{ MastgTest.kt }} + {{ MastgTest_reversed.java }} ### Steps @@ -19,10 +23,10 @@ Let's run our semgrep rule against the reversed java code. ### Observation -The rule has identified one location in the code file where a path to scoped external storage is returned. +The rule has identified one location in the code file where an API, `getExternalFilesDir`, is used to write to external storage with scoped storage restrictions. {{ output.txt }} ### Evaluation -Review the decompiled code at the location specified in the output (file and line number). This test fails because the file written by this instance contains sensitive data, specifically a password. +After reviewing the decompiled code at the location specified in the output (file and line number) we can conclude that the test fails because the file written by this instance contains sensitive data, specifically a password. diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md index 76db5ce2ca..8217102233 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md @@ -1,12 +1,16 @@ --- platform: android -title: Find MediaStore APIs that writes data to locations shared with other apps +title: App Writing to External Storage via the MediaStore API tools: [semgrep] code: [kotlin] --- ### Sample +The snippet below shows sample code that uses the `MediaStore` API to write a file to shared storage in a path like `/storage/emulated/0/Download/` which does not require any permissions to access and is shared with other apps. + +{{ MastgTest.kt }} + {{ MastgTest_reversed.java }} ### Steps @@ -23,9 +27,8 @@ The rule has identified 2 locations that indicate a use of MediaStore API. {{ output.txt }} -### Evaluation +The first location is the import statement for the `MediaStore` API and the second location is where the `MediaStore` API is used to write to shared storage. -Review the reported instances and make sure to either: +### Evaluation -- confirm you intended to make this data public -- store this data in a more strict storage type +After reviewing the decompiled code at the locations specified in the output (file and line number) we can conclude that the test fails because the file written by this instance contains sensitive data, specifically a API key. From 81610ae6507f16b8b2ae58894c6fb7c1e2eaccc6 Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Fri, 21 Jun 2024 12:53:41 +0200 Subject: [PATCH 27/33] Remove SARIF support for now --- .../demo-1/output.sarif | 116 -------------- .../demo-1/output2.sarif | 74 --------- .../demo-1/run.sh | 2 - .../demo-2/output.sarif | 116 -------------- .../demo-2/run.sh | 1 - .../demo-3/output.sarif | 145 ------------------ .../demo-3/run.sh | 1 - 7 files changed, 455 deletions(-) delete mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif delete mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output2.sarif delete mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif delete mode 100644 risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif deleted file mode 100644 index 032f8270c3..0000000000 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.sarif +++ /dev/null @@ -1,116 +0,0 @@ -{ - "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json", - "runs": [ - { - "invocations": [ - { - "executionSuccessful": true, - "toolExecutionNotifications": [] - } - ], - "results": [ - { - "fingerprints": { - "matchBasedId/v1": "08d14b1ca14fd823ee947dd5068ba82e1185bb48d76fa44a2f2f14193c45ab9975bc8bf4e1af53120204c6c3b7edfda9d6ef9a04bc14e600baa636dfeebfb62d_0" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "MastgTest_reversed.java", - "uriBaseId": "%SRCROOT%" - }, - "region": { - "endColumn": 76, - "endLine": 27, - "snippet": { - "text": " File externalStorageDir = Environment.getExternalStorageDirectory();" - }, - "startColumn": 35, - "startLine": 27 - } - } - } - ], - "message": { - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" - }, - "properties": {}, - "ruleId": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public" - } - ], - "tool": { - "driver": { - "name": "Semgrep OSS", - "rules": [ - { - "defaultConfiguration": { - "level": "warning" - }, - "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" - }, - "help": { - "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" - }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", - "properties": { - "precision": "very-high", - "tags": [] - }, - "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" - } - }, - { - "defaultConfiguration": { - "level": "warning" - }, - "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" - }, - "help": { - "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" - }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public", - "properties": { - "precision": "very-high", - "tags": [] - }, - "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public" - } - }, - { - "defaultConfiguration": { - "level": "warning" - }, - "fullDescription": { - "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" - }, - "help": { - "markdown": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions", - "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" - }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped", - "properties": { - "precision": "very-high", - "tags": [] - }, - "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped" - } - } - ], - "semanticVersion": "1.56.0" - } - } - } - ], - "version": "2.1.0" -} \ No newline at end of file diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output2.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output2.sarif deleted file mode 100644 index abb5409f0e..0000000000 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output2.sarif +++ /dev/null @@ -1,74 +0,0 @@ -{ - "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json", - "runs": [ - { - "invocations": [ - { - "executionSuccessful": true, - "toolExecutionNotifications": [] - } - ], - "results": [ - { - "fingerprints": { - "matchBasedId/v1": "4f4da620f6961a9f5dc3861a6ead2be3dac9f043e8beff0c84200108663f19c8083459d308024a924a78f3301bb886eaac9699eee70be6a890110bca7aec4267_0" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "AndroidManifest_reversed.xml", - "uriBaseId": "%SRCROOT%" - }, - "region": { - "endColumn": 78, - "endLine": 2, - "snippet": { - "text": " " - }, - "startColumn": 55, - "startLine": 2 - } - } - } - ], - "message": { - "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" - }, - "properties": {}, - "ruleId": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest" - } - ], - "tool": { - "driver": { - "name": "Semgrep OSS", - "rules": [ - { - "defaultConfiguration": { - "level": "warning" - }, - "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" - }, - "help": { - "markdown": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary", - "text": "[MASVS-STORAGE] Make sure to encrypt files in external storage if necessary" - }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest", - "properties": { - "precision": "very-high", - "tags": [] - }, - "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest" - } - } - ], - "semanticVersion": "1.56.0" - } - } - } - ], - "version": "2.1.0" -} \ No newline at end of file diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh index 76f29308aa..195acb814a 100755 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh @@ -1,5 +1,3 @@ NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml ./MastgTest_reversed.java --text -o output.txt -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml ./MastgTest_reversed.java --sarif -o output.sarif NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest.yml ./AndroidManifest_reversed.xml --text -o output2.txt -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest.yml ./AndroidManifest_reversed.xml --sarif -o output2.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif deleted file mode 100644 index f8aa61a357..0000000000 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.sarif +++ /dev/null @@ -1,116 +0,0 @@ -{ - "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json", - "runs": [ - { - "invocations": [ - { - "executionSuccessful": true, - "toolExecutionNotifications": [] - } - ], - "results": [ - { - "fingerprints": { - "matchBasedId/v1": "4f302b675b47e4b5cc507cc6322f5cfe3fd8bbedb85aa283764d89b22cccc004539df972ea0c655da7f55bbdafc75ddd47c08ce605d0dee0f02bff04d3d3aa66_0" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "MastgTest_reversed.java", - "uriBaseId": "%SRCROOT%" - }, - "region": { - "endColumn": 73, - "endLine": 25, - "snippet": { - "text": " File externalStorageDir = this.context.getExternalFilesDir(null);" - }, - "startColumn": 35, - "startLine": 25 - } - } - } - ], - "message": { - "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" - }, - "properties": {}, - "ruleId": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped" - } - ], - "tool": { - "driver": { - "name": "Semgrep OSS", - "rules": [ - { - "defaultConfiguration": { - "level": "warning" - }, - "fullDescription": { - "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" - }, - "help": { - "markdown": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions", - "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" - }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped", - "properties": { - "precision": "very-high", - "tags": [] - }, - "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped" - } - }, - { - "defaultConfiguration": { - "level": "warning" - }, - "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" - }, - "help": { - "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" - }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public", - "properties": { - "precision": "very-high", - "tags": [] - }, - "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public" - } - }, - { - "defaultConfiguration": { - "level": "warning" - }, - "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" - }, - "help": { - "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" - }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", - "properties": { - "precision": "very-high", - "tags": [] - }, - "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" - } - } - ], - "semanticVersion": "1.56.0" - } - } - } - ], - "version": "2.1.0" -} \ No newline at end of file diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh index e8aa8fc78e..be9f7283bf 100755 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh @@ -1,2 +1 @@ NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml ./MastgTest_reversed.java --text -o output.txt -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml ./MastgTest_reversed.java --sarif -o output.sarif diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.sarif b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.sarif deleted file mode 100644 index 4e4124efd6..0000000000 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.sarif +++ /dev/null @@ -1,145 +0,0 @@ -{ - "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json", - "runs": [ - { - "invocations": [ - { - "executionSuccessful": true, - "toolExecutionNotifications": [] - } - ], - "results": [ - { - "fingerprints": { - "matchBasedId/v1": "c36527e4d1432461d345286b77b11e18d4bc76ece67d3e5392ab76eb4976bab00649247144e1944dae61e29e3582016beff405e036a93eb2201c817f616b0693_0" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "MastgTest_reversed.java", - "uriBaseId": "%SRCROOT%" - }, - "region": { - "endColumn": 35, - "endLine": 8, - "snippet": { - "text": "import android.provider.MediaStore;" - }, - "startColumn": 1, - "startLine": 8 - } - } - } - ], - "message": { - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" - }, - "properties": {}, - "ruleId": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" - }, - { - "fingerprints": { - "matchBasedId/v1": "b1be13cd80a4d0596fe97464b74b86cac6feaf5f27d3a7a077ec36ba3faf862f95d0b1d7f41c5c67693c97d1dfb0c25cec088009dc5513b07af76f0fec1b1c1d_0" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "MastgTest_reversed.java", - "uriBaseId": "%SRCROOT%" - }, - "region": { - "endColumn": 53, - "endLine": 35, - "snippet": { - "text": " Uri textUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);" - }, - "startColumn": 43, - "startLine": 35 - } - } - } - ], - "message": { - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" - }, - "properties": {}, - "ruleId": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" - } - ], - "tool": { - "driver": { - "name": "Semgrep OSS", - "rules": [ - { - "defaultConfiguration": { - "level": "warning" - }, - "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" - }, - "help": { - "markdown": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary", - "text": "[MASVS-STORAGE] Make sure to encrypt files at these locations if necessary" - }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public", - "properties": { - "precision": "very-high", - "tags": [] - }, - "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public" - } - }, - { - "defaultConfiguration": { - "level": "warning" - }, - "fullDescription": { - "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" - }, - "help": { - "markdown": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions", - "text": "[MASVS-STORAGE] These locations might be accessible to other apps on Android 10 and below given relevant permissions" - }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped", - "properties": { - "precision": "very-high", - "tags": [] - }, - "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-scoped" - } - }, - { - "defaultConfiguration": { - "level": "warning" - }, - "fullDescription": { - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" - }, - "help": { - "markdown": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps", - "text": "[MASVS-STORAGE] Make sure to want this data to be shared with other apps" - }, - "id": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", - "name": "rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore", - "properties": { - "precision": "very-high", - "tags": [] - }, - "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-mediastore" - } - } - ], - "semanticVersion": "1.56.0" - } - } - } - ], - "version": "2.1.0" -} \ No newline at end of file diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/run.sh b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/run.sh index e8aa8fc78e..be9f7283bf 100755 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/run.sh +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/run.sh @@ -1,2 +1 @@ NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml ./MastgTest_reversed.java --text -o output.txt -NO_COLOR=true semgrep -c ../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml ./MastgTest_reversed.java --sarif -o output.sarif From 7f4809c4dcaa758b5b825ede1efc9ede0c32b339 Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Sun, 23 Jun 2024 19:49:14 +0200 Subject: [PATCH 28/33] fix paths to snippets --- .../demo-1/demo.md | 6 +++--- .../demo-1/demo.md | 16 +++------------- .../demo-2/demo.md | 4 +--- .../demo-3/demo.md | 4 +--- 4 files changed, 8 insertions(+), 22 deletions(-) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md index bf0c4ea45e..495e0fd00f 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md @@ -19,7 +19,7 @@ The snippet below shows sample code that creates two files in the external stora 4. Execute `run_after.sh`. 5. Close the app once you finish testing. -{{ run.sh }} +{{ run_before.sh # run_after.sh }} ### Observation @@ -31,11 +31,11 @@ Their content is inside the `./new_files/` directory and contains: A password: -{{ secret.txt }} +{{ new_files/secret.txt }} And an API key: -{{ secretFile75.txt }} +{{ new_files/secretFile75.txt }} ### Evaluation diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md index 912b85886a..e238674041 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md @@ -9,15 +9,9 @@ code: [kotlin, xml] The snippet below shows sample code that creates a file in external storage without using scoped storage APIs. The `getExternalStorageDirectory` API returns a path to the root of the shared external storage (e.g. `/storage/emulated/0`). -{{ MastgTest.kt }} - -{{ MastgTest_reversed.java }} - This requires special app access called ["All files access"](https://developer.android.com/preview/privacy/storage#all-files-access), so the `MANAGE_EXTERNAL_STORAGE` permission must be declared in the manifest file. -{{ AndroidManifest.xml }} - -{{ AndroidManifest_reversed.xml }} +{{ MastgTest.kt # MastgTest_reversed.java # AndroidManifest.xml # AndroidManifest_reversed.xml }} ### Steps @@ -33,13 +27,9 @@ And another one against the sample manifest file. ### Observation -The rule has identified one location in the code file where an API, `getExternalStorageDirectory`, is used to write to external storage. - -{{ output.txt }} - -The rule has also identified that the manifest file declares `MANAGE_EXTERNAL_STORAGE` permission. +The rule has identified one location in the code file where an API, `getExternalStorageDirectory`, is used to write to external storage as well as the location in the manifest file where the `MANAGE_EXTERNAL_STORAGE` permission is declared. -{{ output2.txt }} +{{ output.txt # output2.txt }} ### Evaluation diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md index deb8e985d8..01221bd983 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md @@ -9,9 +9,7 @@ code: [kotlin] The snippet below shows sample code that creates a file in external storage using the `getExternalFilesDir` API which returns a path to the app's external files directory (e.g. `/storage/emulated/0/Android/data/org.owasp.mastestapp/files`) and does not require any permissions to access. Scoped storage applies since the app targets Android 12 (API level 31) which is higher than Android 10 (API level 29). -{{ MastgTest.kt }} - -{{ MastgTest_reversed.java }} +{{ MastgTest.kt # MastgTest_reversed.java }} ### Steps diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md index 8217102233..a0847025f8 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md @@ -9,9 +9,7 @@ code: [kotlin] The snippet below shows sample code that uses the `MediaStore` API to write a file to shared storage in a path like `/storage/emulated/0/Download/` which does not require any permissions to access and is shared with other apps. -{{ MastgTest.kt }} - -{{ MastgTest_reversed.java }} +{{ MastgTest.kt # MastgTest_reversed.java }} ### Steps From dff1834124511b1622f5ba1fe2bbabd32bbe1165 Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Mon, 24 Jun 2024 09:59:45 +0200 Subject: [PATCH 29/33] added one CWE and android risk maaping, some additional clarifications and some minor fixes for consistency in test files --- .../test.md | 2 +- .../test.md | 10 ++++------ .../test.md | 4 ++-- .../risk.md | 2 ++ 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md index 7f2d896b12..b8b40b3dc7 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md @@ -19,7 +19,7 @@ The goal of this test is to retrieve the files written to the external storage a ## Observation -The **output** contains a list of files that were created during the excersising the app. +The output should contain a list of files that were created on the external storage during the app's execution. ## Evaluation diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md index ef3caa054b..ea980c0765 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md @@ -1,7 +1,7 @@ --- platform: android title: Runtime Use of APIs to Access External Storage -apis: [Environment#getExternalStorageDirectory, Environment#getExternalStorageDirectory, Environment#getExternalFilesDir, Environment#getExternalCacheDir, FileOutPutStream] +apis: [Environment#getExternalStorageDirectory, Environment#getExternalStorageDirectory, Environment#getExternalFilesDir, Environment#getExternalCacheDir, FileOutputStream] type: [dynamic] --- @@ -12,18 +12,16 @@ Android apps use a variety of APIs to obtain a file path and store a file. Colle ## Steps 1. Make sure you have Frida installed. - 2. Install the app. - 3. Execute a `run.sh` to spawn an app with Frida and log all interactions with files. - 4. Navigate to the screen of the mobile app that you want to analyse. - 5. Close the app to stop Frida. +The Frida script should log all file interactions by hooking into the relevant APIs such as `getExternalStorageDirectory`, `getExternalStoragePublicDirectory`, `getExternalFilesDir` or `FileOutPutStream`. You could also use `open` as a catch-all for file interactions. However, this won't catch all file interactions, such as those that use the `MediaStore` API and should be done with additional filtering as it can generate a lot of noise. + ## Observation -The **method trace output** contains a list of file locations that your app interacts with. +The output should contain a list of files that the app wrote to the external storage during execution and, if possible, the APIs used to write them. ## Evaluation diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md index e756ce783a..6d754974e7 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md @@ -16,14 +16,14 @@ This static test is great for identifying all code locations where the app is wr 1. [Reverse engineer the app](../../../../../techniques/android/MASTG-TECH-0017.md). 2. Run a [static analysis](../../../../../techniques/android/MASTG-TECH-0014.md) tool on the reverse engineered app targeting calls to any external storage APIs and Android manifest storage permissions. +The static analysis tool should be able to identify all possible APIs and permissions used to write to shared storage, such as `getExternalStoragePublicDirectory`, `getExternalStorageDirectory`, `getExternalFilesDir`, `MediaStore`, `WRITE_EXTERNAL_STORAGE`, and `MANAGE_EXTERNAL_STORAGE`. See the [Android documentation](https://developer.android.com/training/data-storage/shared) for more information on these APIs and permissions. + ## Observation The output should contain a list of APIs and storage-related permissions used to write to shared storage and their code locations. ## Evaluation -Inspect the app's Android manifest and reverse engineered code using the information provided. - The test case fails if: - the app has the proper permissions declared in the Android manifest (e.g. `WRITE_EXTERNAL_STORAGE`, `MANAGE_EXTERNAL_STORAGE`, etc.) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/risk.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/risk.md index fba68f3b01..d4a6aae1f7 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/risk.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/risk.md @@ -7,6 +7,8 @@ mappings: masvs-v1: [MSTG-STORAGE-2] masvs-v2: [MASVS-STORAGE-1] mastg-v1: [MASTG-TEST-0052, MASTG-TEST-0001] + cwe: [311] + android: https://developer.android.com/privacy-and-security/risks/sensitive-data-external-storage --- From d61e8672d29e81e4abd854b6297c874692aed755 Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Mon, 24 Jun 2024 11:14:07 +0200 Subject: [PATCH 30/33] fix links to tools and tech --- .../test.md | 10 +++++----- .../test.md | 4 ++-- .../test.md | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md index b8b40b3dc7..b9f55b9178 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md @@ -6,13 +6,13 @@ type: [dynamic] ## Overview -The goal of this test is to retrieve the files written to the external storage and inspect them regardless of the APIs used to write them. It uses a simple approach based on [file retrieval from the device storage](../../../../../techniques/android/MASTG-TECH-0002.md) before and after the app is exercised to identify the files created during the app's execution and to check if they contain sensitive data. +The goal of this test is to retrieve the files written to the external storage and inspect them regardless of the APIs used to write them. It uses a simple approach based on [file retrieval from the device storage](/MASTG/techniques/android/MASTG-TECH-0002) before and after the app is exercised to identify the files created during the app's execution and to check if they contain sensitive data. ## Steps -1. Make sure you have [adb](../../../../../tools/android/MASTG-TOOL-0004.md) installed. -2. [Install the app](../../../../../techniques/android/MASTG-TECH-0005.md). -3. Before running the app, [get the current list of files](../../../../../techniques/android/MASTG-TECH-0002.md) in the external storage. +1. Make sure you have [adb](/MASTG/tools/android/MASTG-TOOL-0004) installed. +2. [Install the app](/MASTG/techniques/android/MASTG-TECH-0005). +3. Before running the app, [get the current list of files](/MASTG/techniques/android/MASTG-TECH-0002) in the external storage. 4. Exercise the app. 5. After running the app, retrieve the list of files in the external storage again. 6. Calculate the difference between the two lists. @@ -25,4 +25,4 @@ The output should contain a list of files that were created on the external stor The test case fails if the files found above are not encrypted and leak sensitive data. -To confirm this, you can [reverse engineer the app](../../../../../techniques/android/MASTG-TECH-0017.md) and [inspect the code](../../../../../techniques/android/MASTG-TECH-0023.md). +To confirm this, you can [reverse engineer the app](/MASTG/techniques/android/MASTG-TECH-0017) and [inspect the code](/MASTG/techniques/android/MASTG-TECH-0023). diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md index ea980c0765..2f75b7b464 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md @@ -7,7 +7,7 @@ type: [dynamic] ## Overview -Android apps use a variety of APIs to obtain a file path and store a file. Collecting a comprehensive list of these APIs can be challenging, especially if an app uses a third-party framework, loads code at runtime, or includes native code. The most effective approach to testing applications that write to device storage is usually dynamic analysis, and specifically [method tracing](../../../../../techniques/android/MASTG-TECH-0033.md). +Android apps use a variety of APIs to obtain a file path and store a file. Collecting a comprehensive list of these APIs can be challenging, especially if an app uses a third-party framework, loads code at runtime, or includes native code. The most effective approach to testing applications that write to device storage is usually dynamic analysis, and specifically [method tracing](/MASTG/techniques/android/MASTG-TECH-0033). ## Steps @@ -27,4 +27,4 @@ The output should contain a list of files that the app wrote to the external sto The test case fails if the files found above are not encrypted and leak sensitive data. -To confirm this, you can manually inspect the files using [adb shell](https://mas.owasp.org/MASTG/techniques/android/MASTG-TECH-0002/) to retrieve them from the device, and [reverse engineer the app](../../../../../techniques/android/MASTG-TECH-0017.md) and [inspect the code](../../../../../techniques/android/MASTG-TECH-0023.md). +To confirm this, you can manually inspect the files using [adb shell](https://mas.owasp.org/MASTG/techniques/android/MASTG-TECH-0002/) to retrieve them from the device, and [reverse engineer the app](/MASTG/techniques/android/MASTG-TECH-0017) and [inspect the code](/MASTG/techniques/android/MASTG-TECH-0023). diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md index 6d754974e7..36d36e19d2 100644 --- a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md +++ b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md @@ -13,8 +13,8 @@ This static test is great for identifying all code locations where the app is wr ## Steps -1. [Reverse engineer the app](../../../../../techniques/android/MASTG-TECH-0017.md). -2. Run a [static analysis](../../../../../techniques/android/MASTG-TECH-0014.md) tool on the reverse engineered app targeting calls to any external storage APIs and Android manifest storage permissions. +1. [Reverse engineer the app](/MASTG/techniques/android/MASTG-TECH-0017). +2. Run a [static analysis](/MASTG/techniques/android/MASTG-TECH-0014) tool on the reverse engineered app targeting calls to any external storage APIs and Android manifest storage permissions. The static analysis tool should be able to identify all possible APIs and permissions used to write to shared storage, such as `getExternalStoragePublicDirectory`, `getExternalStorageDirectory`, `getExternalFilesDir`, `MediaStore`, `WRITE_EXTERNAL_STORAGE`, and `MANAGE_EXTERNAL_STORAGE`. See the [Android documentation](https://developer.android.com/training/data-storage/shared) for more information on these APIs and permissions. @@ -29,7 +29,7 @@ The test case fails if: - the app has the proper permissions declared in the Android manifest (e.g. `WRITE_EXTERNAL_STORAGE`, `MANAGE_EXTERNAL_STORAGE`, etc.) - **and** the data being written to shared storage is sensitive and not encrypted. -To determine the latter, you may need to carefully [review the reversed code](../../../../../techniques/android/MASTG-TECH-0023.md) and/or combine this test with others that take a dynamic approach, as this will provide a more complete view of the data being written to shared storage. +To determine the latter, you may need to carefully [review the reversed code](/MASTG/techniques/android/MASTG-TECH-0023) and/or combine this test with others that take a dynamic approach, as this will provide a more complete view of the data being written to shared storage. ## References From e373dcc60b92c648d97a735b19cb909da27a2149 Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Mon, 24 Jun 2024 15:40:15 +0200 Subject: [PATCH 31/33] rename risk to weakness --- .../{risk.md => weakness.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/{risk.md => weakness.md} (100%) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/risk.md b/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/weakness.md similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/risk.md rename to risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/weakness.md From d44da959921eb04b7b2be560a42653e12740f311 Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Mon, 24 Jun 2024 15:42:34 +0200 Subject: [PATCH 32/33] move all to the weaknesses folder --- .../demo-1/MastgTest.kt | 0 .../demo-1/demo.md | 0 .../demo-1/new_files/secret.txt | 0 .../demo-1/new_files/secretFile75.txt | 0 .../demo-1/output.txt | 0 .../demo-1/run_after.sh | 0 .../demo-1/run_before.sh | 0 .../test.md | 0 .../demo-1/MastgTest.kt | 0 .../demo-1/demo.md | 0 .../demo-1/output.txt | 0 .../demo-1/run.sh | 0 .../demo-1/script.js | 0 .../test.md | 0 .../demo-1/AndroidManifest.xml | 0 .../demo-1/AndroidManifest_reversed.xml | 0 .../demo-1/MastgTest.kt | 0 .../demo-1/MastgTest_reversed.java | 0 .../demo-1/demo.md | 0 .../demo-1/output.txt | 0 .../demo-1/output2.txt | 0 .../demo-1/run.sh | 0 .../demo-2/MastgTest.kt | 0 .../demo-2/MastgTest_reversed.java | 0 .../demo-2/demo.md | 0 .../demo-2/output.txt | 0 .../demo-2/run.sh | 0 .../demo-3/MastgTest.kt | 0 .../demo-3/MastgTest_reversed.java | 0 .../demo-3/demo.md | 0 .../demo-3/output.txt | 0 .../demo-3/run.sh | 0 ...d-data-unencrypted-shared-storage-no-user-interaction-apis.yml | 0 ...ta-unencrypted-shared-storage-no-user-interaction-manifest.yml | 0 .../test.md | 0 .../weakness.md | 0 36 files changed, 0 insertions(+), 0 deletions(-) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/MastgTest.kt (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secret.txt (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secretFile75.txt (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/output.txt (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_after.sh (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_before.sh (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/MastgTest.kt (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/demo.md (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/output.txt (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/run.sh (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/script.js (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/AndroidManifest.xml (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/AndroidManifest_reversed.xml (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest.kt (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest_reversed.java (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.txt (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output2.txt (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest.kt (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest_reversed.java (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest.kt (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest_reversed.java (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.txt (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/run.sh (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest.yml (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md (100%) rename {risks/MASVS-STORAGE/1-store-sensitive-data-securely => weaknesses/MASVS-STORAGE/1-secure-data-storage}/data-unencrypted-shared-storage-no-user-interaction/weakness.md (100%) diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/MastgTest.kt b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/MastgTest.kt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/MastgTest.kt rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/MastgTest.kt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/demo.md diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secret.txt b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secret.txt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secret.txt rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secret.txt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secretFile75.txt b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secretFile75.txt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secretFile75.txt rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/new_files/secretFile75.txt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/output.txt b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/output.txt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/output.txt rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/output.txt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_after.sh b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_after.sh similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_after.sh rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_after.sh diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_before.sh b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_before.sh similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_before.sh rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/demo-1/run_before.sh diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-file-diff/test.md diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/MastgTest.kt b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/MastgTest.kt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/MastgTest.kt rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/MastgTest.kt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/demo.md b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/demo.md similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/demo.md rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/demo.md diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/output.txt b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/output.txt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/output.txt rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/output.txt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/run.sh b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/run.sh similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/run.sh rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/run.sh diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/script.js b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/script.js similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/script.js rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/demo-1/script.js diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/AndroidManifest.xml b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/AndroidManifest.xml similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/AndroidManifest.xml rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/AndroidManifest.xml diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/AndroidManifest_reversed.xml b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/AndroidManifest_reversed.xml similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/AndroidManifest_reversed.xml rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/AndroidManifest_reversed.xml diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest.kt b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest.kt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest.kt rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest.kt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest_reversed.java b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest_reversed.java similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest_reversed.java rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/MastgTest_reversed.java diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/demo.md diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.txt b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.txt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.txt rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output.txt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output2.txt b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output2.txt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output2.txt rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/output2.txt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-1/run.sh diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest.kt b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest.kt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest.kt rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest.kt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest_reversed.java b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest_reversed.java similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest_reversed.java rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/MastgTest_reversed.java diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/demo.md diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/output.txt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-2/run.sh diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest.kt b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest.kt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest.kt rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest.kt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest_reversed.java b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest_reversed.java similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest_reversed.java rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/MastgTest_reversed.java diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/demo.md diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.txt b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.txt similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.txt rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/output.txt diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/run.sh b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/run.sh similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/run.sh rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/demo-3/run.sh diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest.yml b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest.yml similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest.yml rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest.yml diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-static/test.md diff --git a/risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/weakness.md b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/weakness.md similarity index 100% rename from risks/MASVS-STORAGE/1-store-sensitive-data-securely/data-unencrypted-shared-storage-no-user-interaction/weakness.md rename to weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/weakness.md From edeee0412b2f57a7a09268f4ff8835a6a8930138 Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Mon, 24 Jun 2024 17:21:18 +0200 Subject: [PATCH 33/33] include link to frida and remove ref to run.sh from test --- .../test.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md index 2f75b7b464..a04a23c9e3 100644 --- a/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md +++ b/weaknesses/MASVS-STORAGE/1-secure-data-storage/data-unencrypted-shared-storage-no-user-interaction/android-data-unencrypted-shared-storage-no-user-interaction-dynamic-frida/test.md @@ -11,10 +11,10 @@ Android apps use a variety of APIs to obtain a file path and store a file. Colle ## Steps -1. Make sure you have Frida installed. +1. Make sure you have [Frida](/MASTG/tools/generic/MASTG-TOOL-0031). installed. 2. Install the app. -3. Execute a `run.sh` to spawn an app with Frida and log all interactions with files. -4. Navigate to the screen of the mobile app that you want to analyse. +3. Execute a script to spawn the app with Frida and log all interactions with files. +4. Navigate to the screen of the app that you want to analyse. 5. Close the app to stop Frida. The Frida script should log all file interactions by hooking into the relevant APIs such as `getExternalStorageDirectory`, `getExternalStoragePublicDirectory`, `getExternalFilesDir` or `FileOutPutStream`. You could also use `open` as a catch-all for file interactions. However, this won't catch all file interactions, such as those that use the `MediaStore` API and should be done with additional filtering as it can generate a lot of noise.