From 4e2e4efdfc6f56cd4449f32c7ed10006aa549b69 Mon Sep 17 00:00:00 2001 From: titze Date: Tue, 26 Nov 2024 08:46:35 +0100 Subject: [PATCH 01/18] Port MASTG test 0087 (by @guardsquare) (#3056) * Port MASTG test 0087 * Update texts * Update MASTG-TECH-0082: Enhance shared libraries identification and analysis * Add MASTG-TECH-0118: Obtaining compiler provided security features in iOS * Deprecate MASTG-TEST-0087 * Update MASTG-TEST-0x87 tests: Improve documentation on security features and testing steps for PIC, stack canaries, and ARC * Fix title * Fix typos and improve clarity on stack canaries and ARC --------- Co-authored-by: Carlos Holguera --- ...Testing-Code-Quality-and-Build-Settings.md | 2 +- techniques/android/MASTG-TECH-0115.md | 2 +- techniques/ios/MASTG-TECH-0082.md | 80 +++++++++++++------ techniques/ios/MASTG-TECH-0118.md | 64 +++++++++++++++ .../ios/MASVS-CODE/MASTG-TEST-0x87-1.md | 32 ++++++++ .../ios/MASVS-CODE/MASTG-TEST-0x87-2.md | 37 +++++++++ .../ios/MASVS-CODE/MASTG-TEST-0x87-3.md | 35 ++++++++ tests/ios/MASVS-CODE/MASTG-TEST-0087.md | 3 + 8 files changed, 230 insertions(+), 25 deletions(-) create mode 100644 techniques/ios/MASTG-TECH-0118.md create mode 100644 tests-beta/ios/MASVS-CODE/MASTG-TEST-0x87-1.md create mode 100644 tests-beta/ios/MASVS-CODE/MASTG-TEST-0x87-2.md create mode 100644 tests-beta/ios/MASVS-CODE/MASTG-TEST-0x87-3.md 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/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-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/ios/MASVS-CODE/MASTG-TEST-0x87-1.md b/tests-beta/ios/MASVS-CODE/MASTG-TEST-0x87-1.md new file mode 100644 index 0000000000..c78efc79c2 --- /dev/null +++ b/tests-beta/ios/MASVS-CODE/MASTG-TEST-0x87-1.md @@ -0,0 +1,32 @@ +--- +title: Position Independent Code (PIC) not Enabled +platform: ios +id: MASTG-TEST-0x87-1 +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-0x87-2.md b/tests-beta/ios/MASVS-CODE/MASTG-TEST-0x87-2.md new file mode 100644 index 0000000000..fbeff2deea --- /dev/null +++ b/tests-beta/ios/MASVS-CODE/MASTG-TEST-0x87-2.md @@ -0,0 +1,37 @@ +--- +title: Stack Canaries not enabled +platform: ios +id: MASTG-TEST-0x87-2 +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-0x87-3.md b/tests-beta/ios/MASVS-CODE/MASTG-TEST-0x87-3.md new file mode 100644 index 0000000000..25b9a6a43e --- /dev/null +++ b/tests-beta/ios/MASVS-CODE/MASTG-TEST-0x87-3.md @@ -0,0 +1,35 @@ +--- +title: Automatic Reference Counting (ARC) not enabled +platform: ios +id: MASTG-TEST-0x87-3 +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/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 From 69fd560a0de698c3b0e72968659f3dbd2b97cf70 Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Tue, 26 Nov 2024 09:06:07 +0100 Subject: [PATCH 02/18] fix IDs (#3075) --- .../ios/MASVS-CODE/{MASTG-TEST-0x87-1.md => MASTG-TEST-0228.md} | 2 +- .../ios/MASVS-CODE/{MASTG-TEST-0x87-2.md => MASTG-TEST-0229.md} | 2 +- .../ios/MASVS-CODE/{MASTG-TEST-0x87-3.md => MASTG-TEST-0230.md} | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename tests-beta/ios/MASVS-CODE/{MASTG-TEST-0x87-1.md => MASTG-TEST-0228.md} (98%) rename tests-beta/ios/MASVS-CODE/{MASTG-TEST-0x87-2.md => MASTG-TEST-0229.md} (99%) rename tests-beta/ios/MASVS-CODE/{MASTG-TEST-0x87-3.md => MASTG-TEST-0230.md} (98%) diff --git a/tests-beta/ios/MASVS-CODE/MASTG-TEST-0x87-1.md b/tests-beta/ios/MASVS-CODE/MASTG-TEST-0228.md similarity index 98% rename from tests-beta/ios/MASVS-CODE/MASTG-TEST-0x87-1.md rename to tests-beta/ios/MASVS-CODE/MASTG-TEST-0228.md index c78efc79c2..409e19e234 100644 --- a/tests-beta/ios/MASVS-CODE/MASTG-TEST-0x87-1.md +++ b/tests-beta/ios/MASVS-CODE/MASTG-TEST-0228.md @@ -1,7 +1,7 @@ --- title: Position Independent Code (PIC) not Enabled platform: ios -id: MASTG-TEST-0x87-1 +id: MASTG-TEST-0228 type: [static] weakness: MASWE-0116 --- diff --git a/tests-beta/ios/MASVS-CODE/MASTG-TEST-0x87-2.md b/tests-beta/ios/MASVS-CODE/MASTG-TEST-0229.md similarity index 99% rename from tests-beta/ios/MASVS-CODE/MASTG-TEST-0x87-2.md rename to tests-beta/ios/MASVS-CODE/MASTG-TEST-0229.md index fbeff2deea..fae0456e47 100644 --- a/tests-beta/ios/MASVS-CODE/MASTG-TEST-0x87-2.md +++ b/tests-beta/ios/MASVS-CODE/MASTG-TEST-0229.md @@ -1,7 +1,7 @@ --- title: Stack Canaries not enabled platform: ios -id: MASTG-TEST-0x87-2 +id: MASTG-TEST-0229 type: [static] weakness: MASWE-0116 --- diff --git a/tests-beta/ios/MASVS-CODE/MASTG-TEST-0x87-3.md b/tests-beta/ios/MASVS-CODE/MASTG-TEST-0230.md similarity index 98% rename from tests-beta/ios/MASVS-CODE/MASTG-TEST-0x87-3.md rename to tests-beta/ios/MASVS-CODE/MASTG-TEST-0230.md index 25b9a6a43e..cb9077d1b5 100644 --- a/tests-beta/ios/MASVS-CODE/MASTG-TEST-0x87-3.md +++ b/tests-beta/ios/MASVS-CODE/MASTG-TEST-0230.md @@ -1,7 +1,7 @@ --- title: Automatic Reference Counting (ARC) not enabled platform: ios -id: MASTG-TEST-0x87-3 +id: MASTG-TEST-0230 type: [static] weakness: MASWE-0116 --- From b3a082aed20c1ccfad12df73e69ff841dfffe82a Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Fri, 29 Nov 2024 10:01:40 +0100 Subject: [PATCH 03/18] Update MASTG-TEST-0221.md evaluation --- tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0221.md | 2 ++ 1 file changed, 2 insertions(+) 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. From 4f51d692077d23e15312ca1cfffc60f3532aa35f Mon Sep 17 00:00:00 2001 From: Jan Seredynski Date: Fri, 29 Nov 2024 17:19:06 +0100 Subject: [PATCH 04/18] Port MASTG-TEST-0003 (by @guardsquare) (#3059) * Port a static test * Add a deprecation note * fix IDs and titles * Refine logging API test content for clarity and accuracy --------- Co-authored-by: Carlos Holguera --- .../android/MASVS-STORAGE/MASTG-TEST-0203.md | 2 +- .../android/MASVS-STORAGE/MASTG-TEST-0231.md | 45 +++++++++++++++++++ .../android/MASVS-STORAGE/MASTG-TEST-0003.md | 2 + 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 tests-beta/android/MASVS-STORAGE/MASTG-TEST-0231.md diff --git a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0203.md b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0203.md index 81976d7b02..3636bf70a9 100644 --- a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0203.md +++ b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0203.md @@ -1,6 +1,6 @@ --- 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] 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..d8265b6aac --- /dev/null +++ b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0231.md @@ -0,0 +1,45 @@ +--- +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 +--- + +## 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. Ideally, a release build shouldn't use any logging functions, making it easier to assess sensitive data exposure. + +## Mitigation + +While preparing the production release, you can use tools like @MASTG-TOOL-0022 (included in Android Studio). To determine whether all logging functions from the `android.util.Log` class have been removed, check the ProGuard configuration file (proguard-rules.pro) for the following options (according to this [example of removing logging code](https://www.guardsquare.com/en/products/proguard/manual/examples#logging "ProGuard\'s example of removing logging code") and this article about [enabling ProGuard in an Android Studio project](https://developer.android.com/studio/build/shrink-code#enable "Android Developer - Enable shrinking, obfuscation, and optimization")): + +```default +-assumenosideeffects class android.util.Log +{ + public static boolean isLoggable(java.lang.String, int); + public static int v(...); + public static int i(...); + public static int w(...); + public static int d(...); + public static int e(...); + public static int wtf(...); +} +``` + +Note that the example above only ensures that calls to the Log class' methods will be removed. If the string that will be logged is dynamically constructed, the code that constructs the string may remain in the bytecode. + +Alternatively, you can implement a custom logging facility and disable it at once only for the release builds. diff --git a/tests/android/MASVS-STORAGE/MASTG-TEST-0003.md b/tests/android/MASVS-STORAGE/MASTG-TEST-0003.md index 72614587f0..14ed58ca89 100644 --- a/tests/android/MASVS-STORAGE/MASTG-TEST-0003.md +++ b/tests/android/MASVS-STORAGE/MASTG-TEST-0003.md @@ -8,6 +8,8 @@ title: Testing Logs for Sensitive Data masvs_v1_levels: - L1 - L2 +status: deprecated +covered_by: [MASTG-TEST-0203, MASTG-TEST-0231] --- ## Overview From 1da6272951537b913079e9e310cf609bfe47369b Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Fri, 29 Nov 2024 17:37:59 +0100 Subject: [PATCH 05/18] Add MASTG-TEST-0231 for weak encryption modes on Android (#3079) * Add MASTG-TEST-0231 for weak encryption modes in Android * fix typo * fix ID * Update tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0231.md * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0231.md --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../android/MASVS-CRYPTO/MASTG-TEST-0231.md | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0231.md diff --git a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0231.md b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0231.md new file mode 100644 index 0000000000..4c2e352a6b --- /dev/null +++ b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0231.md @@ -0,0 +1,52 @@ +--- +title: Weak Encryption Modes +platform: android +id: MASTG-TEST-0231 +type: [static, dynamic] +weakness: MASWE-0020 +--- + +## 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. + +## Mitigation + +Replace insecure encryption modes with secure block cipher modes such as [AES-GCM or AES-CCM](https://csrc.nist.gov/pubs/sp/800/38/d/final) which are authenticated encryption modes that provide confidentiality, integrity, and authenticity. + +We recommend avoiding CBC, which while being more secure than ECB, improper implementation, especially incorrect padding, can lead to vulnerabilities such as padding oracle attacks. + +For comprehensive guidance on implementing secure encryption modes in Android, refer to the official Android Developers documentation on [Cryptography](https://developer.android.com/privacy-and-security/cryptography). From 626957765711b2680ac9c9b262bf36480bd52cec Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Sat, 30 Nov 2024 10:10:29 +0100 Subject: [PATCH 06/18] fix ID (#3080) --- .../MASVS-CRYPTO/{MASTG-TEST-0231.md => MASTG-TEST-0232.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename tests-beta/android/MASVS-CRYPTO/{MASTG-TEST-0231.md => MASTG-TEST-0232.md} (99%) diff --git a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0231.md b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0232.md similarity index 99% rename from tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0231.md rename to tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0232.md index 4c2e352a6b..ed8e15f474 100644 --- a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0231.md +++ b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0232.md @@ -1,7 +1,7 @@ --- title: Weak Encryption Modes platform: android -id: MASTG-TEST-0231 +id: MASTG-TEST-0232 type: [static, dynamic] weakness: MASWE-0020 --- From 3ca954bdc9d7cb379f330ab3030ed18bec410c73 Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Mon, 2 Dec 2024 11:53:31 +0100 Subject: [PATCH 07/18] Add MASTG Mitigations support (#3081) * Rename and update mitigations using IDs and add index * Update mitigations to tests metadata * Add support for mitigations in cross-references and metadata generation * Add mitigations section to documentation and update navigation * Remove remediation section from MASTG-TEST-0204.md --- Document/index.md | 1 + docs/hooks/add-cross-references.py | 56 ++++++++++++++++++- docs/hooks/create_dynamic_tables.py | 29 ++++++++++ docs/hooks/resolve_references.py | 6 +- docs/hooks/update_titles.py | 2 +- ...e-secure-random.md => MASTG-MITIG-0001.md} | 2 + .../{use-proguard.md => MASTG-MITIG-0002.md} | 12 +++- ...acy-regulations.md => MASTG-MITIG-0003.md} | 2 + mitigations/MASTG-MITIG-0004.md | 11 ++++ mitigations/MASTG-MITIG-0005.md | 12 ++++ mitigations/MASTG-MITIG-0006.md | 26 +++++++++ mitigations/index.md | 11 ++++ mkdocs.yml | 5 ++ src/scripts/structure_mastg.sh | 2 +- .../android/MASVS-CRYPTO/MASTG-TEST-0204.md | 3 +- .../android/MASVS-CRYPTO/MASTG-TEST-0205.md | 3 +- .../android/MASVS-CRYPTO/MASTG-TEST-0232.md | 9 +-- .../MASVS-RESILIENCE/MASTG-TEST-0224.md | 21 +------ .../android/MASVS-STORAGE/MASTG-TEST-0203.md | 1 + .../android/MASVS-STORAGE/MASTG-TEST-0207.md | 3 - .../android/MASVS-STORAGE/MASTG-TEST-0216.md | 6 +- .../android/MASVS-STORAGE/MASTG-TEST-0231.md | 24 +------- 22 files changed, 176 insertions(+), 71 deletions(-) rename mitigations/{android-use-secure-random.md => MASTG-MITIG-0001.md} (93%) rename mitigations/{use-proguard.md => MASTG-MITIG-0002.md} (89%) rename mitigations/{comply-with-privacy-regulations.md => MASTG-MITIG-0003.md} (97%) create mode 100644 mitigations/MASTG-MITIG-0004.md create mode 100644 mitigations/MASTG-MITIG-0005.md create mode 100644 mitigations/MASTG-MITIG-0006.md create mode 100644 mitigations/index.md diff --git a/Document/index.md b/Document/index.md index 19bb81d2db..6d055ab71e 100644 --- a/Document/index.md +++ b/Document/index.md @@ -25,6 +25,7 @@ Start exploring the MASTG: :material-flask-outline: Demos :octicons-tools-24: Tools :octicons-code-square-24: Apps +:material-bandage: Mitigations (v2 Beta) :blue_heart:{ .pump } Support the project by purchasing the [OWASP MASTG on leanpub.com](https://leanpub.com/owasp-mastg). All funds raised through sales of this book go directly into the project budget and will be used to for technical editing and designing the book and fund production of future releases. diff --git a/docs/hooks/add-cross-references.py b/docs/hooks/add-cross-references.py index 6881a2b3e0..6b1a413d5c 100644 --- a/docs/hooks/add-cross-references.py +++ b/docs/hooks/add-cross-references.py @@ -27,13 +27,13 @@ def gather_metadata(directory, id_key): return metadata def generate_cross_references(): - weaknesses = gather_metadata("MASWE", "id") tests = gather_metadata("MASTG/tests-beta", "id") demos = gather_metadata("MASTG/demos", "id") cross_references = { "weaknesses": {}, - "tests": {} + "tests": {}, + "mitigations": {} } for test_id, test_meta in tests.items(): @@ -41,16 +41,28 @@ def generate_cross_references(): test_path = test_meta.get("path") test_title = test_meta.get("title") test_platform = test_meta.get("platform") + mitigations_ids = test_meta.get("mitigations") + + # Create cross-references for weaknesses listing all tests that reference each weakness ID if weakness_id: if weakness_id not in cross_references["weaknesses"]: cross_references["weaknesses"][weakness_id] = [] cross_references["weaknesses"][weakness_id].append({"id": test_id, "path": test_path, "title": test_title, "platform": test_platform}) - + + # Create cross-references for mitigations listing all tests that reference each mitigation ID + if mitigations_ids: + for mitigation_id in mitigations_ids: + if mitigation_id not in cross_references["mitigations"]: + cross_references["mitigations"][mitigation_id] = [] + cross_references["mitigations"][mitigation_id].append({"id": test_id, "path": test_path, "title": test_title, "platform": test_platform}) + for demo_id, demo_meta in demos.items(): test_id = demo_meta.get("test") demo_path = demo_meta.get("path") demo_title = demo_meta.get("title") demo_platform = demo_meta.get("platform") + + # Create cross-references for tests listing all demos that reference each test ID if test_id: if test_id not in cross_references["tests"]: cross_references["tests"][test_id] = [] @@ -81,6 +93,10 @@ def on_page_markdown(markdown, page, config, **kwargs): if "MASWE-" in path: weakness_id = meta.get('id') + + # Add Tests section to weaknesses as buttons + # ORIGIN: Cross-references from this script + if weakness_id in cross_references["weaknesses"]: tests = cross_references["weaknesses"][weakness_id] meta['tests'] = tests @@ -93,6 +109,10 @@ def on_page_markdown(markdown, page, config, **kwargs): if "MASTG-TEST-" in path: test_id = meta.get('id') + + # Add Demos section to tests as buttons + # ORIGIN: Cross-references from this script + if test_id in cross_references["tests"]: demos = cross_references["tests"][test_id] meta['demos'] = demos @@ -104,4 +124,34 @@ def on_page_markdown(markdown, page, config, **kwargs): markdown += f"\n\n{demos_section}" + # Add Mitigations section to tests as a bullet point list with IDs, links are resolved in a separate hook + # ORIGIN: Test metadata + + mitigations = meta.get('mitigations') + if mitigations: + mitigations_section = "## Mitigations\n\n" + for mitigation_id in mitigations: + mitigation_path = f"MASTG/mitigations/{mitigation_id}.md" + relPath = os.path.relpath(mitigation_path, os.path.dirname(path)) + mitigations_section += f"- @{mitigation_id}\n" + + markdown += f"\n\n{mitigations_section}" + + if "MASTG-MITIG" in path: + mitig_id = meta.get('id') + + # Add Tests section to mitigations as buttons + # ORIGIN: Cross-references from this script + + if mitig_id in cross_references["mitigations"]: + mitigations = cross_references["mitigations"].get(mitig_id) + meta['mitigations'] = mitigations + if mitigations: + mitigations_section = "## Tests\n\n" + for mitigation in mitigations: + relPath = os.path.relpath(mitigation['path'], os.path.dirname(path)) + mitigations_section += f"[{get_platform_icon(mitigation['platform'])} {mitigation['id']}: {mitigation['title']}]({relPath}){{: .mas-test-button}} " + + markdown += f"\n\n{mitigations_section}" + return markdown \ No newline at end of file diff --git a/docs/hooks/create_dynamic_tables.py b/docs/hooks/create_dynamic_tables.py index 431e4b6b3e..0984d3e65f 100644 --- a/docs/hooks/create_dynamic_tables.py +++ b/docs/hooks/create_dynamic_tables.py @@ -259,6 +259,25 @@ def get_all_demos_beta(): demos.append(frontmatter) return demos +def get_all_mitigations_beta(): + + mitigations = [] + + for file in glob.glob("docs/MASTG/mitigations/**/MASTG-MITIG-*.md", recursive=True): + with open(file, 'r') as f: + content = f.read() + + frontmatter = next(yaml.load_all(content, Loader=yaml.FullLoader)) + + frontmatter['path'] = f"/MASTG/mitigations/{os.path.splitext(os.path.relpath(file, 'docs/MASTG/mitigations'))[0]}" + mitigation_id = frontmatter['id'] + frontmatter['id'] = mitigation_id + frontmatter['title'] = f"@{mitigation_id}" + frontmatter['platform'] = get_platform_icon(frontmatter['platform']) + + mitigations.append(frontmatter) + return mitigations + def reorder_dict_keys(original_dict, key_order): return {key: original_dict.get(key, "N/A") for key in key_order} @@ -303,6 +322,16 @@ def on_page_markdown(markdown, page, **kwargs): return append_to_page(markdown, list_of_dicts_to_md_table(demos_beta_columns_reordered, column_titles)) + elif path.endswith("mitigations/index.md"): + # mitigations-beta/index.md + + column_titles = {'id': 'ID', 'title': 'Title', 'platform': "Platform"} + + mitigations_beta = get_all_mitigations_beta() + mitigations_beta_columns_reordered = [reorder_dict_keys(mitigation, column_titles.keys()) for mitigation in mitigations_beta] + + return append_to_page(markdown, list_of_dicts_to_md_table(mitigations_beta_columns_reordered, column_titles)) + elif path.endswith("tools/index.md"): # tools/index.md diff --git a/docs/hooks/resolve_references.py b/docs/hooks/resolve_references.py index 0210796265..d5aeef9c32 100644 --- a/docs/hooks/resolve_references.py +++ b/docs/hooks/resolve_references.py @@ -7,7 +7,7 @@ log = logging.getLogger('mkdocs') -mapping = {"TECH":{}, "TOOL":{}, "TEST": {}, "APP": {}, "MASWE": {}, "MASVS": {}, "DEMO": {}} +mapping = {"TECH":{}, "TOOL":{}, "TEST": {}, "APP": {}, "MASWE": {}, "MASVS": {}, "DEMO": {}, "MITIG": {}} @mkdocs.plugins.event_priority(-50) def on_page_markdown(markdown, page, config, **kwargs): @@ -17,7 +17,7 @@ def on_page_markdown(markdown, page, config, **kwargs): icons_for_text = {key.upper(): f":{value.replace('/', '-')}: " for key, value in icons.items()} - pageRefs = {"TECH": [], "TOOL": [], "TEST": [], "APP": [], "MASWE": [], "MASVS": [], "DEMO": []} + pageRefs = {"TECH": [], "TOOL": [], "TEST": [], "APP": [], "MASWE": [], "MASVS": [], "DEMO": [], "MITIG": []} def replaceReference(match): refType = match.group(2) @@ -57,7 +57,7 @@ def replaceReferenceMASVS(match): return f"_[{icon}{mapping[refType][match]['title']}]({mapping[refType][match]['file']})_" - updated_markdown = re.sub(r'@(MASTG-(TECH|TOOL|TEST|APP|DEMO)-\d{3,})', replaceReference, markdown) + updated_markdown = re.sub(r'@(MASTG-(TECH|TOOL|TEST|APP|DEMO|MITIG)-\d{3,})', replaceReference, markdown) updated_markdown = re.sub(r'@(MASWE-\d{3,})', replaceReferenceMASWE, updated_markdown) updated_markdown = re.sub(r'@(MASVS-\w+)', replaceReferenceMASVS, updated_markdown) diff --git a/docs/hooks/update_titles.py b/docs/hooks/update_titles.py index 3130c41119..06a89b6f71 100644 --- a/docs/hooks/update_titles.py +++ b/docs/hooks/update_titles.py @@ -13,7 +13,7 @@ def set_page_icon(page, config, component_type=None): def on_page_markdown(markdown, page, config, **kwargs): path = page.file.src_uri - if any(keyword in path for keyword in ["MASTG-TEST-", "MASTG-TOOL-", "MASTG-TECH-", "MASTG-APP-", "MASTG-DEMO-"]): + if any(keyword in path for keyword in ["MASTG-TEST-", "MASTG-TOOL-", "MASTG-TECH-", "MASTG-APP-", "MASTG-DEMO-", "MASTG-MITIG-"]): # TODO the component ID is the file basename without the extension; ensure that all components have id in the future page.meta['id'] = path.split('/')[-1].split('.')[0] component_type = page.meta['id'].split('-')[1].lower() diff --git a/mitigations/android-use-secure-random.md b/mitigations/MASTG-MITIG-0001.md similarity index 93% rename from mitigations/android-use-secure-random.md rename to mitigations/MASTG-MITIG-0001.md index ef3f9c5367..798356f212 100644 --- a/mitigations/android-use-secure-random.md +++ b/mitigations/MASTG-MITIG-0001.md @@ -1,5 +1,7 @@ --- title: Use Secure Random Number Generators APIs +alias: android-use-secure-random +id: MASTG-MITIG-0001 platform: android --- diff --git a/mitigations/use-proguard.md b/mitigations/MASTG-MITIG-0002.md similarity index 89% rename from mitigations/use-proguard.md rename to mitigations/MASTG-MITIG-0002.md index 992b0bccab..0896119abd 100644 --- a/mitigations/use-proguard.md +++ b/mitigations/MASTG-MITIG-0002.md @@ -1,8 +1,14 @@ --- -title: Use ProGuard to Remove Logging Code +title: Remove Logging Code +alias: remove-logging-code +id: MASTG-MITIG-0002 platform: android --- +Ideally, a release build shouldn't use any logging functions, making it easier to assess sensitive data exposure. + +## Using ProGuard + While preparing the production release, you can use tools like @MASTG-TOOL-0022 (included in Android Studio). To determine whether all logging functions from the `android.util.Log` class have been removed, check the ProGuard configuration file (proguard-rules.pro) for the following options (according to this [example of removing logging code](https://www.guardsquare.com/en/products/proguard/manual/examples#logging "ProGuard\'s example of removing logging code") and this article about [enabling ProGuard in an Android Studio project](https://developer.android.com/studio/build/shrink-code#enable "Android Developer - Enable shrinking, obfuscation, and optimization")): ```default @@ -57,3 +63,7 @@ SecureLog.v("Private key [byte format]: ", key); ``` Then configure ProGuard to strip its calls. + +## Custom Logging + +You can implement a custom logging facility and disable it at once only for the release builds. diff --git a/mitigations/comply-with-privacy-regulations.md b/mitigations/MASTG-MITIG-0003.md similarity index 97% rename from mitigations/comply-with-privacy-regulations.md rename to mitigations/MASTG-MITIG-0003.md index 5ceb5583c3..2e2d66a90b 100644 --- a/mitigations/comply-with-privacy-regulations.md +++ b/mitigations/MASTG-MITIG-0003.md @@ -1,5 +1,7 @@ --- title: Comply with Privacy Regulations and Best Practices +alias: comply-with-privacy-regulations +id: MASTG-MITIG-0003 platform: android --- diff --git a/mitigations/MASTG-MITIG-0004.md b/mitigations/MASTG-MITIG-0004.md new file mode 100644 index 0000000000..bd40281e57 --- /dev/null +++ b/mitigations/MASTG-MITIG-0004.md @@ -0,0 +1,11 @@ +--- +title: Exclude Sensitive Data from Backups +alias: exclude-sensitive-data-from-backups +id: MASTG-MITIG-0004 +platform: android +--- + +For the sensitive files found, instruct the system to exclude them from the backup: + +- If you are using Auto Backup, mark them with the `exclude` tag in `backup_rules.xml` (for Android 11 or lower using `android:fullBackupContent`) or `data_extraction_rules.xml` (for Android 12 and higher using `android:dataExtractionRules`), depending on the target API. Make sure to use both the `cloud-backup` and `device-transfer` parameters. +- If you are using the key-value approach, set up your [BackupAgent](https://developer.android.com/identity/data/keyvaluebackup#BackupAgent) accordingly. diff --git a/mitigations/MASTG-MITIG-0005.md b/mitigations/MASTG-MITIG-0005.md new file mode 100644 index 0000000000..dc7abe4578 --- /dev/null +++ b/mitigations/MASTG-MITIG-0005.md @@ -0,0 +1,12 @@ +--- +title: Use Secure Encryption Modes +alias: use-secure-encryption-modes +id: MASTG-MITIG-0005 +platform: android +--- + +Replace insecure encryption modes with secure block cipher modes such as [AES-GCM or AES-CCM](https://csrc.nist.gov/pubs/sp/800/38/d/final) which are authenticated encryption modes that provide confidentiality, integrity, and authenticity. + +We recommend avoiding CBC, which while being more secure than ECB, improper implementation, especially incorrect padding, can lead to vulnerabilities such as padding oracle attacks. + +For comprehensive guidance on implementing secure encryption modes in Android, refer to the official Android Developers documentation on [Cryptography](https://developer.android.com/privacy-and-security/cryptography). diff --git a/mitigations/MASTG-MITIG-0006.md b/mitigations/MASTG-MITIG-0006.md new file mode 100644 index 0000000000..19715ead00 --- /dev/null +++ b/mitigations/MASTG-MITIG-0006.md @@ -0,0 +1,26 @@ +--- +title: Use Up-to-Date APK Signing Schemes +alias: use-up-to-date-apk-signing-schemes +id: MASTG-MITIG-0006 +platform: android +--- + +Ensure that the app is signed with at least the v2 or v3 APK signing scheme, as these provide comprehensive integrity checks and protect the entire APK from tampering. For optimal security and compatibility, consider using v3, which also supports key rotation. + +Optionally, you can add v4 signing to enable faster [incremental updates](https://developer.android.com/about/versions/11/features#incremental) in Android 11 and above, but v4 alone does not provide security protections and should be used alongside v2 or v3. + +The signing configuration can be managed through Android Studio or the `signingConfigs` section in `build.gradle` or `build.gradle.kts`. To activate both the v3 and v4 schemes, the following values must be set: + +```default +// build.gradle +android { + ... + signingConfigs { + config { + ... + enableV3Signing true + enableV4Signing true + } + } +} +``` diff --git a/mitigations/index.md b/mitigations/index.md new file mode 100644 index 0000000000..84f29f3fec --- /dev/null +++ b/mitigations/index.md @@ -0,0 +1,11 @@ +--- +hide: toc +title: Mitigations (v2 - Beta) +status: new +--- + +??? info "About the MASTG Mitigations" + + The MASTG Mitigations are a collection of specific strategies and best practices that can be used to mitigate security and privacy risks in mobile apps. + + Each mitigation is designed to be simple and focused and may apply to one or multiple tests in the MASTG. diff --git a/mkdocs.yml b/mkdocs.yml index e323f8c2c1..066b600d24 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -149,6 +149,9 @@ nav: # - ... | flat | MASTG/demos/ios/MASVS-RESILIENCE/**/MASTG-DEMO-*.md # - MASVS-PRIVACY: # - ... | flat | MASTG/demos/ios/MASVS-PRIVACY/**/MASTG-DEMO-*.md + - Mitigations: + - MASTG/mitigations/index.md + - ... | flat | MASTG/mitigations/*.md - Techniques: - MASTG/techniques/index.md - Generic: @@ -249,6 +252,7 @@ theme: app: octicons/code-square-24 demo: material/flask-outline tech: material/magic-staff # fontawesome/solid/wand-magic-sparkles + mitig: material/bandage maswe: octicons/shield-24 masvs: simple/owasp features: @@ -374,6 +378,7 @@ extra: tech: tech maswe: maswe masvs: masvs + mitig: mitig status: draft: This page is in draft. new: New in this beta! diff --git a/src/scripts/structure_mastg.sh b/src/scripts/structure_mastg.sh index 1953bb2c3f..0792b56c07 100755 --- a/src/scripts/structure_mastg.sh +++ b/src/scripts/structure_mastg.sh @@ -4,7 +4,7 @@ set -euo pipefail mkdir -p docs/MASTG mkdir -p docs/MASWE -directories=("tests" "techniques" "tools" "apps" "tests-beta" "demos" "rules") +directories=("tests" "techniques" "tools" "apps" "tests-beta" "demos" "rules" "mitigations") for dir in "${directories[@]}"; do rm -rf "docs/MASTG/$dir" diff --git a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0204.md b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0204.md index b9d64ed1a2..f633d35022 100644 --- a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0204.md +++ b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0204.md @@ -3,8 +3,7 @@ platform: android title: Insecure Random API Usage id: MASTG-TEST-0204 type: [static] -mitigations: -- android-use-secure-random +mitigations: [MASTG-MITIG-0001] prerequisites: - identify-sensitive-data - identify-security-relevant-contexts diff --git a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0205.md b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0205.md index 1a2d1cfa05..94aa4b7ede 100644 --- a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0205.md +++ b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0205.md @@ -3,8 +3,7 @@ platform: android title: Non-random Sources Usage id: MASTG-TEST-0205 type: [static] -mitigations: -- android-use-secure-random +mitigations: [MASTG-MITIG-0001] prerequisites: - identify-sensitive-data - identify-security-relevant-contexts diff --git a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0232.md b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0232.md index ed8e15f474..594a1a4395 100644 --- a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0232.md +++ b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0232.md @@ -4,6 +4,7 @@ platform: android id: MASTG-TEST-0232 type: [static, dynamic] weakness: MASWE-0020 +mitigations: [MASTG-MITIG-0005] --- ## Overview @@ -42,11 +43,3 @@ The output should contain a list of locations where insecure or deprecated encry ## Evaluation The test case fails if any insecure encryption modes are identified in the app. - -## Mitigation - -Replace insecure encryption modes with secure block cipher modes such as [AES-GCM or AES-CCM](https://csrc.nist.gov/pubs/sp/800/38/d/final) which are authenticated encryption modes that provide confidentiality, integrity, and authenticity. - -We recommend avoiding CBC, which while being more secure than ECB, improper implementation, especially incorrect padding, can lead to vulnerabilities such as padding oracle attacks. - -For comprehensive guidance on implementing secure encryption modes in Android, refer to the official Android Developers documentation on [Cryptography](https://developer.android.com/privacy-and-security/cryptography). diff --git a/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0224.md b/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0224.md index 9dc960fdb5..c2c52815f0 100644 --- a/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0224.md +++ b/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0224.md @@ -5,6 +5,7 @@ id: MASTG-TEST-0224 type: [static] available_since: 24 weakness: MASWE-0104 +mitigations: [MASTG-MITIG-0006] --- ## Overview @@ -27,23 +28,3 @@ The output should contain the value of the `minSdkVersion` attribute and the use ## Evaluation The test case fails if the app has a `minSdkVersion` attribute of 24 and above, and only the v1 signature scheme is enabled. - -To mitigate this issue, ensure that the app is signed with at least the v2 or v3 APK signing scheme, as these provide comprehensive integrity checks and protect the entire APK from tampering. For optimal security and compatibility, consider using v3, which also supports key rotation. - -Optionally, you can add v4 signing to enable faster [incremental updates](https://developer.android.com/about/versions/11/features#incremental) in Android 11 and above, but v4 alone does not provide security protections and should be used alongside v2 or v3. - -The signing configuration can be managed through Android Studio or the `signingConfigs` section in `build.gradle` or `build.gradle.kts`. To activate both the v3 and v4 schemes, the following values must be set: - -```default -// build.gradle -android { - ... - signingConfigs { - config { - ... - enableV3Signing true - enableV4Signing true - } - } -} -``` diff --git a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0203.md b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0203.md index 3636bf70a9..11e52b98e0 100644 --- a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0203.md +++ b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0203.md @@ -5,6 +5,7 @@ id: MASTG-TEST-0203 apis: [Log, Logger, System.out.print, System.err.print, java.lang.Throwable#printStackTrace] type: [dynamic] weakness: MASWE-0001 +mitigations: [MASTG-MITIG-0002] --- ## Overview diff --git a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0207.md b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0207.md index ca90d2ad8a..fc8e6c4d35 100644 --- a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0207.md +++ b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0207.md @@ -3,9 +3,6 @@ platform: android title: Data Stored in the App Sandbox at Runtime id: MASTG-TEST-0207 type: [dynamic, filesystem] -mitigations: -- android-use-keystore -- android-use-androidx-security prerequisites: - identify-sensitive-data weakness: MASWE-0006 diff --git a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0216.md b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0216.md index f8fcb221ae..7e242275f3 100644 --- a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0216.md +++ b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0216.md @@ -4,6 +4,7 @@ title: Sensitive Data Not Excluded From Backup id: MASTG-TEST-0216 type: [dynamic, filesystem] weakness: MASWE-0004 +mitigations: [MASTG-MITIG-0004] --- ## Overview @@ -32,8 +33,3 @@ The output should contain a list of files that are restored from the backup. ## Evaluation The test fails if any of the files are considered sensitive. - -For the sensitive files found, instruct the system to exclude them from the backup: - -- If you are using Auto Backup, mark them with the `exclude` tag in `backup_rules.xml` (for Android 11 or lower using `android:fullBackupContent`) or `data_extraction_rules.xml` (for Android 12 and higher using `android:dataExtractionRules`), depending on the target API. Make sure to use both the `cloud-backup` and `device-transfer` parameters. -- If you are using the key-value approach, set up your [BackupAgent](https://developer.android.com/identity/data/keyvaluebackup#BackupAgent) accordingly. diff --git a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0231.md b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0231.md index d8265b6aac..ff4c9b41af 100644 --- a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0231.md +++ b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0231.md @@ -5,6 +5,7 @@ id: MASTG-TEST-0231 apis: [Log, Logger, System.out.print, System.err.print, java.lang.Throwable#printStackTrace, android.util.Log] type: [static] weakness: MASWE-0001 +mitigations: [MASTG-MITIG-0002] --- ## Overview @@ -21,25 +22,4 @@ The output should contain a list of locations where logging APIs are used. ## Evaluation -The test fails if an app logs sensitive information from any of the listed locations. Ideally, a release build shouldn't use any logging functions, making it easier to assess sensitive data exposure. - -## Mitigation - -While preparing the production release, you can use tools like @MASTG-TOOL-0022 (included in Android Studio). To determine whether all logging functions from the `android.util.Log` class have been removed, check the ProGuard configuration file (proguard-rules.pro) for the following options (according to this [example of removing logging code](https://www.guardsquare.com/en/products/proguard/manual/examples#logging "ProGuard\'s example of removing logging code") and this article about [enabling ProGuard in an Android Studio project](https://developer.android.com/studio/build/shrink-code#enable "Android Developer - Enable shrinking, obfuscation, and optimization")): - -```default --assumenosideeffects class android.util.Log -{ - public static boolean isLoggable(java.lang.String, int); - public static int v(...); - public static int i(...); - public static int w(...); - public static int d(...); - public static int e(...); - public static int wtf(...); -} -``` - -Note that the example above only ensures that calls to the Log class' methods will be removed. If the string that will be logged is dynamically constructed, the code that constructs the string may remain in the bytecode. - -Alternatively, you can implement a custom logging facility and disable it at once only for the release builds. +The test fails if an app logs sensitive information from any of the listed locations. From 5d16d052420abc346983c0c3d37d9682ebf223cb Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Wed, 4 Dec 2024 16:55:42 +0100 Subject: [PATCH 08/18] rename mitigations to best-practices (#3085) --- Document/index.md | 2 +- .../MASTG-BEST-0001.md | 4 +- .../MASTG-BEST-0002.md | 2 +- .../MASTG-BEST-0003.md | 2 +- .../MASTG-BEST-0004.md | 2 +- .../MASTG-BEST-0005.md | 2 +- .../MASTG-BEST-0006.md | 2 +- best-practices/index.md | 11 +++ demos/index.md | 2 +- docs/hooks/add-cross-references.py | 67 ++++++++--------- docs/hooks/create_dynamic_tables.py | 6 +- docs/hooks/maswe-beta-banner.py | 2 +- docs/hooks/resolve_references.py | 6 +- docs/hooks/update_titles.py | 2 +- mitigations/index.md | 11 --- mkdocs.yml | 74 +++++++++---------- src/scripts/structure_mastg.sh | 2 +- .../android/MASVS-CRYPTO/MASTG-TEST-0204.md | 2 +- .../android/MASVS-CRYPTO/MASTG-TEST-0205.md | 2 +- .../android/MASVS-CRYPTO/MASTG-TEST-0232.md | 2 +- .../MASVS-RESILIENCE/MASTG-TEST-0224.md | 2 +- .../android/MASVS-STORAGE/MASTG-TEST-0203.md | 2 +- .../android/MASVS-STORAGE/MASTG-TEST-0216.md | 2 +- .../android/MASVS-STORAGE/MASTG-TEST-0231.md | 2 +- tests-beta/index.md | 2 +- 25 files changed, 108 insertions(+), 107 deletions(-) rename mitigations/MASTG-MITIG-0001.md => best-practices/MASTG-BEST-0001.md (91%) rename mitigations/MASTG-MITIG-0002.md => best-practices/MASTG-BEST-0002.md (99%) rename mitigations/MASTG-MITIG-0003.md => best-practices/MASTG-BEST-0003.md (99%) rename mitigations/MASTG-MITIG-0004.md => best-practices/MASTG-BEST-0004.md (97%) rename mitigations/MASTG-MITIG-0005.md => best-practices/MASTG-BEST-0005.md (97%) rename mitigations/MASTG-MITIG-0006.md => best-practices/MASTG-BEST-0006.md (97%) create mode 100644 best-practices/index.md delete mode 100644 mitigations/index.md diff --git a/Document/index.md b/Document/index.md index 6d055ab71e..d895a8b0d5 100644 --- a/Document/index.md +++ b/Document/index.md @@ -25,7 +25,7 @@ Start exploring the MASTG: :material-flask-outline: Demos :octicons-tools-24: Tools :octicons-code-square-24: Apps -:material-bandage: Mitigations (v2 Beta) +: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/MASTG-MITIG-0001.md b/best-practices/MASTG-BEST-0001.md similarity index 91% rename from mitigations/MASTG-MITIG-0001.md rename to best-practices/MASTG-BEST-0001.md index 798356f212..d8900086f5 100644 --- a/mitigations/MASTG-MITIG-0001.md +++ b/best-practices/MASTG-BEST-0001.md @@ -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 --- diff --git a/mitigations/MASTG-MITIG-0002.md b/best-practices/MASTG-BEST-0002.md similarity index 99% rename from mitigations/MASTG-MITIG-0002.md rename to best-practices/MASTG-BEST-0002.md index 0896119abd..dd29b6ba13 100644 --- a/mitigations/MASTG-MITIG-0002.md +++ b/best-practices/MASTG-BEST-0002.md @@ -1,7 +1,7 @@ --- title: Remove Logging Code alias: remove-logging-code -id: MASTG-MITIG-0002 +id: MASTG-BEST-0002 platform: android --- diff --git a/mitigations/MASTG-MITIG-0003.md b/best-practices/MASTG-BEST-0003.md similarity index 99% rename from mitigations/MASTG-MITIG-0003.md rename to best-practices/MASTG-BEST-0003.md index 2e2d66a90b..0b701af0d3 100644 --- a/mitigations/MASTG-MITIG-0003.md +++ b/best-practices/MASTG-BEST-0003.md @@ -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 --- diff --git a/mitigations/MASTG-MITIG-0004.md b/best-practices/MASTG-BEST-0004.md similarity index 97% rename from mitigations/MASTG-MITIG-0004.md rename to best-practices/MASTG-BEST-0004.md index bd40281e57..f84628deeb 100644 --- a/mitigations/MASTG-MITIG-0004.md +++ b/best-practices/MASTG-BEST-0004.md @@ -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 --- diff --git a/mitigations/MASTG-MITIG-0005.md b/best-practices/MASTG-BEST-0005.md similarity index 97% rename from mitigations/MASTG-MITIG-0005.md rename to best-practices/MASTG-BEST-0005.md index dc7abe4578..b2bc38bb77 100644 --- a/mitigations/MASTG-MITIG-0005.md +++ b/best-practices/MASTG-BEST-0005.md @@ -1,7 +1,7 @@ --- title: Use Secure Encryption Modes alias: use-secure-encryption-modes -id: MASTG-MITIG-0005 +id: MASTG-BEST-0005 platform: android --- diff --git a/mitigations/MASTG-MITIG-0006.md b/best-practices/MASTG-BEST-0006.md similarity index 97% rename from mitigations/MASTG-MITIG-0006.md rename to best-practices/MASTG-BEST-0006.md index 19715ead00..aeb4ce4af1 100644 --- a/mitigations/MASTG-MITIG-0006.md +++ b/best-practices/MASTG-BEST-0006.md @@ -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 --- diff --git a/best-practices/index.md b/best-practices/index.md new file mode 100644 index 0000000000..b4b9052ae3 --- /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 6b1a413d5c..680fbe6642 100644 --- a/docs/hooks/add-cross-references.py +++ b/docs/hooks/add-cross-references.py @@ -33,7 +33,7 @@ def generate_cross_references(): cross_references = { "weaknesses": {}, "tests": {}, - "mitigations": {} + "best-practices": {} } for test_id, test_meta in tests.items(): @@ -41,7 +41,7 @@ def generate_cross_references(): test_path = test_meta.get("path") test_title = test_meta.get("title") test_platform = test_meta.get("platform") - mitigations_ids = test_meta.get("mitigations") + best_practices_ids = test_meta.get("best-practices") # Create cross-references for weaknesses listing all tests that reference each weakness ID if weakness_id: @@ -49,12 +49,12 @@ def generate_cross_references(): 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") @@ -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 @@ -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 \ No newline at end of file diff --git a/docs/hooks/create_dynamic_tables.py b/docs/hooks/create_dynamic_tables.py index 0984d3e65f..a7a5848bb9 100644 --- a/docs/hooks/create_dynamic_tables.py +++ b/docs/hooks/create_dynamic_tables.py @@ -263,13 +263,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}" @@ -322,7 +322,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"} diff --git a/docs/hooks/maswe-beta-banner.py b/docs/hooks/maswe-beta-banner.py index 1a6dd53dde..b06a271761 100644 --- a/docs/hooks/maswe-beta-banner.py +++ b/docs/hooks/maswe-beta-banner.py @@ -117,7 +117,7 @@ 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': diff --git a/docs/hooks/resolve_references.py b/docs/hooks/resolve_references.py index d5aeef9c32..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": {}, "MITIG": {}} +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": [], "MITIG": []} + 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|MITIG)-\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 06a89b6f71..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-", "MASTG-MITIG-"]): + 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/mitigations/index.md b/mitigations/index.md deleted file mode 100644 index 84f29f3fec..0000000000 --- a/mitigations/index.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -hide: toc -title: Mitigations (v2 - Beta) -status: new ---- - -??? info "About the MASTG Mitigations" - - The MASTG Mitigations are a collection of specific strategies and best practices that can be used to mitigate security and privacy risks in mobile apps. - - Each mitigation is designed to be simple and focused and may apply to one or multiple tests in the MASTG. diff --git a/mkdocs.yml b/mkdocs.yml index 066b600d24..cb403224af 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,26 +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 - - Mitigations: - - MASTG/mitigations/index.md - - ... | flat | MASTG/mitigations/*.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: @@ -252,7 +252,7 @@ theme: app: octicons/code-square-24 demo: material/flask-outline tech: material/magic-staff # fontawesome/solid/wand-magic-sparkles - mitig: material/bandage + best: material/shield-check maswe: octicons/shield-24 masvs: simple/owasp features: @@ -378,7 +378,7 @@ extra: tech: tech maswe: maswe masvs: masvs - mitig: mitig + best: best status: draft: This page is in draft. new: New in this beta! diff --git a/src/scripts/structure_mastg.sh b/src/scripts/structure_mastg.sh index 0792b56c07..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" "mitigations") +directories=("tests" "techniques" "tools" "apps" "tests-beta" "demos" "rules" "best-practices") for dir in "${directories[@]}"; do rm -rf "docs/MASTG/$dir" diff --git a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0204.md b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0204.md index f633d35022..cd69d7a1c4 100644 --- a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0204.md +++ b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0204.md @@ -3,7 +3,7 @@ platform: android title: Insecure Random API Usage id: MASTG-TEST-0204 type: [static] -mitigations: [MASTG-MITIG-0001] +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 94aa4b7ede..14a4f1b248 100644 --- a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0205.md +++ b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0205.md @@ -3,7 +3,7 @@ platform: android title: Non-random Sources Usage id: MASTG-TEST-0205 type: [static] -mitigations: [MASTG-MITIG-0001] +best-practices: [MASTG-BEST-0001] prerequisites: - identify-sensitive-data - identify-security-relevant-contexts diff --git a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0232.md b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0232.md index 594a1a4395..cc1dc83f20 100644 --- a/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0232.md +++ b/tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0232.md @@ -4,7 +4,7 @@ platform: android id: MASTG-TEST-0232 type: [static, dynamic] weakness: MASWE-0020 -mitigations: [MASTG-MITIG-0005] +best-practices: [MASTG-BEST-0005] --- ## Overview diff --git a/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0224.md b/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0224.md index c2c52815f0..5e9e5f0a34 100644 --- a/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0224.md +++ b/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0224.md @@ -5,7 +5,7 @@ id: MASTG-TEST-0224 type: [static] available_since: 24 weakness: MASWE-0104 -mitigations: [MASTG-MITIG-0006] +best-practices: [MASTG-BEST-0006] --- ## Overview diff --git a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0203.md b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0203.md index 11e52b98e0..c4eab837aa 100644 --- a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0203.md +++ b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0203.md @@ -5,7 +5,7 @@ id: MASTG-TEST-0203 apis: [Log, Logger, System.out.print, System.err.print, java.lang.Throwable#printStackTrace] type: [dynamic] weakness: MASWE-0001 -mitigations: [MASTG-MITIG-0002] +best-practices: [MASTG-BEST-0002] --- ## Overview diff --git a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0216.md b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0216.md index 7e242275f3..9449efd522 100644 --- a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0216.md +++ b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0216.md @@ -4,7 +4,7 @@ title: Sensitive Data Not Excluded From Backup id: MASTG-TEST-0216 type: [dynamic, filesystem] weakness: MASWE-0004 -mitigations: [MASTG-MITIG-0004] +best-practices: [MASTG-BEST-0004] --- ## Overview diff --git a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0231.md b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0231.md index ff4c9b41af..f8752dbb8d 100644 --- a/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0231.md +++ b/tests-beta/android/MASVS-STORAGE/MASTG-TEST-0231.md @@ -5,7 +5,7 @@ id: MASTG-TEST-0231 apis: [Log, Logger, System.out.print, System.err.print, java.lang.Throwable#printStackTrace, android.util.Log] type: [static] weakness: MASWE-0001 -mitigations: [MASTG-MITIG-0002] +best-practices: [MASTG-BEST-0002] --- ## Overview 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 --- From bf03708ae2be08a3ce93bb55f9c93b51b2ce4d01 Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Wed, 4 Dec 2024 17:03:12 +0100 Subject: [PATCH 09/18] fix title (#3086) --- best-practices/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/best-practices/index.md b/best-practices/index.md index b4b9052ae3..73f1ebcadc 100644 --- a/best-practices/index.md +++ b/best-practices/index.md @@ -1,6 +1,6 @@ --- hide: toc -title: Best Practices (v2 - Beta) +title: Best Practices (v2 Beta) status: new --- From bc93250c0d5b0b7a0ce1dfd3e7924f7387b79452 Mon Sep 17 00:00:00 2001 From: titze Date: Sat, 7 Dec 2024 16:20:33 +0100 Subject: [PATCH 10/18] Port MASTG test 0019 (by @guardsquare) (#3030) * Port MASTG test 0019 * Fix markdown * Review feedback * Add Frida to trace traffic * Apply suggestions from code review * Refine MASTG-TEST-0x19-1.md for clarity on hardcoded HTTP URLs and their usage * Update covered_by references in MASTG-TEST-0019.md to reflect new test cases * Rename MASTG-TEST-0x19 test cases to MASTG-TEST-0233 through MASTG-TEST-0239 * update IDs * Update MASTG-TEST-0233 to modify title, improve evaluation and add related test references * Update MASTG-TEST-0239 note to clarify potential support for multiple weaknesses * Add --- at end of files for MASTG-TEST-0237, MASTG-TEST-0238, and MASTG-TEST-0239 * rm bare URL --------- Co-authored-by: Carlos Holguera --- .../android/MASVS-NETWORK/MASTG-TEST-0233.md | 39 +++++++++++++++++ .../android/MASVS-NETWORK/MASTG-TEST-0234.md | 24 +++++++++++ .../android/MASVS-NETWORK/MASTG-TEST-0235.md | 43 +++++++++++++++++++ .../android/MASVS-NETWORK/MASTG-TEST-0236.md | 39 +++++++++++++++++ .../android/MASVS-NETWORK/MASTG-TEST-0237.md | 9 ++++ .../android/MASVS-NETWORK/MASTG-TEST-0238.md | 9 ++++ .../android/MASVS-NETWORK/MASTG-TEST-0239.md | 9 ++++ .../android/MASVS-NETWORK/MASTG-TEST-0019.md | 3 ++ 8 files changed, 175 insertions(+) create mode 100644 tests-beta/android/MASVS-NETWORK/MASTG-TEST-0233.md create mode 100644 tests-beta/android/MASVS-NETWORK/MASTG-TEST-0234.md create mode 100644 tests-beta/android/MASVS-NETWORK/MASTG-TEST-0235.md create mode 100644 tests-beta/android/MASVS-NETWORK/MASTG-TEST-0236.md create mode 100644 tests-beta/android/MASVS-NETWORK/MASTG-TEST-0237.md create mode 100644 tests-beta/android/MASVS-NETWORK/MASTG-TEST-0238.md create mode 100644 tests-beta/android/MASVS-NETWORK/MASTG-TEST-0239.md 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..9a134e6613 --- /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. +--- \ No newline at end of file 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/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 From 24fc845415c8368bd9abca2ff49e40d81d56fa73 Mon Sep 17 00:00:00 2001 From: Jeel Patel <84757990+jeel38@users.noreply.github.com> Date: Sun, 8 Dec 2024 18:35:34 +0530 Subject: [PATCH 11/18] Added tool Apkleaks (by @appknox) (#3052) * Added tool Apkleaks * fix lint * updated changes * updated tool ID * Update techniques/android/MASTG-TECH-0022.md * Update tools/android/MASTG-TOOL-0125.md --------- Co-authored-by: Appknox Co-authored-by: Carlos Holguera --- techniques/android/MASTG-TECH-0022.md | 4 +++- tools/android/MASTG-TOOL-0125.md | 13 +++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 tools/android/MASTG-TOOL-0125.md 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/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). From 04d1daa5431a14b91142feaae5022252d4ee2786 Mon Sep 17 00:00:00 2001 From: Kai Date: Sun, 8 Dec 2024 14:08:24 +0100 Subject: [PATCH 12/18] Update MASTG-TEST-0079.md (#3083) Fixed link to Objective C Runtime documentation --- tests/ios/MASVS-CODE/MASTG-TEST-0079.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From fbcd10266dbfc972bb5ed6a017e2c633b936450a Mon Sep 17 00:00:00 2001 From: annab-google Date: Tue, 10 Dec 2024 06:58:23 -0500 Subject: [PATCH 13/18] Update the list of permissions (up to API level 35) (#3087) Added 14 permissions: android.permission.THREAD_NETWORK_PRIVILEGED android.permission.RECORD_SENSITIVE_CONTENT android.permission.RECEIVE_SENSITIVE_NOTIFICATIONS android.permission.WRITE_VERIFICATION_STATE_E2EE_CONTACT_KEYS android.permission.READ_DROPBOX_DATA android.permission.WRITE_FLAGS android.permission.REPORT_USAGE_STATS android.permission.MANAGE_DISPLAYS android.permission.RESTRICT_DISPLAY_MODES android.permission.ACCESS_HIDDEN_PROFILES_FULL android.permission.GET_BACKGROUND_INSTALLED_PACKAGES android.permission.REGISTER_NSD_OFFLOAD_ENGINE android.permission.ACCESS_LAST_KNOWN_CELL_ID android.permission.USE_COMPANION_TRANSPORTS --- Document/0x05h-Testing-Platform-Interaction.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) 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 | From a46b2d7e582e9a20bd8468adb367ccc6f2647e77 Mon Sep 17 00:00:00 2001 From: Jeroen Beckers Date: Wed, 11 Dec 2024 12:31:12 +0100 Subject: [PATCH 14/18] Fix continuity issue (#3088) --- techniques/ios/MASTG-TECH-0091.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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. From df78d891e63e9eb1933318c06f2edb1e8483411d Mon Sep 17 00:00:00 2001 From: Jeroen Beckers Date: Wed, 11 Dec 2024 13:36:43 +0100 Subject: [PATCH 15/18] Update MASTG-TOOL-0056 with new Keychain-Dumper tool repo (#3091) * Update MASTG-TOOL-0056.md Updated keychain_dumper to be usable on rootless jb * Fix linting and url * Update tools/ios/MASTG-TOOL-0056.md --------- Co-authored-by: Carlos Holguera --- tools/ios/MASTG-TOOL-0056.md | 43 ++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 7 deletions(-) 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. From 7328dfc30a403a4de1b322baca59ff05b5aa9a1d Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Wed, 11 Dec 2024 13:49:05 +0100 Subject: [PATCH 16/18] Add deprecation notes and status for MASTG tests (#3089) * Add deprecation notes for MASTG-TESTs * Add deprecated status to theme and extra sections in mkdocs.yml * Add support for 'deprecated' status in tags for markdown pages * Add status for tests in dynamic tables * Add draft banner for MASTG v2 tests and deprecated banner for MASTG v1 tests --- docs/hooks/add-tags.py | 4 ++ docs/hooks/create_dynamic_tables.py | 15 ++++- docs/hooks/maswe-beta-banner.py | 61 +++++++++++++++++-- mkdocs.yml | 3 + .../android/MASVS-STORAGE/MASTG-TEST-0001.md | 1 + .../android/MASVS-STORAGE/MASTG-TEST-0003.md | 1 + tests/ios/MASVS-RESILIENCE/MASTG-TEST-0081.md | 1 + tests/ios/MASVS-RESILIENCE/MASTG-TEST-0083.md | 1 + 8 files changed, 81 insertions(+), 6 deletions(-) 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 a7a5848bb9..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 @@ -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: @@ -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] diff --git a/docs/hooks/maswe-beta-banner.py b/docs/hooks/maswe-beta-banner.py index b06a271761..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) @@ -121,7 +168,13 @@ def on_page_markdown(markdown, page, **kwargs): 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/mkdocs.yml b/mkdocs.yml index cb403224af..f96f761b96 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -246,6 +246,7 @@ 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 @@ -370,6 +371,7 @@ extra: L2: l2 R: r draft: draft + deprecated: deprecated new: new tool: tool test: test @@ -381,4 +383,5 @@ extra: best: best status: draft: This page is in draft. + deprecated: This page is deprecated. new: New in this beta! 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 14ed58ca89..8ab71b51d0 100644 --- a/tests/android/MASVS-STORAGE/MASTG-TEST-0003.md +++ b/tests/android/MASVS-STORAGE/MASTG-TEST-0003.md @@ -10,6 +10,7 @@ masvs_v1_levels: - 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-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 From b924bc289fc5fcd937f3baafd3c7c84db63a7ec3 Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Wed, 11 Dec 2024 19:01:17 +0100 Subject: [PATCH 17/18] refactor resilience best practices (#3092) --- best-practices/MASTG-BEST-0007.md | 10 +++++++ best-practices/MASTG-BEST-0008.md | 29 +++++++++++++++++++ .../MASVS-RESILIENCE/MASTG-TEST-0226.md | 5 +--- .../MASVS-RESILIENCE/MASTG-TEST-0227.md | 24 +-------------- 4 files changed, 41 insertions(+), 27 deletions(-) create mode 100644 best-practices/MASTG-BEST-0007.md create mode 100644 best-practices/MASTG-BEST-0008.md 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/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. From ae43160cdef68a39571b58af06d5e29567cc0f79 Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Wed, 11 Dec 2024 19:03:19 +0100 Subject: [PATCH 18/18] Update MASTG-TEST-0237.md (#3093) --- tests-beta/android/MASVS-NETWORK/MASTG-TEST-0237.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0237.md b/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0237.md index 9a134e6613..19e9f3e012 100644 --- a/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0237.md +++ b/tests-beta/android/MASVS-NETWORK/MASTG-TEST-0237.md @@ -6,4 +6,4 @@ 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. ---- \ No newline at end of file +---