diff --git a/Document/0x05a-Platform-Overview.md b/Document/0x05a-Platform-Overview.md index f8fbbd0b81..98ea7ec16c 100644 --- a/Document/0x05a-Platform-Overview.md +++ b/Document/0x05a-Platform-Overview.md @@ -646,12 +646,21 @@ When an application is installed on the Android device, the Package Manager ensu ### APK Signing Schemes -Android supports three application signing schemes. Starting with Android 9 (API level 28), APKs can be verified with APK Signature Scheme v3 (v3 scheme), APK Signature Scheme v2 (v2 scheme) or JAR signing (v1 scheme). For Android 7.0 (API level 24) and above, APKs can be verified with the APK Signature Scheme v2 (v2 scheme) or JAR signing (v1 scheme). For backwards compatibility, an APK can be signed with multiple signature schemes in order to make the app run on both newer and older SDK versions. [Older platforms ignore v2 signatures and verify v1 signatures only](https://source.android.com/security/apksigning/ "APK Signing"). +Android supports multiple application signing schemes: + +- **Below Android 7.0 (API level 24)**: applications can only use the JAR signing (v1) scheme which does not protect all parts of the APK. This scheme is considered insecure. +- **Android 7.0 (API level 24) and above**: applications can use the **v2 signature scheme**, which signs the APK as a whole, providing stronger protection compared to the older v1 (JAR) signing method. +- **Android 9 (API level 28) and above**: It's recommended to use both the **v2 and v3 signature schemes**. The v3 scheme supports **key rotation**, enabling developers to replace keys in the event of a compromise without invalidating old signatures. +- **Android 11 (API level 30) and above**: applications can optionally include the **v4 signature scheme** to enable faster incremental updates. + +For backwards compatibility, an APK can be signed with multiple signature schemes in order to make the app run on both newer and older SDK versions. For example, [older platforms ignore v2 signatures and verify v1 signatures only](https://source.android.com/security/apksigning/). #### JAR Signing (v1 Scheme) The original version of app signing implements the signed APK as a standard signed JAR, which must contain all the entries in `META-INF/MANIFEST.MF`. All files must be signed with a common certificate. This scheme does not protect some parts of the APK, such as ZIP metadata. The drawback of this scheme is that the APK verifier needs to process untrusted data structures before applying the signature, and the verifier discards data the data structures don't cover. Also, the APK verifier must decompress all compressed files, which takes considerable time and memory. +This signature scheme is considered insecure, it is for example affected by the **Janus vulnerability (CVE-2017-13156)**, which can allow malicious actors to modify APK files without invalidating the v1 signature. As such, **v1 should never be relied on for devices running Android 7.0 and above**. + #### APK Signature Scheme (v2 Scheme) With the APK signature scheme, the complete APK is hashed and signed, and an APK Signing Block is created and inserted into the APK. During validation, the v2 scheme checks the signatures of the entire APK file. This form of APK verification is faster and offers more comprehensive protection against modification. You can see the [APK signature verification process for v2 Scheme](https://source.android.com/security/apksigning/v2#verification "APK Signature verification process") below. diff --git a/Document/0x05i-Testing-Code-Quality-and-Build-Settings.md b/Document/0x05i-Testing-Code-Quality-and-Build-Settings.md index c4d1337b9c..2803571946 100644 --- a/Document/0x05i-Testing-Code-Quality-and-Build-Settings.md +++ b/Document/0x05i-Testing-Code-Quality-and-Build-Settings.md @@ -24,7 +24,7 @@ Three APK signing schemes are available: - APK Signature Scheme v3 (v3 scheme). The v2 signature, which is supported by Android 7.0 (API level 24) and above, offers improved security and performance compared to v1 scheme. -The V3 signature, which is supported by Android 9 (API level 28) and above, gives apps the ability to change their signing keys as part of an APK update. This functionality assures compatibility and apps continuous availability by allowing both the new and the old keys to be used. Note that it is only available via apksigner at the time of writing. +The V3 signature, which is supported by Android 9 (API level 28) and above, gives apps the ability to change their signing keys as part of an APK update. This functionality assures compatibility and apps continuous availability by allowing both the new and the old keys to be used. Note that it is only available via @MASTG-TOOL-0123 at the time of writing. For each signing scheme the release builds should always be signed via all its previous schemes as well. diff --git a/techniques/android/MASTG-TECH-0116.md b/techniques/android/MASTG-TECH-0116.md new file mode 100644 index 0000000000..db45822830 --- /dev/null +++ b/techniques/android/MASTG-TECH-0116.md @@ -0,0 +1,38 @@ +--- +title: Obtaining Information about the APK Signature +platform: android +--- + +## Verify APK Signatures + +@MASTG-TOOL-0123 can be used to verify APK signatures: + +```bash +$ apksigner verify --verbose example.apk +Verifies +Verified using v1 scheme (JAR signing): false +Verified using v2 scheme (APK Signature Scheme v2): true +Verified using v3 scheme (APK Signature Scheme v3): true +Verified using v3.1 scheme (APK Signature Scheme v3.1): false +Verified using v4 scheme (APK Signature Scheme v4): false +Verified for SourceStamp: false +Number of signers: 1 +``` + +## Additional Signature Information + +Additional information about the signature including fields from the signing certificate, digest and key information can be also examined with @MASTG-TOOL-0123: + +```bash +$ apksigner verify --print-certs --verbose example.apk +[...] +Signer #1 certificate DN: CN=Example Developers, OU=Android, O=Example +Signer #1 certificate SHA-256 digest: 1fc4de52d0daa33a9c0e3d67217a77c895b46266ef020fad0d48216a6ad6cb70 +Signer #1 certificate SHA-1 digest: 1df329fda8317da4f17f99be83aa64da62af406b +Signer #1 certificate MD5 digest: 3dbdca9c1b56f6c85415b67957d15310 +Signer #1 key algorithm: RSA +Signer #1 key size (bits): 2048 +Signer #1 public key SHA-256 digest: 296b4e40a31de2dcfa2ed277ccf787db0a524db6fc5eacdcda5e50447b3b1a26 +Signer #1 public key SHA-1 digest: 3e02ebf64f1bd4ca85732186b3774e9ccd60cb86 +Signer #1 public key MD5 digest: 24afa3496f98c66343fc9c8a0a7ff5a2 +``` diff --git a/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0x38-2.md b/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0x38-2.md new file mode 100644 index 0000000000..df423b2638 --- /dev/null +++ b/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0x38-2.md @@ -0,0 +1,23 @@ +--- +title: Usage of Insecure Signature Key Size +platform: android +id: MASTG-TEST-0x39-2 +type: [static] +weakness: MASWE-0104 +--- + +## Overview + +For Android apps, the cryptographic strength of the APK signature is essential for maintaining the app's integrity and authenticity. Using a signature key with insufficient length, such as an RSA key shorter than 2048 bits, weakens security, making it easier for attackers to compromise the signature. This vulnerability could allow malicious actors to forge signatures, tamper with the app's code, or distribute unauthorized, modified versions. + +## Steps + +1. List the additional signature information using @MASTG-TECH-0116. + +## Observation + +The output should contain the information about the key size in a line like: `Signer #1 key size (bits):`. + +## Evaluation + +The test case fails if any of the key sizes (in bits) is less than 2048 (RSA). For example, `Signer #1 key size (bits): 1024`. diff --git a/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0x38.md b/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0x38.md new file mode 100644 index 0000000000..3562989962 --- /dev/null +++ b/tests-beta/android/MASVS-RESILIENCE/MASTG-TEST-0x38.md @@ -0,0 +1,47 @@ +--- +title: Usage of Insecure Signature Version +platform: android +id: MASTG-TEST-0x39-1 +type: [static] +available_since: 24 +weakness: MASWE-0104 +--- + +## Overview + +Not using newer APK signing schemes means that the app lacks the enhanced security provided by more robust, updated mechanisms. + +This test checks if the outdated v1 signature scheme is enabled. The v1 scheme is vulnerable to certain attacks, such as the "Janus" vulnerability ([CVE-2017-13156](https://nvd.nist.gov/vuln/detail/CVE-2017-13156)), because it does not cover all parts of the APK file, allowing malicious actors to potentially **modify parts of the APK without invalidating the signature**. Relying solely on v1 signing therefore increases the risk of tampering and compromises app security. + +To learn more about APK Signing Schemes, see [this document](../../../Document/0x05a-Platform-Overview.md#signing-process). + +## Steps + +1. Obtain the `minSdkVersion` attribute from the AndroidManifest.xml, e.g., via @MASTG-TOOL-0121. +2. List all used signature schemes using the `verify` command of @MASTG-TOOL-0123 as shown in @MASTG-TECH-0116. + +## Observation + +The output should contain the value of the `minSdkVersion` attribute and the used signature schemes (for example `Verified using v3 scheme (APK Signature Scheme v3): true`). + +## 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/android/MASVS-RESILIENCE/MASTG-TEST-0038.md b/tests/android/MASVS-RESILIENCE/MASTG-TEST-0038.md index 2d85130a73..625fa03a5a 100644 --- a/tests/android/MASVS-RESILIENCE/MASTG-TEST-0038.md +++ b/tests/android/MASVS-RESILIENCE/MASTG-TEST-0038.md @@ -7,6 +7,9 @@ platform: android title: Making Sure that the App is Properly Signed masvs_v1_levels: - R +status: deprecated +covered_by: [MASTG-TEST-0x38] +deprecation_note: New version available in MASTG V2 --- ## Overview diff --git a/tools/android/MASTG-TOOL-0123.md b/tools/android/MASTG-TOOL-0123.md new file mode 100644 index 0000000000..6109baad78 --- /dev/null +++ b/tools/android/MASTG-TOOL-0123.md @@ -0,0 +1,7 @@ +--- +title: apksigner +platform: android +source: https://developer.android.com/tools/apksigner +--- + +[apksigner](https://developer.android.com/tools/apksigner), available in revision 24.0.3 and higher of the Android SDK Build Tools, is contained in the @MASTG-TOOL-0006 at `[SDK-Path]/build-tools/[version]/apksigner` and can be used to verify APK signatures, rotate keys and display additional information about the signing certificates and keys.