Skip to content

Commit

Permalink
Merge branch 'master' into add-fastlane
Browse files Browse the repository at this point in the history
  • Loading branch information
cpholguera authored Dec 12, 2024
2 parents 6ef8896 + ae43160 commit c82d09b
Show file tree
Hide file tree
Showing 48 changed files with 474 additions and 149 deletions.
14 changes: 14 additions & 0 deletions Document/0x05h-Testing-Platform-Interaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand All @@ -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 |
Expand All @@ -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 |
Expand All @@ -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 |
Expand Down
2 changes: 1 addition & 1 deletion Document/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Start exploring the MASTG:
<a href="/MASTG/demos/" class="md-button md-button--primary" style="margin: 5px; min-width: 12em; text-align: center;">:material-flask-outline: Demos</a>
<a href="/MASTG/tools/" class="md-button md-button--primary" style="margin: 5px; min-width: 12em; text-align: center;">:octicons-tools-24: Tools</a>
<a href="/MASTG/apps/" class="md-button md-button--primary" style="margin: 5px; min-width: 12em; text-align: center;">:octicons-code-square-24: Apps</a>
<a href="/MASTG/mitigations/" class="md-button md-button--primary" style="margin: 5px; min-width: 12em; text-align: center;">:material-bandage: Mitigations (v2 Beta)</a>
<a href="/MASTG/best-practices/" class="md-button md-button--primary" style="margin: 5px; min-width: 12em; text-align: center;">:material-shield-check: Best Practices (v2 Beta)</a>

<span style="color: darkgray; font-size: small"> :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.</span>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Use Secure Random Number Generators APIs
title: Use Secure Random Number Generator APIs
alias: android-use-secure-random
id: MASTG-MITIG-0001
id: MASTG-BEST-0001
platform: android
---

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Remove Logging Code
alias: remove-logging-code
id: MASTG-MITIG-0002
id: MASTG-BEST-0002
platform: android
---

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Comply with Privacy Regulations and Best Practices
alias: comply-with-privacy-regulations
id: MASTG-MITIG-0003
id: MASTG-BEST-0003
platform: android
---

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Exclude Sensitive Data from Backups
alias: exclude-sensitive-data-from-backups
id: MASTG-MITIG-0004
id: MASTG-BEST-0004
platform: android
---

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Use Secure Encryption Modes
alias: use-secure-encryption-modes
id: MASTG-MITIG-0005
id: MASTG-BEST-0005
platform: android
---

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Use Up-to-Date APK Signing Schemes
alias: use-up-to-date-apk-signing-schemes
id: MASTG-MITIG-0006
id: MASTG-BEST-0006
platform: android
---

Expand Down
10 changes: 10 additions & 0 deletions best-practices/MASTG-BEST-0007.md
Original file line number Diff line number Diff line change
@@ -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.
29 changes: 29 additions & 0 deletions best-practices/MASTG-BEST-0008.md
Original file line number Diff line number Diff line change
@@ -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.
11 changes: 11 additions & 0 deletions best-practices/index.md
Original file line number Diff line number Diff line change
@@ -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.
2 changes: 1 addition & 1 deletion demos/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
hide: toc
title: MASTG Demos
title: MASTG Demos (v2 Beta)
status: new
---

Expand Down
67 changes: 34 additions & 33 deletions docs/hooks/add-cross-references.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,28 @@ def generate_cross_references():
cross_references = {
"weaknesses": {},
"tests": {},
"mitigations": {}
"best-practices": {}
}

for test_id, test_meta in tests.items():
weakness_id = test_meta.get("weakness")
test_path = test_meta.get("path")
test_title = test_meta.get("title")
test_platform = test_meta.get("platform")
mitigations_ids = test_meta.get("mitigations")
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 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})
# 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")
Expand Down Expand Up @@ -108,6 +108,20 @@ 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
Expand All @@ -123,35 +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}"

# 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')
if "MASTG-BEST" in path:
best_practice_id = meta.get('id')

# Add Tests section to mitigations as buttons
# Add Tests section to best_practices 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}} "
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{mitigations_section}"
markdown += f"\n\n{best_practices_section}"

return markdown
4 changes: 4 additions & 0 deletions docs/hooks/add-tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
21 changes: 16 additions & 5 deletions docs/hooks/create_dynamic_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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'] = '<span class="md-tag md-tag-icon md-tag--new">new</span><span style="display: none;">status:new</span>'
elif status == 'draft':
frontmatter['status'] = f'<a href="https://github.com/OWASP/owasp-mastg/issues?q=is%3Aissue+is%3Aopen+{test_id}" target="_blank"><span class="md-tag md-tag-icon md-tag--draft" style="min-width: 4em">draft</span></a><span style="display: none;">status:draft</span>'
elif status == 'deprecated':
frontmatter['status'] = '<span class="md-tag md-tag-icon md-tag--deprecated">deprecated</span><span style="display: none;">status:deprecated</span>'

tests.append(frontmatter)
return tests
Expand Down Expand Up @@ -263,13 +274,13 @@ def get_all_mitigations_beta():

mitigations = []

for file in glob.glob("docs/MASTG/mitigations/**/MASTG-MITIG-*.md", recursive=True):
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/mitigations/{os.path.splitext(os.path.relpath(file, 'docs/MASTG/mitigations'))[0]}"
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}"
Expand All @@ -291,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:
Expand All @@ -305,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]
Expand All @@ -322,7 +333,7 @@ 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"):
elif path.endswith("best-practices/index.md"):
# mitigations-beta/index.md

column_titles = {'id': 'ID', 'title': 'Title', 'platform': "Platform"}
Expand Down
Loading

0 comments on commit c82d09b

Please sign in to comment.