diff --git a/Document/0x05h-Testing-Platform-Interaction.md b/Document/0x05h-Testing-Platform-Interaction.md
index 239cca1741..7e5995636c 100644
--- a/Document/0x05h-Testing-Platform-Interaction.md
+++ b/Document/0x05h-Testing-Platform-Interaction.md
@@ -48,6 +48,9 @@ Independently from the assigned Protection Level, it is important to consider th
| **CRITICAL** | `android.permission.MOUNT_UNMOUNT_FILESYSTEMS` | signature |
| **CRITICAL** | `android.permission.PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE` | signature |
| **CRITICAL** | `android.permission.PROVIDE_REMOTE_CREDENTIALS` | signature |
+| **CRITICAL** | `android.permission.THREAD_NETWORK_PRIVILEGED` | signature |
+| **CRITICAL** | `android.permission.RECORD_SENSITIVE_CONTENT` | signature |
+| **CRITICAL** | `android.permission.RECEIVE_SENSITIVE_NOTIFICATIONS` | signature |
| **HIGH** | `android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS` | signature |
| **HIGH** | `android.permission.READ_SMS` | dangerous |
| **HIGH** | `android.permission.WRITE_SMS` | normal |
@@ -72,6 +75,9 @@ Independently from the assigned Protection Level, it is important to consider th
| **HIGH** | `android.permission.MANAGE_ONGOING_CALLS` | signature |
| **HIGH** | `android.permission.READ_RESTRICTED_STATS` | internal |
| **HIGH** | `android.permission.BIND_AUTOFILL_SERVICE` | signature |
+| **HIGH** | `android.permission.WRITE_VERIFICATION_STATE_E2EE_CONTACT_KEYS` | signature |
+| **HIGH** | `android.permission.READ_DROPBOX_DATA` | signature |
+| **HIGH** | `android.permission.WRITE_FLAGS` | signature |
| **MEDIUM** | `android.permission.ACCESS_COARSE_LOCATION` | dangerous |
| **MEDIUM** | `android.permission.CHANGE_COMPONENT_ENABLED_STATE` | signature |
| **MEDIUM** | `android.permission.READ_CONTACTS` | dangerous |
@@ -94,6 +100,9 @@ Independently from the assigned Protection Level, it is important to consider th
| **MEDIUM** | `android.permission.READ_MEDIA_AUDIO` | dangerous |
| **MEDIUM** | `android.permission.READ_MEDIA_IMAGES` | dangerous |
| **MEDIUM** | `android.permission.READ_MEDIA_VIDEO` | dangerous |
+| **MEDIUM** | `android.permission.REGISTER_NSD_OFFLOAD_ENGINE` | signature |
+| **MEDIUM** | `android.permission.ACCESS_LAST_KNOWN_CELL_ID` | signature |
+| **MEDIUM** | `android.permission.USE_COMPANION_TRANSPORTS` | signature |
| **LOW** | `android.permission.DOWNLOAD_WITHOUT_NOTIFICATION` | normal |
| **LOW** | `android.permission.PACKAGE_USAGE_STATS` | signature |
| **LOW** | `android.permission.MASTER_CLEAR` | signature |
@@ -105,6 +114,11 @@ Independently from the assigned Protection Level, it is important to consider th
| **LOW** | `android.permission.LOG_FOREGROUND_RESOURCE_USE` | signature |
| **LOW** | `android.permission.MANAGE_DEFAULT_APPLICATIONS` | signature |
| **LOW** | `android.permission.MANAGE_FACE` | signature |
+| **LOW** | `android.permission.REPORT_USAGE_STATS` | signature |
+| **LOW** | `android.permission.MANAGE_DISPLAYS` | signature |
+| **LOW** | `android.permission.RESTRICT_DISPLAY_MODES` | signature |
+| **LOW** | `android.permission.ACCESS_HIDDEN_PROFILES_FULL` | signature |
+| **LOW** | `android.permission.GET_BACKGROUND_INSTALLED_PACKAGES` | signature |
| **NONE** | `android.permission.ACCESS_NETWORK_STATE` | normal |
| **NONE** | `android.permission.RECEIVE_BOOT_COMPLETED` | normal |
| **NONE** | `android.permission.WAKE_LOCK` | normal |
diff --git a/Document/0x06i-Testing-Code-Quality-and-Build-Settings.md b/Document/0x06i-Testing-Code-Quality-and-Build-Settings.md
index 656240e978..7a81091224 100644
--- a/Document/0x06i-Testing-Code-Quality-and-Build-Settings.md
+++ b/Document/0x06i-Testing-Code-Quality-and-Build-Settings.md
@@ -51,7 +51,7 @@ Detecting the presence of [binary protection mechanisms](0x04h-Testing-Code-Qual
Although Xcode enables all binary security features by default, it may be relevant to verify this for old applications or to check for compiler flag misconfigurations. The following features are applicable:
- [**PIE (Position Independent Executable)**](0x04h-Testing-Code-Quality.md#position-independent-code):
- - PIE applies to executable binaries (Mach-O type `MH_EXECUTE`).
+ - PIE applies to executable binaries (Mach-O type `MH_EXECUTE`) [source](https://web.archive.org/web/20230328221404/https://opensource.apple.com/source/cctools/cctools-921/include/mach-o/loader.h.auto.html).
- However it's not applicable for libraries (Mach-O type `MH_DYLIB`).
- [**Memory management**](0x04h-Testing-Code-Quality.md#memory-management):
- Both pure Objective-C, Swift and hybrid binaries should have ARC (Automatic Reference Counting) enabled.
diff --git a/Document/index.md b/Document/index.md
index 19bb81d2db..d895a8b0d5 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-shield-check: Best Practices (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/mitigations/android-use-secure-random.md b/best-practices/MASTG-BEST-0001.md
similarity index 87%
rename from mitigations/android-use-secure-random.md
rename to best-practices/MASTG-BEST-0001.md
index ef3f9c5367..d8900086f5 100644
--- a/mitigations/android-use-secure-random.md
+++ b/best-practices/MASTG-BEST-0001.md
@@ -1,5 +1,7 @@
---
-title: Use Secure Random Number Generators APIs
+title: Use Secure Random Number Generator APIs
+alias: android-use-secure-random
+id: MASTG-BEST-0001
platform: android
---
diff --git a/mitigations/use-proguard.md b/best-practices/MASTG-BEST-0002.md
similarity index 89%
rename from mitigations/use-proguard.md
rename to best-practices/MASTG-BEST-0002.md
index 992b0bccab..dd29b6ba13 100644
--- a/mitigations/use-proguard.md
+++ b/best-practices/MASTG-BEST-0002.md
@@ -1,8 +1,14 @@
---
-title: Use ProGuard to Remove Logging Code
+title: Remove Logging Code
+alias: remove-logging-code
+id: MASTG-BEST-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/best-practices/MASTG-BEST-0003.md
similarity index 97%
rename from mitigations/comply-with-privacy-regulations.md
rename to best-practices/MASTG-BEST-0003.md
index 5ceb5583c3..0b701af0d3 100644
--- a/mitigations/comply-with-privacy-regulations.md
+++ b/best-practices/MASTG-BEST-0003.md
@@ -1,5 +1,7 @@
---
title: Comply with Privacy Regulations and Best Practices
+alias: comply-with-privacy-regulations
+id: MASTG-BEST-0003
platform: android
---
diff --git a/best-practices/MASTG-BEST-0004.md b/best-practices/MASTG-BEST-0004.md
new file mode 100644
index 0000000000..f84628deeb
--- /dev/null
+++ b/best-practices/MASTG-BEST-0004.md
@@ -0,0 +1,11 @@
+---
+title: Exclude Sensitive Data from Backups
+alias: exclude-sensitive-data-from-backups
+id: MASTG-BEST-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/best-practices/MASTG-BEST-0005.md b/best-practices/MASTG-BEST-0005.md
new file mode 100644
index 0000000000..b2bc38bb77
--- /dev/null
+++ b/best-practices/MASTG-BEST-0005.md
@@ -0,0 +1,12 @@
+---
+title: Use Secure Encryption Modes
+alias: use-secure-encryption-modes
+id: MASTG-BEST-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/best-practices/MASTG-BEST-0006.md b/best-practices/MASTG-BEST-0006.md
new file mode 100644
index 0000000000..aeb4ce4af1
--- /dev/null
+++ b/best-practices/MASTG-BEST-0006.md
@@ -0,0 +1,26 @@
+---
+title: Use Up-to-Date APK Signing Schemes
+alias: use-up-to-date-apk-signing-schemes
+id: MASTG-BEST-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/best-practices/MASTG-BEST-0007.md b/best-practices/MASTG-BEST-0007.md
new file mode 100644
index 0000000000..70b2cb6c9d
--- /dev/null
+++ b/best-practices/MASTG-BEST-0007.md
@@ -0,0 +1,10 @@
+---
+title: Debuggable Flag Disabled in the AndroidManifest
+alias: debuggable-flag-disabled
+id: MASTG-BEST-0007
+platform: android
+---
+
+Ensure the debuggable flag in the AndroidManifest.xml is set to `false` for all release builds.
+
+**Note:** Disabling debugging via the `debuggable` flag is an important first step but does not fully protect the app from advanced attacks. Skilled attackers can enable debugging through various means, such as binary patching (see @MASTG-TECH-0038) to allow attachment of a debugger or the use of binary instrumentation tools like @MASTG-TOOL-0001 to achieve similar capabilities. For apps requiring a higher level of security, consider implementing anti-debugging techniques as an additional layer of defense. Refer to @MASWE-0101 for detailed guidance.
diff --git a/best-practices/MASTG-BEST-0008.md b/best-practices/MASTG-BEST-0008.md
new file mode 100644
index 0000000000..de2f264ae2
--- /dev/null
+++ b/best-practices/MASTG-BEST-0008.md
@@ -0,0 +1,29 @@
+---
+title: Debugging Disabled for WebViews
+alias: debugging-disabled-webviews
+id: MASTG-BEST-0008
+platform: android
+---
+
+Ensure that WebView debugging is disabled in production builds to prevent attackers from exploiting this feature to eavesdrop, modify, or debug communication within WebViews.
+
+- Set `WebView.setWebContentsDebuggingEnabled` to `false` in production, or remove the calls entirely if they are unnecessary.
+- If WebView debugging is required during development, ensure it is enabled only when the app is in a debuggable state by [checking the `ApplicationInfo.FLAG_DEBUGGABLE` flag at runtime](https://developer.chrome.com/docs/devtools/remote-debugging/webviews/#configure_webviews_for_debugging).
+
+For example:
+
+```kotlin
+if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
+ { WebView.setWebContentsDebuggingEnabled(true); }
+}
+```
+
+**Note:** Disabling WebView debugging this way helps protect an app already running on a device. For an attacker to exploit WebView debugging, they must have physical access to the device (e.g., a stolen or test device) or remote access through malware or other malicious means. Additionally, the device must typically be unlocked, and the attacker would need to know the device PIN, password, or biometric authentication to gain full control and connect debugging tools like `adb` or Chrome DevTools.
+
+However, disabling WebView debugging does not eliminate all attack vectors. An attacker could:
+
+1. Patch the app to add calls to these APIs (see @MASTG-TECH-0038), then repackage and re-sign it (see @MASTG-TECH-0039).
+2. Use runtime method hooking (see @MASTG-TECH-0043) to enable WebView debugging dynamically at runtime.
+
+Disabling WebView debugging serves as one layer of defense to reduce risks but should be combined with other security measures.
diff --git a/best-practices/index.md b/best-practices/index.md
new file mode 100644
index 0000000000..73f1ebcadc
--- /dev/null
+++ b/best-practices/index.md
@@ -0,0 +1,11 @@
+---
+hide: toc
+title: Best Practices (v2 Beta)
+status: new
+---
+
+??? info "About the MASTG Best Practices"
+
+ The MASTG Best Practices are a collection of specific strategies and practices that can be used to prevent or mitigate security and privacy risks in mobile apps.
+
+ Each Best Practices is designed to be simple and focused and may apply to one or multiple tests in the MASTG.
diff --git a/demos/index.md b/demos/index.md
index 6f72844c65..6838bd9a2d 100644
--- a/demos/index.md
+++ b/demos/index.md
@@ -1,6 +1,6 @@
---
hide: toc
-title: MASTG Demos
+title: MASTG Demos (v2 Beta)
status: new
---
diff --git a/docs/hooks/add-cross-references.py b/docs/hooks/add-cross-references.py
index 6881a2b3e0..680fbe6642 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": {},
+ "best-practices": {}
}
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")
+ best_practices_ids = test_meta.get("best-practices")
+
+ # 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 best_practices listing all tests that reference each best_practice ID
+ if best_practices_ids:
+ for best_practice_id in best_practices_ids:
+ if best_practice_id not in cross_references["best-practices"]:
+ cross_references["best-practices"][best_practice_id] = []
+ cross_references["best-practices"][best_practice_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
@@ -92,7 +108,25 @@ def on_page_markdown(markdown, page, config, **kwargs):
markdown += f"\n\n{tests_section}"
if "MASTG-TEST-" in path:
+
+ # Add best_practices section to tests as a bullet point list with IDs, links are resolved in a separate hook
+ # ORIGIN: Test metadata
+
+ best_practices = meta.get('best-practices')
+ if best_practices:
+ best_practices_section = "## Mitigations\n\n"
+ for best_practice_id in best_practices:
+ best_practice_path = f"MASTG/best-practices/{best_practice_id}.md"
+ relPath = os.path.relpath(best_practice_path, os.path.dirname(path))
+ best_practices_section += f"- @{best_practice_id}\n"
+
+ markdown += f"\n\n{best_practices_section}"
+
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
@@ -103,5 +137,22 @@ def on_page_markdown(markdown, page, config, **kwargs):
demos_section += f"[{get_platform_icon(demo['platform'])} {demo['id']}: {demo['title']}]({relPath}){{: .mas-demo-button}} "
markdown += f"\n\n{demos_section}"
+
+ if "MASTG-BEST" in path:
+ best_practice_id = meta.get('id')
+
+ # Add Tests section to best_practices as buttons
+ # ORIGIN: Cross-references from this script
+
+ if best_practice_id in cross_references["best-practices"]:
+ best_practices = cross_references["best-practices"].get(best_practice_id)
+ meta['best-practices'] = best_practices
+ if best_practices:
+ best_practices_section = "## Tests\n\n"
+ for best_practice in best_practices:
+ relPath = os.path.relpath(best_practice['path'], os.path.dirname(path))
+ best_practices_section += f"[{get_platform_icon(best_practice['platform'])} {best_practice['id']}: {best_practice['title']}]({relPath}){{: .mas-test-button}} "
+
+ markdown += f"\n\n{best_practices_section}"
return markdown
\ No newline at end of file
diff --git a/docs/hooks/add-tags.py b/docs/hooks/add-tags.py
index 4ee57294f6..d21f852c9c 100644
--- a/docs/hooks/add-tags.py
+++ b/docs/hooks/add-tags.py
@@ -45,6 +45,10 @@ def on_page_markdown(markdown, page, **kwargs):
if page.meta.get('status'):
if page.meta.get('status') == 'draft':
tags.append('draft')
+
+ if page.meta.get('status'):
+ if page.meta.get('status') == 'deprecated':
+ tags.append('deprecated')
page.meta['tags'] = tags
diff --git a/docs/hooks/create_dynamic_tables.py b/docs/hooks/create_dynamic_tables.py
index 431e4b6b3e..f8222ca9b3 100644
--- a/docs/hooks/create_dynamic_tables.py
+++ b/docs/hooks/create_dynamic_tables.py
@@ -185,6 +185,9 @@ def get_mastg_components_dict(name):
frontmatter['platform'] = "".join([get_platform_icon(platform) for platform in frontmatter['platform']])
else:
frontmatter['platform'] = get_platform_icon(frontmatter['platform'])
+ if "tests" in component_path:
+ frontmatter['status'] = frontmatter.get('status', 'current')
+
components.append(frontmatter)
return components
@@ -236,6 +239,14 @@ def get_all_tests_beta():
frontmatter['id'] = test_id
frontmatter['title'] = f"@{frontmatter['id']}"
frontmatter['platform'] = get_platform_icon(frontmatter['platform'])
+ frontmatter['status'] = frontmatter.get('status', 'new')
+ status = frontmatter['status']
+ if status == 'new':
+ frontmatter['status'] = 'newstatus:new'
+ elif status == 'draft':
+ frontmatter['status'] = f'draftstatus:draft'
+ elif status == 'deprecated':
+ frontmatter['status'] = 'deprecatedstatus:deprecated'
tests.append(frontmatter)
return tests
@@ -259,6 +270,25 @@ def get_all_demos_beta():
demos.append(frontmatter)
return demos
+def get_all_mitigations_beta():
+
+ mitigations = []
+
+ for file in glob.glob("docs/MASTG/best-practices/**/MASTG-BEST-*.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/best-practices/{os.path.splitext(os.path.relpath(file, 'docs/MASTG/best-practices'))[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}
@@ -272,7 +302,7 @@ def on_page_markdown(markdown, page, **kwargs):
# tests/index.md
- column_titles = {'id': 'ID', 'title': 'Title', 'platform': "Platform", 'masvs_v2_id': "MASVS v2 ID", 'masvs_v1_id': "MASVS v1 IDs", 'last_updated': 'Last Updated'} #'id': 'ID', ... , 'refs': 'Refs', 'techniques': 'Techniques'
+ column_titles = {'id': 'ID', 'title': 'Title', 'platform': "Platform", 'masvs_v2_id': "MASVS v2 ID", 'masvs_v1_id': "MASVS v1 IDs", 'status': 'Status'}
tests = get_mastg_components_dict("docs/MASTG/tests")
tests_of_type = [reorder_dict_keys(test, column_titles.keys()) for test in tests]
for test in tests_of_type:
@@ -286,7 +316,7 @@ def on_page_markdown(markdown, page, **kwargs):
# tests-beta/index.md
- column_titles = {'id': 'ID', 'title': 'Title', 'platform': "Platform", 'weakness': "Weakness", 'type': "Type"}
+ column_titles = {'id': 'ID', 'title': 'Title', 'platform': "Platform", 'weakness': "Weakness", 'type': "Type", 'status': "Status"}
tests_beta = get_all_tests_beta()
tests_beta_columns_reordered = [reorder_dict_keys(test, column_titles.keys()) for test in tests_beta]
@@ -303,6 +333,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("best-practices/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/maswe-beta-banner.py b/docs/hooks/maswe-beta-banner.py
index 1a6dd53dde..f68e5dc846 100644
--- a/docs/hooks/maswe-beta-banner.py
+++ b/docs/hooks/maswe-beta-banner.py
@@ -63,7 +63,7 @@ def get_mastg_v1_coverage(meta):
mastg_v1_tests = " No MASTG v1 tests are related to this weakness."
return mastg_v1_tests
-def get_info_banner(meta):
+def get_maswe_draft_banner(meta):
id = meta.get('id')
@@ -88,7 +88,7 @@ def get_info_banner(meta):
mastg_v1_tests = get_mastg_v1_coverage(meta)
- info_banner = f"""
+ banner = f"""
!!! warning "Draft Weakness"
This weakness hasn't been created yet and it's in **draft**. But you can check its status or start working on it yourself.
@@ -108,7 +108,54 @@ def get_info_banner(meta):
{mastg_v1_tests}
"""
- return info_banner
+ return banner
+
+def get_tests_draft_banner(meta):
+ id = meta.get('id')
+ note = meta.get('note', None)
+ weakness = meta.get('weakness', None)
+
+ if note:
+ note = f" > Note: {note}\n"
+
+ if weakness:
+ weakness = f"\nFor more details, check the associated weakness: @{weakness}\n"
+
+ banner = f"""
+!!! warning "Draft Test"
+
+ This test hasn't been created yet and it's in **draft**. But you can check its status or start working on it yourself.
+ If the issue has not yet been assigned, you can request to be assigned to it and submit a PR with the new content for that test by following our [guidelines](https://docs.google.com/document/d/1EMsVdfrDBAu0gmjWAUEs60q-fWaOmDB5oecY9d9pOlg/edit?pli=1&tab=t.0#heading=h.j1tiymiuocrm).
+
+ :material-github: Check our GitHub Issues for {id}
+
+ If an issue doesn't exist yet, please create one and assign it to yourself or request to be assigned to it.
+
+{note}
+{weakness}
+"""
+ return banner
+
+def get_v1_deprecated_tests_banner(meta):
+ id = meta.get('id')
+ covered_by = meta.get('covered_by', [])
+ deprecation_note = meta.get('deprecation_note', "")
+
+ if covered_by:
+ covered_by = "\n".join([f" - @{test}" for test in covered_by])
+ else:
+ covered_by = " No tests are covering this weakness."
+
+ banner = f"""
+!!! danger "Deprecated Test"
+
+ This test is **deprecated** and should not be used anymore. **Reason**: {deprecation_note}
+
+ Please check the following MASTG v2 tests that cover this v1 test:
+
+{covered_by}
+"""
+ return banner
# https://www.mkdocs.org/dev-guide/plugins/#on_page_markdown
@mkdocs.plugins.event_priority(-50)
@@ -117,11 +164,17 @@ def on_page_markdown(markdown, page, **kwargs):
banners = []
- if any(substring in path for substring in ["MASWE/", "MASTG/tests-beta/", "MASTG/demos/"]):
+ if any(substring in path for substring in ["MASWE/", "MASTG/tests-beta/", "MASTG/demos/", "MASTG/best-practices/"]):
banners.append(beta_banner)
if "MASWE/" in path and page.meta.get('status') == 'draft':
- banners.append(get_info_banner(page.meta))
+ banners.append(get_maswe_draft_banner(page.meta))
+
+ if "MASTG/tests-beta/" in path and page.meta.get('status') == 'draft':
+ banners.append(get_tests_draft_banner(page.meta))
+
+ if "MASTG/tests/" in path and page.meta.get('status') == 'deprecated':
+ banners.append(get_v1_deprecated_tests_banner(page.meta))
if banners:
markdown = "\n\n".join(banners) + "\n\n" + markdown
diff --git a/docs/hooks/resolve_references.py b/docs/hooks/resolve_references.py
index 0210796265..eab538e43c 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": {}, "BEST": {}}
@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": [], "BEST": []}
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|BEST)-\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..e0fbb8c0ef 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-BEST-"]):
# 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/mkdocs.yml b/mkdocs.yml
index e323f8c2c1..f96f761b96 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -41,6 +41,9 @@ nav:
- ... | flat | MASTG/0x05*.md
- iOS Security Testing:
- ... | flat | MASTG/0x06*.md
+ - Best Practices (v2 Beta):
+ - MASTG/best-practices/index.md
+ - ... | flat | MASTG/best-practices/*.md
- Tests:
- MASTG/tests/index.md
- Android:
@@ -86,31 +89,31 @@ nav:
- ... | flat | MASTG/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-*.md
# - MASVS-AUTH:
# - ... | flat | MASTG/tests-beta/android/MASVS-AUTH/MASTG-TEST-*.md
- # - MASVS-NETWORK:
- # - ... | flat | MASTG/tests-beta/android/MASVS-NETWORK/MASTG-TEST-*.md
+ - MASVS-NETWORK:
+ - ... | flat | MASTG/tests-beta/android/MASVS-NETWORK/MASTG-TEST-*.md
# - MASVS-PLATFORM:
# - ... | flat | MASTG/tests-beta/android/MASVS-PLATFORM/MASTG-TEST-*.md
- # - MASVS-CODE:
- # - ... | flat | MASTG/tests-beta/android/MASVS-CODE/MASTG-TEST-*.md
- # - MASVS-RESILIENCE:
- # - ... | flat | MASTG/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-*.md
+ - MASVS-CODE:
+ - ... | flat | MASTG/tests-beta/android/MASVS-CODE/MASTG-TEST-*.md
+ - MASVS-RESILIENCE:
+ - ... | flat | MASTG/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-*.md
- MASVS-PRIVACY:
- ... | flat | MASTG/tests-beta/android/MASVS-PRIVACY/MASTG-TEST-*.md
- # - iOS:
- # - MASVS-STORAGE:
- # - ... | flat | MASTG/tests-beta/ios/MASVS-STORAGE/MASTG-TEST-*.md
- # - MASVS-CRYPTO:
- # - ... | flat | MASTG/tests-beta/ios/MASVS-CRYPTO/MASTG-TEST-*.md
+ - iOS:
+ - MASVS-STORAGE:
+ - ... | flat | MASTG/tests-beta/ios/MASVS-STORAGE/MASTG-TEST-*.md
+ - MASVS-CRYPTO:
+ - ... | flat | MASTG/tests-beta/ios/MASVS-CRYPTO/MASTG-TEST-*.md
# - MASVS-AUTH:
# - ... | flat | MASTG/tests-beta/ios/MASVS-AUTH/MASTG-TEST-*.md
# - MASVS-NETWORK:
# - ... | flat | MASTG/tests-beta/ios/MASVS-NETWORK/MASTG-TEST-*.md
# - MASVS-PLATFORM:
# - ... | flat | MASTG/tests-beta/ios/MASVS-PLATFORM/MASTG-TEST-*.md
- # - MASVS-CODE:
- # - ... | flat | MASTG/tests-beta/ios/MASVS-CODE/MASTG-TEST-*.md
- # - MASVS-RESILIENCE:
- # - ... | flat | MASTG/tests-beta/ios/MASVS-RESILIENCE/MASTG-TEST-*.md
+ - MASVS-CODE:
+ - ... | flat | MASTG/tests-beta/ios/MASVS-CODE/MASTG-TEST-*.md
+ - MASVS-RESILIENCE:
+ - ... | flat | MASTG/tests-beta/ios/MASVS-RESILIENCE/MASTG-TEST-*.md
# - MASVS-PRIVACY:
# - ... | flat | MASTG/tests-beta/ios/MASVS-PRIVACY/MASTG-TEST-*.md
- Demos (v2 Beta):
@@ -132,23 +135,23 @@ nav:
# - ... | flat | MASTG/demos/android/MASVS-RESILIENCE/**/MASTG-DEMO-*.md
- MASVS-PRIVACY:
- ... | flat | MASTG/demos/android/MASVS-PRIVACY/**/MASTG-DEMO-*.md
- # - iOS:
- # - MASVS-STORAGE:
- # - ... | flat | MASTG/demos/ios/MASVS-STORAGE/**/MASTG-DEMO-*.md
- # - MASVS-CRYPTO:
- # - ... | flat | MASTG/demos/ios/MASVS-CRYPTO/**/MASTG-DEMO-*.md
- # - MASVS-AUTH:
- # - ... | flat | MASTG/demos/ios/MASVS-AUTH/**/MASTG-DEMO-*.md
- # - MASVS-NETWORK:
- # - ... | flat | MASTG/demos/ios/MASVS-NETWORK/**/MASTG-DEMO-*.md
- # - MASVS-PLATFORM:
- # - ... | flat | MASTG/demos/ios/MASVS-PLATFORM/**/MASTG-DEMO-*.md
- # - MASVS-CODE:
- # - ... | flat | MASTG/demos/ios/MASVS-CODE/**/MASTG-DEMO-*.md
- # - MASVS-RESILIENCE:
- # - ... | flat | MASTG/demos/ios/MASVS-RESILIENCE/**/MASTG-DEMO-*.md
- # - MASVS-PRIVACY:
- # - ... | flat | MASTG/demos/ios/MASVS-PRIVACY/**/MASTG-DEMO-*.md
+ - iOS:
+ - MASVS-STORAGE:
+ - ... | flat | MASTG/demos/ios/MASVS-STORAGE/**/MASTG-DEMO-*.md
+ - MASVS-CRYPTO:
+ - ... | flat | MASTG/demos/ios/MASVS-CRYPTO/**/MASTG-DEMO-*.md
+ # - MASVS-AUTH:
+ # - ... | flat | MASTG/demos/ios/MASVS-AUTH/**/MASTG-DEMO-*.md
+ # - MASVS-NETWORK:
+ # - ... | flat | MASTG/demos/ios/MASVS-NETWORK/**/MASTG-DEMO-*.md
+ # - MASVS-PLATFORM:
+ # - ... | flat | MASTG/demos/ios/MASVS-PLATFORM/**/MASTG-DEMO-*.md
+ # - MASVS-CODE:
+ # - ... | flat | MASTG/demos/ios/MASVS-CODE/**/MASTG-DEMO-*.md
+ # - MASVS-RESILIENCE:
+ # - ... | flat | MASTG/demos/ios/MASVS-RESILIENCE/**/MASTG-DEMO-*.md
+ # - MASVS-PRIVACY:
+ # - ... | flat | MASTG/demos/ios/MASVS-PRIVACY/**/MASTG-DEMO-*.md
- Techniques:
- MASTG/techniques/index.md
- Generic:
@@ -243,12 +246,14 @@ theme:
l2: material/circle-multiple-outline
r: material/circle-double
draft: material/information-outline
+ deprecated: material/trash-can
new: material/alert-decagram
tool: octicons/tools-24
test: octicons/codescan-checkmark-24
app: octicons/code-square-24
demo: material/flask-outline
tech: material/magic-staff # fontawesome/solid/wand-magic-sparkles
+ best: material/shield-check
maswe: octicons/shield-24
masvs: simple/owasp
features:
@@ -366,6 +371,7 @@ extra:
L2: l2
R: r
draft: draft
+ deprecated: deprecated
new: new
tool: tool
test: test
@@ -374,6 +380,8 @@ extra:
tech: tech
maswe: maswe
masvs: masvs
+ best: best
status:
draft: This page is in draft.
+ deprecated: This page is deprecated.
new: New in this beta!
diff --git a/src/scripts/structure_mastg.sh b/src/scripts/structure_mastg.sh
index 1953bb2c3f..5bdc0bd095 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" "best-practices")
for dir in "${directories[@]}"; do
rm -rf "docs/MASTG/$dir"
diff --git a/techniques/android/MASTG-TECH-0022.md b/techniques/android/MASTG-TECH-0022.md
index 41e82ee3ef..2e3792242d 100644
--- a/techniques/android/MASTG-TECH-0022.md
+++ b/techniques/android/MASTG-TECH-0022.md
@@ -5,7 +5,9 @@ platform: android
Most of the apps you might encounter connect to remote endpoints. Even before you perform any dynamic analysis (e.g. traffic capture and analysis), you can obtain some initial inputs or entry points by enumerating the domains to which the application is supposed to communicate to.
-Typically these domains will be present as strings within the binary of the application. One way to achieve this is by using automated tools such as [APKEnum](https://github.com/shivsahni/APKEnum "APKEnum: A Python Utility For APK Enumeration") or @MASTG-TOOL-0035. Alternatively, you can _grep_ for the domain names by using regular expressions. For this you can target the app binary directly or reverse engineer it and target the disassembled or decompiled code. The latter option has a clear advantage: it can provide you with **context**, as you'll be able to see in which context each domain is being used (e.g. class and method).
+Typically, these domains will be present as strings within the binary of the application. One way to do this is to use automated tools such as @MASTG-TOOL-0125 or @MASTG-TOOL-0035.
+
+Alternatively, you can _grep_ for the domain names using regular expressions. To do this, you can target the app binary directly, or reverse engineer it and target the disassembled or decompiled code. The latter option has a clear advantage: it can provide you with **context**, as you'll be able to see in which context each domain is used (e.g. class and method).
From here on you can use this information to derive more insights which might be of use later during your analysis, e.g. you could match the domains to the pinned certificates or the [Network Security Configuration](../../Document/0x05g-Testing-Network-Communication.md#android-network-security-configuration) file or perform further reconnaissance on domain names to know more about the target environment. When evaluating an application it is important to check the Network Security Configuration file, as often (less secure) debug configurations might be pushed into final release builds by mistake.
diff --git a/techniques/android/MASTG-TECH-0115.md b/techniques/android/MASTG-TECH-0115.md
index 0864e845d8..e261541ac0 100644
--- a/techniques/android/MASTG-TECH-0115.md
+++ b/techniques/android/MASTG-TECH-0115.md
@@ -1,5 +1,5 @@
---
-title: Obtaining Compiler Provided Security Features
+title: Obtaining Compiler-Provided Security Features
platform: android
---
diff --git a/techniques/ios/MASTG-TECH-0082.md b/techniques/ios/MASTG-TECH-0082.md
index 2421292ed3..6922bdd774 100644
--- a/techniques/ios/MASTG-TECH-0082.md
+++ b/techniques/ios/MASTG-TECH-0082.md
@@ -1,11 +1,63 @@
---
-title: Get Loaded Native Libraries
+title: Get Shared Libraries
platform: ios
---
-## Using Objection
-You can use the `list_frameworks` command in @MASTG-TOOL-0038 to list all the application's bundles that represent Frameworks.
+To effectively identify and analyze shared libraries within an iOS application, it's important to distinguish between the app's bundled libraries and the system libraries provided by iOS. This distinction helps focus on the components that are unique to the app, thereby reducing noise during security assessments.
+
+- **System Libraries**: Part of the iOS SDK, located in directories such as `/System/Library/Frameworks` or `/usr/lib`. These libraries are standard for all iOS applications and generally don't require detailed analysis unless there is a specific reason.
+- **App-Bundled Libraries**: Included in the app bundle, often found in the `Frameworks` directory (`YourApp.app/Frameworks`). They include both first-party (custom) and third-party libraries that the developer intentionally incorporated into the app. They are the primary focus for security assessments. However, note that some **system libraries** may be also bundled with the app to ensure compatibility with specific versions of the iOS SDK so you'd need to filter them out.
+
+Note that we're not considering static libraries, which, unlike dynamic libraries that are loaded at runtime, become part of the app's binary, resulting in a single executable file.
+
+**Strategy**: Use one of the methods below, or a combination of them, to identify shared libraries, and then filter out system libraries to focus on those that are bundled with the app.
+
+## Inspecting the Application Binary
+
+Navigate to the `Frameworks` directory within the application bundle to find the shared libraries. The shared libraries are usually in the form of `.framework` or `.dylib` files.
+
+```bash
+ls -1 Frameworks
+App.framework
+Flutter.framework
+libswiftCore.dylib
+libswiftCoreAudio.dylib
+...
+```
+
+## @MASTG-TOOL-0060
+
+You can use the `otool -L` command to list the shared libraries.
+
+```bash
+otool -L MASTestApp
+MASTestApp:
+ /System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 2503.1.0)
+ /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
+ /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1345.120.2)
+ /System/Library/Frameworks/CryptoKit.framework/CryptoKit (compatibility version 1.0.0, current version 1.0.0)
+ ...
+```
+
+## @MASTG-TOOL-0073
+
+In radare2, you can list the linked libraries using the `il` command.
+
+```bash
+r2 MASTestApp
+[0x100006e9c]> il
+[Linked libraries]
+/System/Library/Frameworks/Foundation.framework/Foundation
+/usr/lib/libobjc.A.dylib
+/usr/lib/libSystem.B.dylib
+/System/Library/Frameworks/CryptoKit.framework/CryptoKit
+...
+```
+
+## @MASTG-TOOL-0074
+
+You can use Objection's command `list_frameworks` to list all the app's bundles that represent Frameworks.
```bash
...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # ios bundles list_frameworks
@@ -17,9 +69,9 @@ RealmSwift org.cocoapods.RealmSwift 4.1.1 ...A-v2.ap
...
```
-## Using Frida
+## @MASTG-TOOL-0039
-In Frida REPL process related information can be obtained using the `Process` command. Within the `Process` command the function `enumerateModules` lists the libraries loaded into the process memory.
+The `Process.enumerateModules()` function in Frida's REPL allows enumeration of modules loaded into memory during runtime.
```bash
[iPhone::com.iOweApp]-> Process.enumerateModules()
@@ -45,21 +97,3 @@ In Frida REPL process related information can be obtained using the `Process` co
...
```
-
-Similarly, information related to various threads can be obtained.
-
-```bash
-Process.enumerateThreads()
-[
- {
- "context": {
- ...
- },
- "id": 1287,
- "state": "waiting"
- },
-
- ...
-```
-
-The `Process` command exposes multiple functions which can be explored as per needs. Some useful functions are `findModuleByAddress`, `findModuleByName` and `enumerateRanges` besides others.
diff --git a/techniques/ios/MASTG-TECH-0091.md b/techniques/ios/MASTG-TECH-0091.md
index 16c98c790e..dda9ae36ab 100644
--- a/techniques/ios/MASTG-TECH-0091.md
+++ b/techniques/ios/MASTG-TECH-0091.md
@@ -29,4 +29,4 @@ Writing executable to Payload/UnCrackable Level 1.app/UnCrackable Level 1...
By default, an app available on the Apple App Store is not debuggable. In order to debug an iOS application, it must have the `get-task-allow` entitlement enabled. This entitlement allows other processes (like a debugger) to attach to the app. Xcode is not adding the `get-task-allow` entitlement in a distribution provisioning profile; it is only whitelisted and added in a development provisioning profile.
-Thus, to debug an iOS application obtained from the App Store, it needs to be re-signed with a development provisioning profile with the `get-task-allow` entitlement. How to re-sign an application is discussed in the next section.
+Thus, to debug an iOS application obtained from the App Store, it needs to be re-signed with a development provisioning profile with the `get-task-allow` entitlement. How to re-sign an application is discussed in @MASTG-TECH-0079.
diff --git a/techniques/ios/MASTG-TECH-0118.md b/techniques/ios/MASTG-TECH-0118.md
new file mode 100644
index 0000000000..a0d3055494
--- /dev/null
+++ b/techniques/ios/MASTG-TECH-0118.md
@@ -0,0 +1,64 @@
+---
+title: Obtaining Compiler-Provided Security Features
+platform: ios
+---
+
+The iOS compiler provides several [security features that can be enabled during compilation](../../../Document/0x06i-Testing-Code-Quality-and-Build-Settings.md/#binary-protection-mechanisms). These features help protect the application from common vulnerabilities like buffer overflows and memory leaks. This technique provides guidance on how to check if these features are enabled in the compiled binary.
+
+## @MASTG-TOOL-0073
+
+In radare2, the presence of these compiler-provided security features can be checked by using the `i` and `is` commands.
+
+**Check for PIC and Canaries:** Using the `i` command, you can check if the binary has Position Independent Code (PIC) enabled (`pic`) and if it has stack canaries (`canary`).
+
+```sh
+r2 MASTestApp
+[0x100007408]> i~canary,pic
+canary true
+pic true
+```
+
+The output shows that the binary has stack canaries and PIE enabled.
+
+**Check for ARC:** Using the `is` command, you can list the symbols in the binary and check for symbols that indicate the usage of Automatic Reference Counting (ARC). Common ARC symbols include:
+
+- `objc_autorelease`
+- `objc_retainAutorelease`
+- `objc_release`
+- `objc_retain`
+- `objc_retainAutoreleasedReturnValue`
+- `swift_release`
+- `swift_retain`
+
+An iOS binary does not need to have all of these symbols to be considered ARC-enabled, but the presence of some of them indicates that ARC is used.
+
+```sh
+[0x100007408]> is~release,retain
+80 0x0000790c 0x10000790c LOCAL FUNC 0 imp.objc_release_x20
+81 0x00007918 0x100007918 LOCAL FUNC 0 imp.objc_release_x24
+82 0x00007924 0x100007924 LOCAL FUNC 0 imp.objc_release_x25
+83 0x00007930 0x100007930 LOCAL FUNC 0 imp.objc_release_x27
+84 0x0000793c 0x10000793c LOCAL FUNC 0 imp.objc_release_x8
+85 0x00007948 0x100007948 LOCAL FUNC 0 imp.objc_retainAutoreleasedReturnValue
+86 0x00007954 0x100007954 LOCAL FUNC 0 imp.objc_retain_x23
+101 0x00007a08 0x100007a08 LOCAL FUNC 0 imp.swift_release
+102 0x00007a14 0x100007a14 LOCAL FUNC 0 imp.swift_retain
+```
+
+The output shows that the binary contains symbols indicating the usage of ARC.
+
+## @MASTG-TOOL-0074
+
+Objection has a command `ios info binary` which can be used to get information about the binary, including whether stack canaries and PIE are enabled.
+
+```sh
+com.yourcompany.PPClient on (iPhone: 13.2.3) [usb] # ios info binary
+Name Type Encrypted PIE ARC Canary Stack Exec RootSafe
+-------------------- ------- ----------- ----- ----- -------- ------------ ----------
+PayPal execute True True True True False False
+CardinalMobile dylib False False True True False False
+FraudForce dylib False False True True False False
+...
+```
+
+The output shows `PIE`, `ARC` and `Canary` with a value of `True` or `False`.
diff --git a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0204.md b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0204.md
index b9d64ed1a2..cd69d7a1c4 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
+best-practices: [MASTG-BEST-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..14a4f1b248 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
+best-practices: [MASTG-BEST-0001]
prerequisites:
- identify-sensitive-data
- identify-security-relevant-contexts
diff --git a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0221.md b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0221.md
index 92a31b6075..e0deedc183 100644
--- a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0221.md
+++ b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0221.md
@@ -25,3 +25,5 @@ The output should contain a list of locations where insecure symmetric encryptio
## Evaluation
The test case fails if you can find [insecure or deprecated](../../../Document/0x04g-Testing-Cryptography.md#Identifying-Insecure-and/or-Deprecated-Cryptographic-Algorithms) encryption algorithms being used.
+
+For example, [DES (Data Encryption Standard) and 3DES (Triple DES)](https://developer.android.com/privacy-and-security/risks/broken-cryptographic-algorithm), are deprecated by [NIST SP 800-131A Rev. 2](https://csrc.nist.gov/publications/detail/sp/800-131a/rev-2/final) due to vulnerabilities such as brute-force attacks and meet-in-the-middle attacks. Replace them with stronger alternatives, such as [AES-256](https://developer.android.com/privacy-and-security/cryptography#choose-algorithm), which is widely recognized as secure for modern apps.
diff --git a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0232.md b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0232.md
new file mode 100644
index 0000000000..cc1dc83f20
--- /dev/null
+++ b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0232.md
@@ -0,0 +1,45 @@
+---
+title: Weak Encryption Modes
+platform: android
+id: MASTG-TEST-0232
+type: [static, dynamic]
+weakness: MASWE-0020
+best-practices: [MASTG-BEST-0005]
+---
+
+## Overview
+
+To test for the [use of weak encryption modes](../../../Document/0x04g-Testing-Cryptography.md#weak-block-cipher-mode) in Android apps, we need to focus on methods from cryptographic frameworks and libraries that are used to configure and apply encryption modes.
+
+In Android development, the `Cipher` class from the Java Cryptography Architecture (JCA) is the primary API that allows you to specify the encryption mode for cryptographic operations. [`Cipher.getInstance`](https://developer.android.com/reference/javax/crypto/Cipher#getInstance(java.lang.String)) defines the transformation string, which includes the encryption algorithm, mode of operation, and padding scheme. The general format is `"Algorithm/Mode/Padding"`. For example:
+
+```kotlin
+Cipher.getInstance("AES/ECB/PKCS5Padding")
+```
+
+In this test we're going to focus on symmetric encryption modes such as [ECB (Electronic Codebook)](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_(ECB)) operate deterministically, dividing plaintext into blocks and encrypting them separately, which reveals patterns in the ciphertext. This makes it vulnerable to attacks like [known-plaintext attacks](https://en.wikipedia.org/wiki/Known-plaintext_attack) and [chosen-plaintext attacks](https://en.wikipedia.org/wiki/Chosen-plaintext_attack).
+
+For example, the following transformations are all [considered vulnerable](https://support.google.com/faqs/answer/10046138?hl=en):
+
+- "AES" (uses AES/ECB mode by [default](https://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#Cipher))
+- "AES/ECB/NoPadding"
+- "AES/ECB/PKCS5Padding"
+- "AES/ECB/ISO10126Padding"
+
+You can learn more about ECB and other modes in [NIST SP 800-38A - Recommendation for Block Cipher Modes of Operation: Methods and Techniques](https://csrc.nist.gov/pubs/sp/800/38/a/final). Also check the [Decision to Revise NIST SP 800-38A, Recommendation for Block Cipher Modes of Operation: Methods and Techniques](https://csrc.nist.gov/news/2023/decision-to-revise-nist-sp-800-38a) and [NIST IR 8459 Report on the Block Cipher Modes of Operation in the NIST SP 800-38 Series](https://nvlpubs.nist.gov/nistpubs/ir/2024/NIST.IR.8459.pdf) for the latest information.
+
+**Out of Scope**: Asymmetric encryption modes like RSA are out of scope for this test because they don't use block modes like ECB.
+
+In the transformation strings like `"RSA/ECB/OAEPPadding"` or `"RSA/ECB/PKCS1Padding"`, the inclusion of `ECB` in this context is misleading. Unlike symmetric ciphers, **RSA doesn't operate in block modes like ECB**. The `ECB` designation is a [placeholder in some cryptographic APIs](https://github.com/openjdk/jdk/blob/680ac2cebecf93e5924a441a5de6918cd7adf118/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java#L126) and doesn't imply that RSA uses ECB mode. Understanding these nuances helps prevent false positives.
+
+## Steps
+
+1. Run @MASTG-TECH-0014 with a tool such as @MASTG-TOOL-0110 on the app binary, or use @MASTG-TECH-0033 (dynamic analysis) with a tool like @MASTG-TOOL-0001, and look for cryptographic functions specifying the encryption mode to insecure modes.
+
+## Observation
+
+The output should contain a list of locations where insecure or deprecated encryption modes are used in cryptographic operations.
+
+## Evaluation
+
+The test case fails if any insecure encryption modes are identified in the app.
diff --git a/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0233.md b/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0233.md
new file mode 100644
index 0000000000..89e9acf586
--- /dev/null
+++ b/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0233.md
@@ -0,0 +1,39 @@
+---
+title: Hardcoded HTTP URLs
+platform: android
+id: MASTG-TEST-0233
+type: [static]
+weakness: MASWE-0050
+related-tests: [MASTG-TEST-0235, MASTG-TEST-0236, MASTG-TEST-0238]
+---
+
+## Overview
+
+An Android app may have hardcoded HTTP URLs embedded in the app binary, library binaries, or other resources within the APK. These URLs may indicate potential locations where the app communicates with servers over an unencrypted connection.
+
+!!! warning Limitations
+ The presence of HTTP URLs alone does not necessarily mean they are actively used for communication. Their usage may depend on runtime conditions, such as how the URLs are invoked and whether cleartext traffic is allowed in the app's configuration. For example, HTTP requests may fail if cleartext traffic is disabled in the AndroidManifest.xml or restricted by the Network Security Configuration. See @MASTG-TEST-0235.
+
+## Steps
+
+1. Reverse engineer the app (@MASTG-TECH-0017).
+2. Run a static analysis (@MASTG-TECH-0014) tool and look for any `http://` URLs.
+
+## Observation
+
+The output contains a list of URLs and their locations within the app.
+
+## Evaluation
+
+The test case fails if any HTTP URLs are confirmed to be used for communication.
+
+The presence of hardcoded HTTP URLs does not inherently mean they are used; their actual usage must be validated through careful inspection and testing:
+
+- **Reverse Engineering**: Inspect the code locations where the HTTP URLs are referenced. Determine if they are merely stored as constants or actively used to create HTTP requests through networking APIs like `HttpURLConnection` or `OkHttp`.
+- **Static Analysis**: Analyze the app's configuration to identify whether cleartext traffic is permitted. For example, check the AndroidManifest.xml for `android:usesCleartextTraffic="true"` or inspect the `network_security_config`. Refer to @MASTG-TEST-0235 for detailed guidance.
+
+Additionally, complement this static inspection with dynamic testing methods:
+
+- **Dynamic Analysis**: Use tools like Frida to hook into networking APIs at runtime. This can reveal how and when the HTTP URLs are used during execution. See @MASTG-TEST-0238 for more details.
+
+- **Network Traffic Interception**: Capture and analyze network traffic using tools like Burp Suite, mitmproxy, or Wireshark. This approach confirms whether the app connects to the identified HTTP URLs during real-world usage but depends on the tester's ability to exercise the app's functionality comprehensively. See @MASTG-TEST-0236.
diff --git a/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0234.md b/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0234.md
new file mode 100644
index 0000000000..b64a741bff
--- /dev/null
+++ b/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0234.md
@@ -0,0 +1,24 @@
+---
+title: SSLSockets not Properly Verifying Hostnames
+platform: android
+id: MASTG-TEST-0234
+type: [static]
+weakness: MASWE-0052
+---
+
+## Overview
+
+`SSLSocket` does not perform hostname verification by default unless the app explicitly uses [`HostnameVerifier.verify()`](https://developer.android.com/reference/javax/net/ssl/HostnameVerifier#verify(java.lang.String,%20javax.net.SSL.SSLSession)). See the ["Android documentation"](https://developer.android.com/privacy-and-security/security-ssl#WarningsSslSocket) and ["Unsafe HostnameVerifier"](https://developer.android.com/privacy-and-security/risks/unsafe-hostname) for more details.
+
+## Steps
+
+1. Reverse engineer the app (@MASTG-TECH-0017).
+2. Run a static analysis (@MASTG-TECH-0014) tool and look for all usages of `SSLSocket` and `HostnameVerifier`.
+
+## Observation
+
+The output contains a list of locations where `SSLSocket` and `HostnameVerifier` are used.
+
+## Evaluation
+
+The test case fails if hostname verification is missing or implemented incorrectly.
diff --git a/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0235.md b/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0235.md
new file mode 100644
index 0000000000..726a326d7c
--- /dev/null
+++ b/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0235.md
@@ -0,0 +1,43 @@
+---
+title: Android App Configurations Allowing Cleartext Traffic
+platform: android
+id: MASTG-TEST-0235
+type: [static]
+weakness: MASWE-0050
+---
+
+## Overview
+
+Since Android 9 (API level 28) cleartext HTTP traffic is blocked by default (thanks to the [default Network Security Configuration](../../../Document/0x05g-Testing-Network-Communication.md#default-configurations)) but there are multiple ways in which an application can still send it:
+
+- **AndroidManifest.xml**: Setting the [`android:usesCleartextTraffic`](https://developer.android.com/guide/topics/manifest/application-element#usesCleartextTraffic) attribute of the `` tag. Note that this flag is ignored in case the Network Security Configuration is configured.
+- **Network Security Configuration**: Setting the [`cleartextTrafficPermitted`](https://developer.android.com/privacy-and-security/security-config#CleartextTrafficPermitted) attribute to `true` on `` or `` elements.
+
+## Steps
+
+1. Reverse engineer the app (@MASTG-TECH-0017).
+2. Obtain the AndroidManifest.xml.
+3. Obtain the Network Security Configuration.
+4. Read the value of `usesCleartextTraffic` from the AndroidManifest.xml.
+5. Read the value of `cleartextTrafficPermitted` from the NSC `` element.
+6. Read the value of `cleartextTrafficPermitted` from the NSC `` elements.
+
+## Observation
+
+The output contains a list of configurations potentially allowing for cleartext traffic.
+
+## Evaluation
+
+The test case fails if cleartext traffic is permitted. This can happen if any of the following is true:
+
+1. The AndroidManifest sets `usesCleartextTraffic` to `true` and there's no NSC.
+2. The NSC sets `cleartextTrafficPermitted` to `true` in the ``.
+3. The NSC sets `cleartextTrafficPermitted` to `true` in any ``.
+
+**Note:** The test doesn't fail if the AndroidManifest sets `usesCleartextTraffic` to `true` and there's a NSC, even if it only has an empty `` element. For example:
+
+```xml
+
+
+
+```
diff --git a/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0236.md b/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0236.md
new file mode 100644
index 0000000000..5d1e262c63
--- /dev/null
+++ b/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0236.md
@@ -0,0 +1,39 @@
+---
+title: Cleartext Traffic Observed on the Network
+platform: network
+id: MASTG-TEST-0236
+type: [dynamic]
+weakness: MASWE-0050
+---
+
+## Overview
+
+This test intercepts the app's incoming and outgoing network traffic, and checks for any cleartext communication.
+Whilst the static checks can only show _potential_ cleartext traffic, this dynamic test shows all communication the application definitely makes.
+
+!!! warning Limitation
+ - Intercepting traffic on a network level will show all traffic _the device_ performs, not only the single app. Linking the traffic back to a specific app can be difficult, especially when more apps are installed on the device.
+ - Linking the intercepted traffic back to specific locations in the app can be difficult and requires manual analysis of the code.
+ - Dynamic analysis works best when you interact extensively with the app. But even then there could be corner cases which are difficult or impossible to execute on every device. The results from this test therefore are likely not exhaustive.
+
+## Steps
+
+You can use one of the following approaches:
+
+- Set up @MASTG-TECH-0010 (for Android) or @MASTG-TECH-0062 (for iOS) to capture all traffic.
+- Set up @MASTG-TECH-0011 (for Android) or @MASTG-TECH-0063 (for iOS) to capture all traffic.
+
+**Notes**:
+
+- Interception proxies will show HTTP(S) traffic only. You can, however, use some tool-specific plugins such as [Burp-non-HTTP-Extension](https://github.com/summitt/Burp-Non-HTTP-Extension) or other tools like @MASTG-TOOL-0078 to decode and visualize communication via XMPP and other protocols.
+- Some apps may not function correctly with proxies like Burp and OWASP ZAP because of certificate pinning. In such a scenario, you can still use basic network sniffing to detect cleartext traffic. Otherwise, you can try to disable pinning (see @MASTG-TECH-0012 for Android and @MASTG-TECH-0064 for iOS)
+
+## Observation
+
+The output contains the captured network traffic.
+
+## Evaluation
+
+The test case fails if any clear text traffic originates from the target app.
+
+**Note**: This can be challenging to determine because traffic can potentially come from any app on the device. See the [Overview](#overview) section.
diff --git a/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0237.md b/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0237.md
new file mode 100644
index 0000000000..19e9f3e012
--- /dev/null
+++ b/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0237.md
@@ -0,0 +1,9 @@
+---
+title: Cross-Platform Framework Configurations Allowing Cleartext Traffic
+platform: android
+id: MASTG-TEST-0237
+type: [static]
+weakness: MASWE-0050
+status: draft
+note: Cross-platform frameworks (e.g. Flutter, React native, ...), typically have their own implementations for HTTP libraries, where cleartext traffic can be allowed.
+---
diff --git a/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0238.md b/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0238.md
new file mode 100644
index 0000000000..e2751e676b
--- /dev/null
+++ b/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0238.md
@@ -0,0 +1,9 @@
+---
+title: Runtime Use of Network APIs Transmitting Cleartext Traffic
+platform: android
+id: MASTG-TEST-0238
+type: [dynamic]
+weakness: MASWE-0050
+status: draft
+note: Using Frida, you can trace all traffic of the app, mitigating the limitation of the dynamic analysis that you do not know which app, or which location is responsible for the traffic. Using Frida (and `.backtrace()`), you can be sure this is from the analyzed app, and know the exact location. A new limitation is then that all relevant networking APIs need to be instrumented.
+---
diff --git a/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0239.md b/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0239.md
new file mode 100644
index 0000000000..1202b89b76
--- /dev/null
+++ b/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0239.md
@@ -0,0 +1,9 @@
+---
+title: Using low-level APIs (e.g. Socket) to set up a custom HTTP connection
+platform: android
+id: MASTG-TEST-0239
+type: [static]
+weakness: MASWE-0050
+status: draft
+note: This test could also be for MASWE-0049 but we'd need to support multiple weaknesses.
+---
diff --git a/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0224.md b/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0224.md
index 9dc960fdb5..5e9e5f0a34 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
+best-practices: [MASTG-BEST-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-RESILIENCE/MASTG-TEST-0226.md b/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0226.md
index 3c335db745..64910a05b0 100644
--- a/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0226.md
+++ b/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0226.md
@@ -4,6 +4,7 @@ platform: android
id: MASTG-TEST-0226
type: [static]
weakness: MASWE-0067
+best-practices: [MASTG-BEST-0007]
---
## Overview
@@ -26,7 +27,3 @@ The output should explicitly show whether the `debuggable` flag is set (`true` o
## Evaluation
The test case fails if the `debuggable` flag is explicitly set to `true`. This indicates that the app is configured to allow debugging, which is inappropriate for production environments.
-
-To mitigate this issue, ensure the debuggable flag in the AndroidManifest.xml is set to false for all release builds.
-
-**Note:** Disabling debugging via the `debuggable` flag is an important first step but does not fully protect the app from advanced attacks. Skilled attackers can enable debugging through various means, such as binary patching (see @MASTG-TECH-0038) to allow attachment of a debugger or the use of binary instrumentation tools like @MASTG-TOOL-0001 to achieve similar capabilities. For apps requiring a higher level of security, consider implementing anti-debugging techniques as an additional layer of defense. Refer to @MASWE-0101 for detailed guidance.
diff --git a/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0227.md b/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0227.md
index 4eeba07266..defecedd9b 100644
--- a/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0227.md
+++ b/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0227.md
@@ -4,6 +4,7 @@ platform: android
id: MASTG-TEST-0227
type: [static]
weakness: MASWE-0067
+best-practices: [MASTG-BEST-0008]
---
## Overview
@@ -28,26 +29,3 @@ The output should list:
## Evaluation
The test case fails if `WebView.setWebContentsDebuggingEnabled(true)` is called unconditionally or in contexts where the `ApplicationInfo.FLAG_DEBUGGABLE` flag is not checked.
-
-To mitigate this issue:
-
-- Set `WebView.setWebContentsDebuggingEnabled` to `false` in production, or remove the calls entirely if they are unnecessary.
-- If WebView debugging is required during development, ensure it is enabled only when the app is in a debuggable state by [checking the `ApplicationInfo.FLAG_DEBUGGABLE` flag at runtime](https://developer.chrome.com/docs/devtools/remote-debugging/webviews/#configure_webviews_for_debugging).
-
-For example:
-
-```kotlin
-if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
- { WebView.setWebContentsDebuggingEnabled(true); }
-}
-```
-
-**Note:** Disabling WebView debugging this way helps protect an app already running on a device. For an attacker to exploit WebView debugging, they must have physical access to the device (e.g., a stolen or test device) or remote access through malware or other malicious means. Additionally, the device must typically be unlocked, and the attacker would need to know the device PIN, password, or biometric authentication to gain full control and connect debugging tools like `adb` or Chrome DevTools.
-
-However, disabling WebView debugging does not eliminate all attack vectors. An attacker could:
-
-1. Patch the app to add calls to these APIs (see @MASTG-TECH-0038), then repackage and re-sign it (see @MASTG-TECH-0039).
-2. Use runtime method hooking (see @MASTG-TECH-0043) to enable WebView debugging dynamically at runtime.
-
-Disabling WebView debugging serves as one layer of defense to reduce risks but should be combined with other security measures.
diff --git a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0203.md b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0203.md
index 81976d7b02..c4eab837aa 100644
--- a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0203.md
+++ b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0203.md
@@ -1,10 +1,11 @@
---
platform: android
-title: Leakage of Sensitive Data via Logging APIs
+title: Runtime Use of Logging APIs
id: MASTG-TEST-0203
apis: [Log, Logger, System.out.print, System.err.print, java.lang.Throwable#printStackTrace]
type: [dynamic]
weakness: MASWE-0001
+best-practices: [MASTG-BEST-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..9449efd522 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
+best-practices: [MASTG-BEST-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
new file mode 100644
index 0000000000..f8752dbb8d
--- /dev/null
+++ b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0231.md
@@ -0,0 +1,25 @@
+---
+platform: android
+title: References to Logging APIs
+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
+best-practices: [MASTG-BEST-0002]
+---
+
+## Overview
+
+This test verifies if an app uses logging APIs like `android.util.Log`, `Log`, `Logger`, `System.out.print`, `System.err.print`, and `java.lang.Throwable#printStackTrace`.
+
+## Steps
+
+1. Use either @MASTG-TECH-0014 with a tool such as @MASTG-TOOL-0110 to identify all logging APIs.
+
+## Observation
+
+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.
diff --git a/tests-beta/index.md b/tests-beta/index.md
index dc191ceca9..68e27e9359 100644
--- a/tests-beta/index.md
+++ b/tests-beta/index.md
@@ -1,6 +1,6 @@
---
hide: toc
-title: MASTG Tests (v2 - Beta)
+title: MASTG Tests (v2 Beta)
status: new
---
diff --git a/tests-beta/ios/MASVS-CODE/MASTG-TEST-0228.md b/tests-beta/ios/MASVS-CODE/MASTG-TEST-0228.md
new file mode 100644
index 0000000000..409e19e234
--- /dev/null
+++ b/tests-beta/ios/MASVS-CODE/MASTG-TEST-0228.md
@@ -0,0 +1,32 @@
+---
+title: Position Independent Code (PIC) not Enabled
+platform: ios
+id: MASTG-TEST-0228
+type: [static]
+weakness: MASWE-0116
+---
+
+## Overview
+
+[PIE (Position Independent Executables)](../../../Document/0x04h-Testing-Code-Quality.md/#position-independent-code) are designed to enhance security by allowing executables to be loaded at random memory addresses, mitigating certain types of attacks.
+
+In the context Mach-O file format of iOS applications:
+
+- PIE is applicable to executables with the `MH_EXECUTE` file type, which essentially means the main app binary (e.g. `YourApp.app/YourApp`).
+- Shared libraries with the `MH_DYLIB` file type (dylibs and frameworks) are inherently position-independent and do not utilize the `MH_PIE` flag.
+
+This test case checks if the main executable is compiled with PIE.
+
+## Steps
+
+1. Extract the application and identify the main binary (@MASTG-TECH-0054).
+2. Identify all shared libraries (@MASTG-TECH-0082).
+3. Run @MASTG-TECH-0118 on the main binary and grep for "pic" or the corresponding keyword used by the selected tool.
+
+## Observation
+
+The output should list if PIC is enabled or disabled.
+
+## Evaluation
+
+The test case fails if PIC is disabled.
diff --git a/tests-beta/ios/MASVS-CODE/MASTG-TEST-0229.md b/tests-beta/ios/MASVS-CODE/MASTG-TEST-0229.md
new file mode 100644
index 0000000000..fae0456e47
--- /dev/null
+++ b/tests-beta/ios/MASVS-CODE/MASTG-TEST-0229.md
@@ -0,0 +1,37 @@
+---
+title: Stack Canaries not enabled
+platform: ios
+id: MASTG-TEST-0229
+type: [static]
+weakness: MASWE-0116
+---
+
+## Overview
+
+This test case checks if the main binary or any libraries of the app are compiled without stack canaries and therefore lack [stack smashing protection](../../../Document/0x06i-Testing-Code-Quality-and-Build-Settings.md/#binary-protection-mechanisms), a common mitigation technique against buffer overflow attacks.
+
+This test applies to all binaries and libraries:
+
+- It is especially important for non-memory safe languages like Objective-C or C/C++.
+- For pure Swift apps, checking for stack canaries can be usually skipped, as Swift is considered a memory safe by design and conventional parsing techniques cannot detect stack canaries in Swift binaries (see the "canary – exceptions" section of this [blog post](https://sensepost.com/blog/2021/on-ios-binary-protections/)).
+
+To differentiate between Objective-C and Swift binaries, you can inspect the imports and linked libraries. Detecting Objective-C binaries is straightforward, but detecting pure Swift binaries is more challenging because depending on the Swift version and compiler settings, the binary may still contain Objective-C symbols or libraries. See the "identifying objc vs swift" section of this [blog post](https://sensepost.com/blog/2021/on-ios-binary-protections/) for more details.
+
+## Steps
+
+1. Extract the application and identify the main binary (@MASTG-TECH-0054).
+2. Identify all shared libraries (@MASTG-TECH-0082).
+3. Run @MASTG-TECH-0118 on the main binary and each shared library.
+4. If the output contains the symbol `__stack_chk_fail` it indicates stack canaries are enabled.
+
+## Observation
+
+The output should contain a list of symbols of the main binary and each shared library.
+
+## Evaluation
+
+The test case fails any binary or library is not purely Swift but does not contain methods indicating stack canaries like `objc_autorelease` or `objc_retainAutorelease`.
+
+**Note:** Checking for the `__stack_chk_fail` symbol only indicates that stack smashing protection is enabled somewhere in the app. While stack canaries are typically enabled or disabled for the entire binary, there may be corner cases where only parts of the application are protected. For example, if the app developer statically links a library with stack smashing protection enabled, but disables it for the entire application.
+
+If you want to be sure that specific security-critical methods are sufficiently protected, you need to reverse-engineer each of them and manually check for stack smashing protection.
diff --git a/tests-beta/ios/MASVS-CODE/MASTG-TEST-0230.md b/tests-beta/ios/MASVS-CODE/MASTG-TEST-0230.md
new file mode 100644
index 0000000000..cb9077d1b5
--- /dev/null
+++ b/tests-beta/ios/MASVS-CODE/MASTG-TEST-0230.md
@@ -0,0 +1,35 @@
+---
+title: Automatic Reference Counting (ARC) not enabled
+platform: ios
+id: MASTG-TEST-0230
+type: [static]
+weakness: MASWE-0116
+---
+
+## Overview
+
+This test case checks if [ARC (Automatic Reference Counting)](../../../Document/0x04h-Testing-Code-Quality.md/#automatic-reference-counting) is enabled in iOS apps. ARC is a compiler feature in Objective-C and Swift that automates memory management, reducing the likelihood of memory leaks and other related issues. Enabling ARC is crucial for maintaining the security and stability of iOS applications.
+
+- **Objective-C Code:** ARC can be enabled by compiling with the `-fobjc-arc` flag in Clang.
+- **Swift Code:** ARC is enabled by default.
+- **C/C++ Code:** ARC is not applicable, as it pertains specifically to Objective-C and Swift.
+
+When ARC is enabled, binaries will include symbols such as `objc_autorelease` or `objc_retainAutorelease`.
+
+## Steps
+
+1. Extract the application and identify the main binary (@MASTG-TECH-0054).
+2. Identify all shared libraries (@MASTG-TECH-0082).
+3. Run @MASTG-TECH-0118 on the main binary and each shared library looking for ARC symbols like `objc_autorelease` or `objc_retainAutorelease`.
+
+## Observation
+
+The output should contain a list of symbols of the main binary and each shared library.
+
+## Evaluation
+
+The test fails if any binary or library containing Objective-C or Swift code is missing ARC-related symbols. The presence of symbols such as `_objc_msgSend` (Objective-C) or `_swift_allocObject` (Swift) without corresponding ARC symbols indicates that ARC may not be enabled.
+
+**Note:** Checking for these symbols only indicates that ARC is enabled somewhere in the app. While ARC is typically enabled or disabled for the entire binary, there can be corner cases where only parts of the application or libraries are protected. For example, if the app developer statically links a library that has ARC enabled, but disables it for the entire application.
+
+If you want to be sure that specific security-critical methods are adequately protected, you need to reverse-engineer each of them and manually check for ARC, or request the source code from the developer.
diff --git a/tests/android/MASVS-NETWORK/MASTG-TEST-0019.md b/tests/android/MASVS-NETWORK/MASTG-TEST-0019.md
index a1098d4c94..03e31f9b83 100644
--- a/tests/android/MASVS-NETWORK/MASTG-TEST-0019.md
+++ b/tests/android/MASVS-NETWORK/MASTG-TEST-0019.md
@@ -8,6 +8,9 @@ title: Testing Data Encryption on the Network
masvs_v1_levels:
- L1
- L2
+status: deprecated
+covered_by: [MASTG-TEST-0233, MASTG-TEST-0234, MASTG-TEST-0235, MASTG-TEST-0236, MASTG-TEST-0237, MASTG-TEST-0238, MASTG-TEST-0239]
+deprecation_note: New version available in MASTG V2
---
## Overview
diff --git a/tests/android/MASVS-STORAGE/MASTG-TEST-0001.md b/tests/android/MASVS-STORAGE/MASTG-TEST-0001.md
index 7a967dc7b6..b54de8dea2 100644
--- a/tests/android/MASVS-STORAGE/MASTG-TEST-0001.md
+++ b/tests/android/MASVS-STORAGE/MASTG-TEST-0001.md
@@ -11,6 +11,7 @@ masvs_v1_levels:
- L2
status: deprecated
covered_by: [MASTG-TEST-0207, MASTG-TEST-0200]
+deprecation_note: New version available in MASTG V2
---
## Overview
diff --git a/tests/android/MASVS-STORAGE/MASTG-TEST-0003.md b/tests/android/MASVS-STORAGE/MASTG-TEST-0003.md
index 72614587f0..8ab71b51d0 100644
--- a/tests/android/MASVS-STORAGE/MASTG-TEST-0003.md
+++ b/tests/android/MASVS-STORAGE/MASTG-TEST-0003.md
@@ -8,6 +8,9 @@ title: Testing Logs for Sensitive Data
masvs_v1_levels:
- L1
- L2
+status: deprecated
+covered_by: [MASTG-TEST-0203, MASTG-TEST-0231]
+deprecation_note: New version available in MASTG V2
---
## Overview
diff --git a/tests/ios/MASVS-CODE/MASTG-TEST-0079.md b/tests/ios/MASVS-CODE/MASTG-TEST-0079.md
index 99e13b2d91..60a5418a92 100644
--- a/tests/ios/MASVS-CODE/MASTG-TEST-0079.md
+++ b/tests/ios/MASVS-CODE/MASTG-TEST-0079.md
@@ -20,7 +20,7 @@ All different flavors of object persistence share the following concerns:
- Need to guarantee the integrity of the information? Use an HMAC mechanism or sign the information stored. Always verify the HMAC/signature before processing the actual information stored in the objects.
- Make sure that keys used in the two notions above are safely stored in the KeyChain and well protected. See the chapter "[Data Storage on iOS](../../../Document/0x06d-Testing-Data-Storage.md)" for more details.
- Ensure that the data within the deserialized object is carefully validated before it is actively used (e.g., no exploit of business/application logic is possible).
-- Do not use persistence mechanisms that use [Runtime Reference](https://developer.apple.com/library/archive/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html "Objective-C Runtime Reference") to serialize/deserialize objects in high-risk applications, as the attacker might be able to manipulate the steps to execute business logic via this mechanism (see the chapter "[iOS Anti-Reversing Defenses](../../../Document/0x06j-Testing-Resiliency-Against-Reverse-Engineering.md)" for more details).
+- Do not use persistence mechanisms that use [Runtime Reference](https://developer.apple.com/documentation/objectivec/objective-c_runtime "Objective-C Runtime Reference") to serialize/deserialize objects in high-risk applications, as the attacker might be able to manipulate the steps to execute business logic via this mechanism (see the chapter "[iOS Anti-Reversing Defenses](../../../Document/0x06j-Testing-Resiliency-Against-Reverse-Engineering.md)" for more details).
- Note that in Swift 2 and beyond, a [Mirror](https://developer.apple.com/documentation/swift/mirror "Mirror") can be used to read parts of an object, but cannot be used to write against the object.
## Dynamic Analysis
diff --git a/tests/ios/MASVS-CODE/MASTG-TEST-0087.md b/tests/ios/MASVS-CODE/MASTG-TEST-0087.md
index 2924621d87..c29ad69325 100644
--- a/tests/ios/MASVS-CODE/MASTG-TEST-0087.md
+++ b/tests/ios/MASVS-CODE/MASTG-TEST-0087.md
@@ -8,6 +8,9 @@ title: Make Sure That Free Security Features Are Activated
masvs_v1_levels:
- L1
- L2
+status: deprecated
+covered_by: [MASTG-TEST-0228, MASTG-TEST-0229, MASTG-TEST-0230]
+deprecation_note: New version available in MASTG V2
---
## Overview
diff --git a/tests/ios/MASVS-RESILIENCE/MASTG-TEST-0081.md b/tests/ios/MASVS-RESILIENCE/MASTG-TEST-0081.md
index faa742cd70..cd2bac43b8 100644
--- a/tests/ios/MASVS-RESILIENCE/MASTG-TEST-0081.md
+++ b/tests/ios/MASVS-RESILIENCE/MASTG-TEST-0081.md
@@ -9,6 +9,7 @@ masvs_v1_levels:
- R
covered_by: [MASTG-TEST-0220]
status: deprecated
+deprecation_note: New version available in MASTG V2
---
## Overview
diff --git a/tests/ios/MASVS-RESILIENCE/MASTG-TEST-0083.md b/tests/ios/MASVS-RESILIENCE/MASTG-TEST-0083.md
index 4bd11fb1d0..ac8aeb8ac3 100644
--- a/tests/ios/MASVS-RESILIENCE/MASTG-TEST-0083.md
+++ b/tests/ios/MASVS-RESILIENCE/MASTG-TEST-0083.md
@@ -9,6 +9,7 @@ masvs_v1_levels:
- R
covered_by: [MASTG-TEST-0219]
status: deprecated
+deprecation_note: New version available in MASTG V2
---
## Overview
diff --git a/tools/android/MASTG-TOOL-0125.md b/tools/android/MASTG-TOOL-0125.md
new file mode 100644
index 0000000000..149196b36a
--- /dev/null
+++ b/tools/android/MASTG-TOOL-0125.md
@@ -0,0 +1,13 @@
+---
+title: Apkleaks
+platform: android
+source: https://github.com/dwisiswant0/apkleaks
+host:
+- windows
+- linux
+- macOS
+---
+
+[Apkleaks](https://github.com/dwisiswant0/apkleaks) is an open-source utility designed for static analysis of Android APK files, with a primary focus on identifying sensitive data such as API keys, URLs, AWS S3 buckets, and Firebase URLs. This tool automates the process of string analysis, facilitating the detection of hardcoded secrets and potential security vulnerabilities.
+
+It offers support for custom regular expression rules, enabling users to specify additional search criteria through a JSON configuration file [regexes.json](https://github.com/dwisiswant0/apkleaks/blob/master/config/regexes.json).
diff --git a/tools/ios/MASTG-TOOL-0056.md b/tools/ios/MASTG-TOOL-0056.md
index 747c1d303e..6404d6b2a4 100644
--- a/tools/ios/MASTG-TOOL-0056.md
+++ b/tools/ios/MASTG-TOOL-0056.md
@@ -1,17 +1,46 @@
---
title: Keychain-Dumper
platform: ios
-source: https://github.com/mechanico/Keychain-Dumper
+source: https://github.com/ptoomey3/Keychain-Dumper
---
-[Keychain-dumper](https://github.com/mechanico/Keychain-Dumper "keychain-dumper") is an iOS tool to check which keychain items are available to an attacker once an iOS device has been jailbroken. The easiest way to get the tool is to download the binary from its GitHub repo and run it from your device:
+[Keychain-dumper](https://github.com/ptoomey3/Keychain-Dumper/releases "keychain-dumper") is an iOS tool to check which keychain items are available to an attacker once an iOS device has been jailbroken. In order to use the tool on modern versions of iOS, you need to follow a few steps. First, download the latest release from [the Keychain-Dumper releases page](https://github.com/ptoomey3/Keychain-Dumper/releases), and unzip the package. Next, download the [updateEntitlements.sh](https://raw.githubusercontent.com/ptoomey3/Keychain-Dumper/refs/heads/master/updateEntitlements.sh) script to the same directory. Modify the first line (`KEYCHAIN_DUMPER_FOLDER=/usr/bin`) to say `KEYCHAIN_DUMPER_FOLDER=/var/jb/usr/bin` to be compatible with rootless jailbreaks. If your device has a rooted jailbreak (e.g. palera1n) you can skip this step.
```bash
-$ git clone https://github.com/ptoomey3/Keychain-Dumper
-$ scp -P 2222 Keychain-Dumper/keychain_dumper root@localhost:/tmp/
-$ ssh -p 2222 root@localhost
-iPhone:~ root# chmod +x /tmp/keychain_dumper
-iPhone:~ root# /tmp/keychain_dumper
+# Copy over the binary to /var/jb/usr/bin/
+scp keychain_dumper mobile@:/var/jb/usr/bin/
+
+# Copy over the updateEntitlements.sh script
+scp updateEntitlements.sh mobile@:/var/jb/usr/bin/
+
+# SSH into the device
+ssh mobile@
+
+# Go to the /var/jb/tmp directory and switch to root
+cd /var/jb/usr/bin & sudo su
+
+# Add executable permissions to both files
+chmod +x keychain_dumper
+chmod +x updateEntitlements.sh
+
+# Run updateEntitlements.sh
+./updateEntitlements.sh
+
+# Run keychain_dumper
+/var/jb/tmp/keychain_dump -h
+```
+
+By default, the script will give keychain_dump all the required entitlements to analyze the KeyChain for all installed applications. To focus on a single application, you can remove all unnecessary requirements:
+
+```bash
+# Extract entitlements
+ldid -e /var/jb/tmp/keychain_dump > ent.xml
+
+# Remove all non-needed entitlements from the segment
+nano ent.xml
+
+# Assign the entitlements again
+ldid -Sent.xml /var/jb/tmp/keychain_dump
```
For usage instructions please refer to the [Keychain-dumper](https://github.com/mechanico/Keychain-Dumper "keychain-dumper") GitHub page.