diff --git a/Document/index.md b/Document/index.md
index 19bb81d2db..6d055ab71e 100644
--- a/Document/index.md
+++ b/Document/index.md
@@ -25,6 +25,7 @@ Start exploring the MASTG:
:material-flask-outline: Demos
:octicons-tools-24: Tools
:octicons-code-square-24: Apps
+:material-bandage: Mitigations (v2 Beta)
:blue_heart:{ .pump } Support the project by purchasing the [OWASP MASTG on leanpub.com](https://leanpub.com/owasp-mastg). All funds raised through sales of this book go directly into the project budget and will be used to for technical editing and designing the book and fund production of future releases.
diff --git a/docs/hooks/add-cross-references.py b/docs/hooks/add-cross-references.py
index 6881a2b3e0..6b1a413d5c 100644
--- a/docs/hooks/add-cross-references.py
+++ b/docs/hooks/add-cross-references.py
@@ -27,13 +27,13 @@ def gather_metadata(directory, id_key):
return metadata
def generate_cross_references():
- weaknesses = gather_metadata("MASWE", "id")
tests = gather_metadata("MASTG/tests-beta", "id")
demos = gather_metadata("MASTG/demos", "id")
cross_references = {
"weaknesses": {},
- "tests": {}
+ "tests": {},
+ "mitigations": {}
}
for test_id, test_meta in tests.items():
@@ -41,16 +41,28 @@ def generate_cross_references():
test_path = test_meta.get("path")
test_title = test_meta.get("title")
test_platform = test_meta.get("platform")
+ mitigations_ids = test_meta.get("mitigations")
+
+ # Create cross-references for weaknesses listing all tests that reference each weakness ID
if weakness_id:
if weakness_id not in cross_references["weaknesses"]:
cross_references["weaknesses"][weakness_id] = []
cross_references["weaknesses"][weakness_id].append({"id": test_id, "path": test_path, "title": test_title, "platform": test_platform})
-
+
+ # Create cross-references for mitigations listing all tests that reference each mitigation ID
+ if mitigations_ids:
+ for mitigation_id in mitigations_ids:
+ if mitigation_id not in cross_references["mitigations"]:
+ cross_references["mitigations"][mitigation_id] = []
+ cross_references["mitigations"][mitigation_id].append({"id": test_id, "path": test_path, "title": test_title, "platform": test_platform})
+
for demo_id, demo_meta in demos.items():
test_id = demo_meta.get("test")
demo_path = demo_meta.get("path")
demo_title = demo_meta.get("title")
demo_platform = demo_meta.get("platform")
+
+ # Create cross-references for tests listing all demos that reference each test ID
if test_id:
if test_id not in cross_references["tests"]:
cross_references["tests"][test_id] = []
@@ -81,6 +93,10 @@ def on_page_markdown(markdown, page, config, **kwargs):
if "MASWE-" in path:
weakness_id = meta.get('id')
+
+ # Add Tests section to weaknesses as buttons
+ # ORIGIN: Cross-references from this script
+
if weakness_id in cross_references["weaknesses"]:
tests = cross_references["weaknesses"][weakness_id]
meta['tests'] = tests
@@ -93,6 +109,10 @@ def on_page_markdown(markdown, page, config, **kwargs):
if "MASTG-TEST-" in path:
test_id = meta.get('id')
+
+ # Add Demos section to tests as buttons
+ # ORIGIN: Cross-references from this script
+
if test_id in cross_references["tests"]:
demos = cross_references["tests"][test_id]
meta['demos'] = demos
@@ -104,4 +124,34 @@ def on_page_markdown(markdown, page, config, **kwargs):
markdown += f"\n\n{demos_section}"
+ # Add Mitigations section to tests as a bullet point list with IDs, links are resolved in a separate hook
+ # ORIGIN: Test metadata
+
+ mitigations = meta.get('mitigations')
+ if mitigations:
+ mitigations_section = "## Mitigations\n\n"
+ for mitigation_id in mitigations:
+ mitigation_path = f"MASTG/mitigations/{mitigation_id}.md"
+ relPath = os.path.relpath(mitigation_path, os.path.dirname(path))
+ mitigations_section += f"- @{mitigation_id}\n"
+
+ markdown += f"\n\n{mitigations_section}"
+
+ if "MASTG-MITIG" in path:
+ mitig_id = meta.get('id')
+
+ # Add Tests section to mitigations as buttons
+ # ORIGIN: Cross-references from this script
+
+ if mitig_id in cross_references["mitigations"]:
+ mitigations = cross_references["mitigations"].get(mitig_id)
+ meta['mitigations'] = mitigations
+ if mitigations:
+ mitigations_section = "## Tests\n\n"
+ for mitigation in mitigations:
+ relPath = os.path.relpath(mitigation['path'], os.path.dirname(path))
+ mitigations_section += f"[{get_platform_icon(mitigation['platform'])} {mitigation['id']}: {mitigation['title']}]({relPath}){{: .mas-test-button}} "
+
+ markdown += f"\n\n{mitigations_section}"
+
return markdown
\ No newline at end of file
diff --git a/docs/hooks/create_dynamic_tables.py b/docs/hooks/create_dynamic_tables.py
index 431e4b6b3e..0984d3e65f 100644
--- a/docs/hooks/create_dynamic_tables.py
+++ b/docs/hooks/create_dynamic_tables.py
@@ -259,6 +259,25 @@ def get_all_demos_beta():
demos.append(frontmatter)
return demos
+def get_all_mitigations_beta():
+
+ mitigations = []
+
+ for file in glob.glob("docs/MASTG/mitigations/**/MASTG-MITIG-*.md", recursive=True):
+ with open(file, 'r') as f:
+ content = f.read()
+
+ frontmatter = next(yaml.load_all(content, Loader=yaml.FullLoader))
+
+ frontmatter['path'] = f"/MASTG/mitigations/{os.path.splitext(os.path.relpath(file, 'docs/MASTG/mitigations'))[0]}"
+ mitigation_id = frontmatter['id']
+ frontmatter['id'] = mitigation_id
+ frontmatter['title'] = f"@{mitigation_id}"
+ frontmatter['platform'] = get_platform_icon(frontmatter['platform'])
+
+ mitigations.append(frontmatter)
+ return mitigations
+
def reorder_dict_keys(original_dict, key_order):
return {key: original_dict.get(key, "N/A") for key in key_order}
@@ -303,6 +322,16 @@ def on_page_markdown(markdown, page, **kwargs):
return append_to_page(markdown, list_of_dicts_to_md_table(demos_beta_columns_reordered, column_titles))
+ elif path.endswith("mitigations/index.md"):
+ # mitigations-beta/index.md
+
+ column_titles = {'id': 'ID', 'title': 'Title', 'platform': "Platform"}
+
+ mitigations_beta = get_all_mitigations_beta()
+ mitigations_beta_columns_reordered = [reorder_dict_keys(mitigation, column_titles.keys()) for mitigation in mitigations_beta]
+
+ return append_to_page(markdown, list_of_dicts_to_md_table(mitigations_beta_columns_reordered, column_titles))
+
elif path.endswith("tools/index.md"):
# tools/index.md
diff --git a/docs/hooks/resolve_references.py b/docs/hooks/resolve_references.py
index 0210796265..d5aeef9c32 100644
--- a/docs/hooks/resolve_references.py
+++ b/docs/hooks/resolve_references.py
@@ -7,7 +7,7 @@
log = logging.getLogger('mkdocs')
-mapping = {"TECH":{}, "TOOL":{}, "TEST": {}, "APP": {}, "MASWE": {}, "MASVS": {}, "DEMO": {}}
+mapping = {"TECH":{}, "TOOL":{}, "TEST": {}, "APP": {}, "MASWE": {}, "MASVS": {}, "DEMO": {}, "MITIG": {}}
@mkdocs.plugins.event_priority(-50)
def on_page_markdown(markdown, page, config, **kwargs):
@@ -17,7 +17,7 @@ def on_page_markdown(markdown, page, config, **kwargs):
icons_for_text = {key.upper(): f":{value.replace('/', '-')}: " for key, value in icons.items()}
- pageRefs = {"TECH": [], "TOOL": [], "TEST": [], "APP": [], "MASWE": [], "MASVS": [], "DEMO": []}
+ pageRefs = {"TECH": [], "TOOL": [], "TEST": [], "APP": [], "MASWE": [], "MASVS": [], "DEMO": [], "MITIG": []}
def replaceReference(match):
refType = match.group(2)
@@ -57,7 +57,7 @@ def replaceReferenceMASVS(match):
return f"_[{icon}{mapping[refType][match]['title']}]({mapping[refType][match]['file']})_"
- updated_markdown = re.sub(r'@(MASTG-(TECH|TOOL|TEST|APP|DEMO)-\d{3,})', replaceReference, markdown)
+ updated_markdown = re.sub(r'@(MASTG-(TECH|TOOL|TEST|APP|DEMO|MITIG)-\d{3,})', replaceReference, markdown)
updated_markdown = re.sub(r'@(MASWE-\d{3,})', replaceReferenceMASWE, updated_markdown)
updated_markdown = re.sub(r'@(MASVS-\w+)', replaceReferenceMASVS, updated_markdown)
diff --git a/docs/hooks/update_titles.py b/docs/hooks/update_titles.py
index 3130c41119..06a89b6f71 100644
--- a/docs/hooks/update_titles.py
+++ b/docs/hooks/update_titles.py
@@ -13,7 +13,7 @@ def set_page_icon(page, config, component_type=None):
def on_page_markdown(markdown, page, config, **kwargs):
path = page.file.src_uri
- if any(keyword in path for keyword in ["MASTG-TEST-", "MASTG-TOOL-", "MASTG-TECH-", "MASTG-APP-", "MASTG-DEMO-"]):
+ if any(keyword in path for keyword in ["MASTG-TEST-", "MASTG-TOOL-", "MASTG-TECH-", "MASTG-APP-", "MASTG-DEMO-", "MASTG-MITIG-"]):
# TODO the component ID is the file basename without the extension; ensure that all components have id in the future
page.meta['id'] = path.split('/')[-1].split('.')[0]
component_type = page.meta['id'].split('-')[1].lower()
diff --git a/mitigations/android-use-secure-random.md b/mitigations/MASTG-MITIG-0001.md
similarity index 93%
rename from mitigations/android-use-secure-random.md
rename to mitigations/MASTG-MITIG-0001.md
index ef3f9c5367..798356f212 100644
--- a/mitigations/android-use-secure-random.md
+++ b/mitigations/MASTG-MITIG-0001.md
@@ -1,5 +1,7 @@
---
title: Use Secure Random Number Generators APIs
+alias: android-use-secure-random
+id: MASTG-MITIG-0001
platform: android
---
diff --git a/mitigations/use-proguard.md b/mitigations/MASTG-MITIG-0002.md
similarity index 89%
rename from mitigations/use-proguard.md
rename to mitigations/MASTG-MITIG-0002.md
index 992b0bccab..0896119abd 100644
--- a/mitigations/use-proguard.md
+++ b/mitigations/MASTG-MITIG-0002.md
@@ -1,8 +1,14 @@
---
-title: Use ProGuard to Remove Logging Code
+title: Remove Logging Code
+alias: remove-logging-code
+id: MASTG-MITIG-0002
platform: android
---
+Ideally, a release build shouldn't use any logging functions, making it easier to assess sensitive data exposure.
+
+## Using ProGuard
+
While preparing the production release, you can use tools like @MASTG-TOOL-0022 (included in Android Studio). To determine whether all logging functions from the `android.util.Log` class have been removed, check the ProGuard configuration file (proguard-rules.pro) for the following options (according to this [example of removing logging code](https://www.guardsquare.com/en/products/proguard/manual/examples#logging "ProGuard\'s example of removing logging code") and this article about [enabling ProGuard in an Android Studio project](https://developer.android.com/studio/build/shrink-code#enable "Android Developer - Enable shrinking, obfuscation, and optimization")):
```default
@@ -57,3 +63,7 @@ SecureLog.v("Private key [byte format]: ", key);
```
Then configure ProGuard to strip its calls.
+
+## Custom Logging
+
+You can implement a custom logging facility and disable it at once only for the release builds.
diff --git a/mitigations/comply-with-privacy-regulations.md b/mitigations/MASTG-MITIG-0003.md
similarity index 97%
rename from mitigations/comply-with-privacy-regulations.md
rename to mitigations/MASTG-MITIG-0003.md
index 5ceb5583c3..2e2d66a90b 100644
--- a/mitigations/comply-with-privacy-regulations.md
+++ b/mitigations/MASTG-MITIG-0003.md
@@ -1,5 +1,7 @@
---
title: Comply with Privacy Regulations and Best Practices
+alias: comply-with-privacy-regulations
+id: MASTG-MITIG-0003
platform: android
---
diff --git a/mitigations/MASTG-MITIG-0004.md b/mitigations/MASTG-MITIG-0004.md
new file mode 100644
index 0000000000..bd40281e57
--- /dev/null
+++ b/mitigations/MASTG-MITIG-0004.md
@@ -0,0 +1,11 @@
+---
+title: Exclude Sensitive Data from Backups
+alias: exclude-sensitive-data-from-backups
+id: MASTG-MITIG-0004
+platform: android
+---
+
+For the sensitive files found, instruct the system to exclude them from the backup:
+
+- If you are using Auto Backup, mark them with the `exclude` tag in `backup_rules.xml` (for Android 11 or lower using `android:fullBackupContent`) or `data_extraction_rules.xml` (for Android 12 and higher using `android:dataExtractionRules`), depending on the target API. Make sure to use both the `cloud-backup` and `device-transfer` parameters.
+- If you are using the key-value approach, set up your [BackupAgent](https://developer.android.com/identity/data/keyvaluebackup#BackupAgent) accordingly.
diff --git a/mitigations/MASTG-MITIG-0005.md b/mitigations/MASTG-MITIG-0005.md
new file mode 100644
index 0000000000..dc7abe4578
--- /dev/null
+++ b/mitigations/MASTG-MITIG-0005.md
@@ -0,0 +1,12 @@
+---
+title: Use Secure Encryption Modes
+alias: use-secure-encryption-modes
+id: MASTG-MITIG-0005
+platform: android
+---
+
+Replace insecure encryption modes with secure block cipher modes such as [AES-GCM or AES-CCM](https://csrc.nist.gov/pubs/sp/800/38/d/final) which are authenticated encryption modes that provide confidentiality, integrity, and authenticity.
+
+We recommend avoiding CBC, which while being more secure than ECB, improper implementation, especially incorrect padding, can lead to vulnerabilities such as padding oracle attacks.
+
+For comprehensive guidance on implementing secure encryption modes in Android, refer to the official Android Developers documentation on [Cryptography](https://developer.android.com/privacy-and-security/cryptography).
diff --git a/mitigations/MASTG-MITIG-0006.md b/mitigations/MASTG-MITIG-0006.md
new file mode 100644
index 0000000000..19715ead00
--- /dev/null
+++ b/mitigations/MASTG-MITIG-0006.md
@@ -0,0 +1,26 @@
+---
+title: Use Up-to-Date APK Signing Schemes
+alias: use-up-to-date-apk-signing-schemes
+id: MASTG-MITIG-0006
+platform: android
+---
+
+Ensure that the app is signed with at least the v2 or v3 APK signing scheme, as these provide comprehensive integrity checks and protect the entire APK from tampering. For optimal security and compatibility, consider using v3, which also supports key rotation.
+
+Optionally, you can add v4 signing to enable faster [incremental updates](https://developer.android.com/about/versions/11/features#incremental) in Android 11 and above, but v4 alone does not provide security protections and should be used alongside v2 or v3.
+
+The signing configuration can be managed through Android Studio or the `signingConfigs` section in `build.gradle` or `build.gradle.kts`. To activate both the v3 and v4 schemes, the following values must be set:
+
+```default
+// build.gradle
+android {
+ ...
+ signingConfigs {
+ config {
+ ...
+ enableV3Signing true
+ enableV4Signing true
+ }
+ }
+}
+```
diff --git a/mitigations/index.md b/mitigations/index.md
new file mode 100644
index 0000000000..84f29f3fec
--- /dev/null
+++ b/mitigations/index.md
@@ -0,0 +1,11 @@
+---
+hide: toc
+title: Mitigations (v2 - Beta)
+status: new
+---
+
+??? info "About the MASTG Mitigations"
+
+ The MASTG Mitigations are a collection of specific strategies and best practices that can be used to mitigate security and privacy risks in mobile apps.
+
+ Each mitigation is designed to be simple and focused and may apply to one or multiple tests in the MASTG.
diff --git a/mkdocs.yml b/mkdocs.yml
index e323f8c2c1..066b600d24 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -149,6 +149,9 @@ nav:
# - ... | flat | MASTG/demos/ios/MASVS-RESILIENCE/**/MASTG-DEMO-*.md
# - MASVS-PRIVACY:
# - ... | flat | MASTG/demos/ios/MASVS-PRIVACY/**/MASTG-DEMO-*.md
+ - Mitigations:
+ - MASTG/mitigations/index.md
+ - ... | flat | MASTG/mitigations/*.md
- Techniques:
- MASTG/techniques/index.md
- Generic:
@@ -249,6 +252,7 @@ theme:
app: octicons/code-square-24
demo: material/flask-outline
tech: material/magic-staff # fontawesome/solid/wand-magic-sparkles
+ mitig: material/bandage
maswe: octicons/shield-24
masvs: simple/owasp
features:
@@ -374,6 +378,7 @@ extra:
tech: tech
maswe: maswe
masvs: masvs
+ mitig: mitig
status:
draft: This page is in draft.
new: New in this beta!
diff --git a/src/scripts/structure_mastg.sh b/src/scripts/structure_mastg.sh
index 1953bb2c3f..0792b56c07 100755
--- a/src/scripts/structure_mastg.sh
+++ b/src/scripts/structure_mastg.sh
@@ -4,7 +4,7 @@ set -euo pipefail
mkdir -p docs/MASTG
mkdir -p docs/MASWE
-directories=("tests" "techniques" "tools" "apps" "tests-beta" "demos" "rules")
+directories=("tests" "techniques" "tools" "apps" "tests-beta" "demos" "rules" "mitigations")
for dir in "${directories[@]}"; do
rm -rf "docs/MASTG/$dir"
diff --git a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0204.md b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0204.md
index b9d64ed1a2..f633d35022 100644
--- a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0204.md
+++ b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0204.md
@@ -3,8 +3,7 @@ platform: android
title: Insecure Random API Usage
id: MASTG-TEST-0204
type: [static]
-mitigations:
-- android-use-secure-random
+mitigations: [MASTG-MITIG-0001]
prerequisites:
- identify-sensitive-data
- identify-security-relevant-contexts
diff --git a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0205.md b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0205.md
index 1a2d1cfa05..94aa4b7ede 100644
--- a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0205.md
+++ b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0205.md
@@ -3,8 +3,7 @@ platform: android
title: Non-random Sources Usage
id: MASTG-TEST-0205
type: [static]
-mitigations:
-- android-use-secure-random
+mitigations: [MASTG-MITIG-0001]
prerequisites:
- identify-sensitive-data
- identify-security-relevant-contexts
diff --git a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0232.md b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0232.md
index ed8e15f474..594a1a4395 100644
--- a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0232.md
+++ b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0232.md
@@ -4,6 +4,7 @@ platform: android
id: MASTG-TEST-0232
type: [static, dynamic]
weakness: MASWE-0020
+mitigations: [MASTG-MITIG-0005]
---
## Overview
@@ -42,11 +43,3 @@ The output should contain a list of locations where insecure or deprecated encry
## Evaluation
The test case fails if any insecure encryption modes are identified in the app.
-
-## Mitigation
-
-Replace insecure encryption modes with secure block cipher modes such as [AES-GCM or AES-CCM](https://csrc.nist.gov/pubs/sp/800/38/d/final) which are authenticated encryption modes that provide confidentiality, integrity, and authenticity.
-
-We recommend avoiding CBC, which while being more secure than ECB, improper implementation, especially incorrect padding, can lead to vulnerabilities such as padding oracle attacks.
-
-For comprehensive guidance on implementing secure encryption modes in Android, refer to the official Android Developers documentation on [Cryptography](https://developer.android.com/privacy-and-security/cryptography).
diff --git a/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0224.md b/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0224.md
index 9dc960fdb5..c2c52815f0 100644
--- a/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0224.md
+++ b/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0224.md
@@ -5,6 +5,7 @@ id: MASTG-TEST-0224
type: [static]
available_since: 24
weakness: MASWE-0104
+mitigations: [MASTG-MITIG-0006]
---
## Overview
@@ -27,23 +28,3 @@ The output should contain the value of the `minSdkVersion` attribute and the use
## Evaluation
The test case fails if the app has a `minSdkVersion` attribute of 24 and above, and only the v1 signature scheme is enabled.
-
-To mitigate this issue, ensure that the app is signed with at least the v2 or v3 APK signing scheme, as these provide comprehensive integrity checks and protect the entire APK from tampering. For optimal security and compatibility, consider using v3, which also supports key rotation.
-
-Optionally, you can add v4 signing to enable faster [incremental updates](https://developer.android.com/about/versions/11/features#incremental) in Android 11 and above, but v4 alone does not provide security protections and should be used alongside v2 or v3.
-
-The signing configuration can be managed through Android Studio or the `signingConfigs` section in `build.gradle` or `build.gradle.kts`. To activate both the v3 and v4 schemes, the following values must be set:
-
-```default
-// build.gradle
-android {
- ...
- signingConfigs {
- config {
- ...
- enableV3Signing true
- enableV4Signing true
- }
- }
-}
-```
diff --git a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0203.md b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0203.md
index 3636bf70a9..11e52b98e0 100644
--- a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0203.md
+++ b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0203.md
@@ -5,6 +5,7 @@ id: MASTG-TEST-0203
apis: [Log, Logger, System.out.print, System.err.print, java.lang.Throwable#printStackTrace]
type: [dynamic]
weakness: MASWE-0001
+mitigations: [MASTG-MITIG-0002]
---
## Overview
diff --git a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0207.md b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0207.md
index ca90d2ad8a..fc8e6c4d35 100644
--- a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0207.md
+++ b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0207.md
@@ -3,9 +3,6 @@ platform: android
title: Data Stored in the App Sandbox at Runtime
id: MASTG-TEST-0207
type: [dynamic, filesystem]
-mitigations:
-- android-use-keystore
-- android-use-androidx-security
prerequisites:
- identify-sensitive-data
weakness: MASWE-0006
diff --git a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0216.md b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0216.md
index f8fcb221ae..7e242275f3 100644
--- a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0216.md
+++ b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0216.md
@@ -4,6 +4,7 @@ title: Sensitive Data Not Excluded From Backup
id: MASTG-TEST-0216
type: [dynamic, filesystem]
weakness: MASWE-0004
+mitigations: [MASTG-MITIG-0004]
---
## Overview
@@ -32,8 +33,3 @@ The output should contain a list of files that are restored from the backup.
## Evaluation
The test fails if any of the files are considered sensitive.
-
-For the sensitive files found, instruct the system to exclude them from the backup:
-
-- If you are using Auto Backup, mark them with the `exclude` tag in `backup_rules.xml` (for Android 11 or lower using `android:fullBackupContent`) or `data_extraction_rules.xml` (for Android 12 and higher using `android:dataExtractionRules`), depending on the target API. Make sure to use both the `cloud-backup` and `device-transfer` parameters.
-- If you are using the key-value approach, set up your [BackupAgent](https://developer.android.com/identity/data/keyvaluebackup#BackupAgent) accordingly.
diff --git a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0231.md b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0231.md
index d8265b6aac..ff4c9b41af 100644
--- a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0231.md
+++ b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0231.md
@@ -5,6 +5,7 @@ id: MASTG-TEST-0231
apis: [Log, Logger, System.out.print, System.err.print, java.lang.Throwable#printStackTrace, android.util.Log]
type: [static]
weakness: MASWE-0001
+mitigations: [MASTG-MITIG-0002]
---
## Overview
@@ -21,25 +22,4 @@ The output should contain a list of locations where logging APIs are used.
## Evaluation
-The test fails if an app logs sensitive information from any of the listed locations. Ideally, a release build shouldn't use any logging functions, making it easier to assess sensitive data exposure.
-
-## Mitigation
-
-While preparing the production release, you can use tools like @MASTG-TOOL-0022 (included in Android Studio). To determine whether all logging functions from the `android.util.Log` class have been removed, check the ProGuard configuration file (proguard-rules.pro) for the following options (according to this [example of removing logging code](https://www.guardsquare.com/en/products/proguard/manual/examples#logging "ProGuard\'s example of removing logging code") and this article about [enabling ProGuard in an Android Studio project](https://developer.android.com/studio/build/shrink-code#enable "Android Developer - Enable shrinking, obfuscation, and optimization")):
-
-```default
--assumenosideeffects class android.util.Log
-{
- public static boolean isLoggable(java.lang.String, int);
- public static int v(...);
- public static int i(...);
- public static int w(...);
- public static int d(...);
- public static int e(...);
- public static int wtf(...);
-}
-```
-
-Note that the example above only ensures that calls to the Log class' methods will be removed. If the string that will be logged is dynamically constructed, the code that constructs the string may remain in the bytecode.
-
-Alternatively, you can implement a custom logging facility and disable it at once only for the release builds.
+The test fails if an app logs sensitive information from any of the listed locations.