Skip to content

Commit

Permalink
Merge branch 'OWASP:master' into MASWE-0103
Browse files Browse the repository at this point in the history
  • Loading branch information
martinzigrai authored Dec 12, 2024
2 parents 701f402 + ae43160 commit 83357f2
Show file tree
Hide file tree
Showing 57 changed files with 880 additions and 146 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/0x06i-Testing-Code-Quality-and-Build-Settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions Document/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +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/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,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
---

Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
---
title: Comply with Privacy Regulations and Best Practices
alias: comply-with-privacy-regulations
id: MASTG-BEST-0003
platform: android
---

Expand Down
11 changes: 11 additions & 0 deletions best-practices/MASTG-BEST-0004.md
Original file line number Diff line number Diff line change
@@ -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.
12 changes: 12 additions & 0 deletions best-practices/MASTG-BEST-0005.md
Original file line number Diff line number Diff line change
@@ -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).
26 changes: 26 additions & 0 deletions best-practices/MASTG-BEST-0006.md
Original file line number Diff line number Diff line change
@@ -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
}
}
}
```
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
57 changes: 54 additions & 3 deletions docs/hooks/add-cross-references.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,30 +27,42 @@ 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():
weakness_id = test_meta.get("weakness")
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] = []
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
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
Loading

0 comments on commit 83357f2

Please sign in to comment.