-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'OWASP:master' into MASTG-TEST-0045
- Loading branch information
Showing
74 changed files
with
784 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,7 @@ on: | |
branches: | ||
- master | ||
paths: | ||
- 'demos/**' | ||
- 'demos/android/**' | ||
pull_request: | ||
branches: | ||
- master | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,7 @@ on: | |
branches: | ||
- master | ||
paths: | ||
- 'demos/**' | ||
- 'demos/ios/**' | ||
pull_request: | ||
branches: | ||
- master | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
--- | ||
title: Use Secure Encryption Algorithms | ||
alias: use-secure-encryption-algorithms | ||
id: MASTG-BEST-0009 | ||
platform: android | ||
--- | ||
|
||
Replace insecure encryption algorithms with secure ones such as AES-256 (preferably in GCM mode) or Chacha20. | ||
|
||
For comprehensive guidance on implementing secure encryption in Android, refer to the documentation on ["Cryptography"](https://developer.android.com/privacy-and-security/cryptography) and ["Broken or risky cryptographic algorithm"](https://developer.android.com/privacy-and-security/risks/broken-cryptographic-algorithm#weak-or-broken-cryptographic-encryption-functions-use-strong-cryptographic-algorithms-in-encryption-1B2M2Y8Asg) on the official Android Developers website. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,7 @@ code: [java] | |
|
||
### Sample | ||
|
||
{{ MastgTest.kt }} | ||
{{ MastgTest.kt # MastgTest_reversed.java }} | ||
|
||
### Steps | ||
|
||
|
33 changes: 33 additions & 0 deletions
33
demos/android/MASVS-CRYPTO/MASTG-DEMO-0022/MASTG-DEMO-0022.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
--- | ||
platform: android | ||
title: Uses of Insecure Symmetric Encryption Algorithms in Cipher with semgrep | ||
id: MASTG-DEMO-0022 | ||
code: [kotlin] | ||
test: MASTG-TEST-0221 | ||
--- | ||
|
||
### Sample | ||
|
||
The code snippet below shows sample code contains use of insecure encryption algorithms. | ||
|
||
{{ MastgTest.kt # MastgTest_reversed.java }} | ||
|
||
### Steps | ||
|
||
Let's run our @MASTG-TOOL-0110 rule against the sample code. | ||
|
||
{{ ../../../../rules/mastg-android-weak-encryption-algorithms.yaml }} | ||
|
||
{{ run.sh }} | ||
|
||
### Observation | ||
|
||
The rule has identified two instances in the code file where insecure encryption algorithms are used. The specified line numbers can be located in the reverse-engineered code for further investigation and remediation. | ||
|
||
{{ output.txt }} | ||
|
||
### Evaluation | ||
|
||
The test fails due to the use of weak encryption algorithms, specifically DES, 3DES, RC4 and Blowfish. | ||
|
||
See @MASTG-TEST-0221 for more information. |
113 changes: 113 additions & 0 deletions
113
demos/android/MASVS-CRYPTO/MASTG-DEMO-0022/MastgTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package org.owasp.mastestapp | ||
|
||
import android.content.Context | ||
import java.security.Key | ||
import javax.crypto.Cipher | ||
import javax.crypto.SecretKeyFactory | ||
import javax.crypto.spec.DESKeySpec | ||
import javax.crypto.spec.DESedeKeySpec | ||
import javax.crypto.spec.SecretKeySpec | ||
import android.util.Base64 | ||
import java.security.SecureRandom | ||
import javax.crypto.SecretKey | ||
|
||
class MastgTest(private val context: Context) { | ||
|
||
// Vulnerable encryption using DES (weak algorithm) | ||
fun vulnerableDesEncryption(data: String): String { | ||
try { | ||
// Weak key for DES | ||
val keyBytes = ByteArray(8) | ||
SecureRandom().nextBytes(keyBytes) | ||
val keySpec = DESKeySpec(keyBytes) | ||
val keyFactory = SecretKeyFactory.getInstance("DES") | ||
val secretKey: Key = keyFactory.generateSecret(keySpec) | ||
|
||
// Weak encryption algorithm (DES) | ||
val cipher = Cipher.getInstance("DES") | ||
cipher.init(Cipher.ENCRYPT_MODE, secretKey) | ||
|
||
val encryptedData = cipher.doFinal(data.toByteArray()) | ||
return Base64.encodeToString(encryptedData, Base64.DEFAULT) | ||
} catch (e: Exception) { | ||
return "Encryption error: ${e.message}" | ||
} | ||
} | ||
|
||
|
||
// Vulnerable encryption using 3DES (Triple DES) | ||
fun vulnerable3DesEncryption(data: String): String { | ||
try { | ||
val keyBytes = ByteArray(24) | ||
SecureRandom().nextBytes(keyBytes) | ||
val keySpec = DESedeKeySpec(keyBytes) | ||
val keyFactory = SecretKeyFactory.getInstance("DESede") | ||
val secretKey: Key = keyFactory.generateSecret(keySpec) | ||
|
||
// Weak encryption algorithm (3DES) | ||
val cipher = Cipher.getInstance("DESede") | ||
cipher.init(Cipher.ENCRYPT_MODE, secretKey) | ||
|
||
val encryptedData = cipher.doFinal(data.toByteArray()) | ||
return Base64.encodeToString(encryptedData, Base64.DEFAULT) | ||
} catch (e: Exception) { | ||
return "Encryption error: ${e.message}" | ||
} | ||
} | ||
|
||
// Insecure encryption using RC4 (ARCFOUR) (Deprecated) | ||
fun vulnerableRc4Encryption(data: String): String { | ||
return try { | ||
val keyBytes = ByteArray(16) | ||
SecureRandom().nextBytes(keyBytes) | ||
val secretKey = SecretKeySpec(keyBytes, "RC4") | ||
|
||
val cipher = Cipher.getInstance("RC4") | ||
cipher.init(Cipher.ENCRYPT_MODE, secretKey) | ||
|
||
val encryptedData = cipher.doFinal(data.toByteArray()) | ||
Base64.encodeToString(encryptedData, Base64.DEFAULT) | ||
} catch (e: Exception) { | ||
"Encryption error: ${e.message}" | ||
} | ||
} | ||
|
||
// Insecure encryption using Blowfish (weak algorithm) | ||
fun vulnerableBlowfishEncryption(data: String): String { | ||
return try { | ||
// Weak key for Blowfish (insecure, small key size) | ||
val keyBytes = ByteArray(8) // Only 8 bytes (64-bit key) - not secure | ||
SecureRandom().nextBytes(keyBytes) | ||
val secretKey: SecretKey = SecretKeySpec(keyBytes, "Blowfish") | ||
|
||
// Weak encryption algorithm (Blowfish) | ||
val cipher = Cipher.getInstance("Blowfish") | ||
cipher.init(Cipher.ENCRYPT_MODE, secretKey) | ||
|
||
val encryptedData = cipher.doFinal(data.toByteArray()) | ||
Base64.encodeToString(encryptedData, Base64.DEFAULT) | ||
} catch (e: Exception) { | ||
"Encryption error: ${e.message}" | ||
} | ||
} | ||
|
||
|
||
fun mastgTest(): String { | ||
val sensitiveString = "Hello from the OWASP MASTG Test app." | ||
|
||
// Encrypt with weak DES | ||
val desEncryptedString = vulnerableDesEncryption(sensitiveString) | ||
|
||
// Encrypt with weak 3DES | ||
val tripleDesEncryptedString = vulnerable3DesEncryption(sensitiveString) | ||
|
||
// Encrypt with deprecated RC4 | ||
val rc4EncryptedString = vulnerableRc4Encryption(sensitiveString) | ||
|
||
// Encrypt with weak Blowfish | ||
val blowfishEncryptedString = vulnerableBlowfishEncryption(sensitiveString) | ||
|
||
// Returning the encrypted results | ||
return "DES Encrypted: $desEncryptedString\n3DES Encrypted: $tripleDesEncryptedString\nRC4 Encrypted: $rc4EncryptedString\nBlowfish Encrypted: $blowfishEncryptedString" | ||
} | ||
} |
120 changes: 120 additions & 0 deletions
120
demos/android/MASVS-CRYPTO/MASTG-DEMO-0022/MastgTest_reversed.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
package org.owasp.mastestapp; | ||
|
||
import android.content.Context; | ||
import android.util.Base64; | ||
import java.security.Key; | ||
import java.security.SecureRandom; | ||
import javax.crypto.Cipher; | ||
import javax.crypto.SecretKey; | ||
import javax.crypto.SecretKeyFactory; | ||
import javax.crypto.spec.DESKeySpec; | ||
import javax.crypto.spec.DESedeKeySpec; | ||
import javax.crypto.spec.SecretKeySpec; | ||
import kotlin.Metadata; | ||
import kotlin.jvm.internal.Intrinsics; | ||
import kotlin.text.Charsets; | ||
|
||
/* compiled from: MastgTest.kt */ | ||
@Metadata(d1 = {"\u0000\u001a\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0002\b\u0006\b\u0007\u0018\u00002\u00020\u0001B\r\u0012\u0006\u0010\u0002\u001a\u00020\u0003¢\u0006\u0002\u0010\u0004J\u0006\u0010\u0005\u001a\u00020\u0006J\u000e\u0010\u0007\u001a\u00020\u00062\u0006\u0010\b\u001a\u00020\u0006J\u000e\u0010\t\u001a\u00020\u00062\u0006\u0010\b\u001a\u00020\u0006J\u000e\u0010\n\u001a\u00020\u00062\u0006\u0010\b\u001a\u00020\u0006J\u000e\u0010\u000b\u001a\u00020\u00062\u0006\u0010\b\u001a\u00020\u0006R\u000e\u0010\u0002\u001a\u00020\u0003X\u0082\u0004¢\u0006\u0002\n\u0000¨\u0006\f"}, d2 = {"Lorg/owasp/mastestapp/MastgTest;", "", "context", "Landroid/content/Context;", "(Landroid/content/Context;)V", "mastgTest", "", "vulnerable3DesEncryption", "data", "vulnerableBlowfishEncryption", "vulnerableDesEncryption", "vulnerableRc4Encryption", "app_debug"}, k = 1, mv = {1, 9, 0}, xi = 48) | ||
/* loaded from: classes4.dex */ | ||
public final class MastgTest { | ||
public static final int $stable = 8; | ||
private final Context context; | ||
|
||
public MastgTest(Context context) { | ||
Intrinsics.checkNotNullParameter(context, "context"); | ||
this.context = context; | ||
} | ||
|
||
public final String vulnerableDesEncryption(String data) { | ||
Intrinsics.checkNotNullParameter(data, "data"); | ||
try { | ||
byte[] keyBytes = new byte[8]; | ||
new SecureRandom().nextBytes(keyBytes); | ||
DESKeySpec keySpec = new DESKeySpec(keyBytes); | ||
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); | ||
Key generateSecret = keyFactory.generateSecret(keySpec); | ||
Intrinsics.checkNotNullExpressionValue(generateSecret, "generateSecret(...)"); | ||
Key secretKey = generateSecret; | ||
Cipher cipher = Cipher.getInstance("DES"); | ||
cipher.init(1, secretKey); | ||
byte[] bytes = data.getBytes(Charsets.UTF_8); | ||
Intrinsics.checkNotNullExpressionValue(bytes, "this as java.lang.String).getBytes(charset)"); | ||
byte[] encryptedData = cipher.doFinal(bytes); | ||
String encodeToString = Base64.encodeToString(encryptedData, 0); | ||
Intrinsics.checkNotNullExpressionValue(encodeToString, "encodeToString(...)"); | ||
return encodeToString; | ||
} catch (Exception e) { | ||
return "Encryption error: " + e.getMessage(); | ||
} | ||
} | ||
|
||
public final String vulnerable3DesEncryption(String data) { | ||
Intrinsics.checkNotNullParameter(data, "data"); | ||
try { | ||
byte[] keyBytes = new byte[24]; | ||
new SecureRandom().nextBytes(keyBytes); | ||
DESedeKeySpec keySpec = new DESedeKeySpec(keyBytes); | ||
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede"); | ||
Key generateSecret = keyFactory.generateSecret(keySpec); | ||
Intrinsics.checkNotNullExpressionValue(generateSecret, "generateSecret(...)"); | ||
Key secretKey = generateSecret; | ||
Cipher cipher = Cipher.getInstance("DESede"); | ||
cipher.init(1, secretKey); | ||
byte[] bytes = data.getBytes(Charsets.UTF_8); | ||
Intrinsics.checkNotNullExpressionValue(bytes, "this as java.lang.String).getBytes(charset)"); | ||
byte[] encryptedData = cipher.doFinal(bytes); | ||
String encodeToString = Base64.encodeToString(encryptedData, 0); | ||
Intrinsics.checkNotNullExpressionValue(encodeToString, "encodeToString(...)"); | ||
return encodeToString; | ||
} catch (Exception e) { | ||
return "Encryption error: " + e.getMessage(); | ||
} | ||
} | ||
|
||
public final String vulnerableRc4Encryption(String data) { | ||
Intrinsics.checkNotNullParameter(data, "data"); | ||
try { | ||
byte[] keyBytes = new byte[16]; | ||
new SecureRandom().nextBytes(keyBytes); | ||
SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "RC4"); | ||
Cipher cipher = Cipher.getInstance("RC4"); | ||
cipher.init(1, secretKey); | ||
byte[] bytes = data.getBytes(Charsets.UTF_8); | ||
Intrinsics.checkNotNullExpressionValue(bytes, "this as java.lang.String).getBytes(charset)"); | ||
byte[] encryptedData = cipher.doFinal(bytes); | ||
String encodeToString = Base64.encodeToString(encryptedData, 0); | ||
Intrinsics.checkNotNull(encodeToString); | ||
return encodeToString; | ||
} catch (Exception e) { | ||
return "Encryption error: " + e.getMessage(); | ||
} | ||
} | ||
|
||
public final String vulnerableBlowfishEncryption(String data) { | ||
Intrinsics.checkNotNullParameter(data, "data"); | ||
try { | ||
byte[] keyBytes = new byte[8]; | ||
new SecureRandom().nextBytes(keyBytes); | ||
SecretKey secretKey = new SecretKeySpec(keyBytes, "Blowfish"); | ||
Cipher cipher = Cipher.getInstance("Blowfish"); | ||
cipher.init(1, secretKey); | ||
byte[] bytes = data.getBytes(Charsets.UTF_8); | ||
Intrinsics.checkNotNullExpressionValue(bytes, "this as java.lang.String).getBytes(charset)"); | ||
byte[] encryptedData = cipher.doFinal(bytes); | ||
String encodeToString = Base64.encodeToString(encryptedData, 0); | ||
Intrinsics.checkNotNull(encodeToString); | ||
return encodeToString; | ||
} catch (Exception e) { | ||
return "Encryption error: " + e.getMessage(); | ||
} | ||
} | ||
|
||
public final String mastgTest() { | ||
String desEncryptedString = vulnerableDesEncryption("Hello from the OWASP MASTG Test app."); | ||
String tripleDesEncryptedString = vulnerable3DesEncryption("Hello from the OWASP MASTG Test app."); | ||
String rc4EncryptedString = vulnerableRc4Encryption("Hello from the OWASP MASTG Test app."); | ||
String blowfishEncryptedString = vulnerableBlowfishEncryption("Hello from the OWASP MASTG Test app."); | ||
return "DES Encrypted: " + desEncryptedString + "\n3DES Encrypted: " + tripleDesEncryptedString + "\nRC4 Encrypted: " + rc4EncryptedString + "\nBlowfish Encrypted: " + blowfishEncryptedString; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
|
||
|
||
┌─────────────────┐ | ||
│ 4 Code Findings │ | ||
└─────────────────┘ | ||
|
||
MastgTest_reversed.java | ||
❯❱ rules.weak-encryption-algorithms | ||
[MASVS-CRYPTO-1] Weak encryption algorithms found in use. | ||
|
||
39┆ Cipher cipher = Cipher.getInstance("DES"); | ||
⋮┆---------------------------------------- | ||
62┆ Cipher cipher = Cipher.getInstance("DESede"); | ||
⋮┆---------------------------------------- | ||
81┆ Cipher cipher = Cipher.getInstance("RC4"); | ||
⋮┆---------------------------------------- | ||
100┆ Cipher cipher = Cipher.getInstance("Blowfish"); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
NO_COLOR=true semgrep -c ../../../../rules/mastg-android-weak-encryption-algorithms.yaml ./MastgTest_reversed.java --text > output.txt |
33 changes: 33 additions & 0 deletions
33
demos/android/MASVS-CRYPTO/MASTG-DEMO-0023/MASTG-DEMO-0023.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
--- | ||
platform: android | ||
title: Uses of Insecure Encryption Modes in Cipher with semgrep | ||
id: MASTG-DEMO-0023 | ||
code: [kotlin] | ||
test: MASTG-TEST-0232 | ||
--- | ||
|
||
### Sample | ||
|
||
The code snippet below shows sample code contains use of insecure encryption modes. | ||
|
||
{{ MastgTest.kt # MastgTest_reversed.java }} | ||
|
||
### Steps | ||
|
||
Let's run our @MASTG-TOOL-0110 rule against the sample code. | ||
|
||
{{ ../../../../rules/mastg-android-weak-encryption-modes.yaml }} | ||
|
||
{{ run.sh }} | ||
|
||
### Observation | ||
|
||
The rule has identified six instances in the code file where insecure encryption modes are used. The specified line numbers can be located in the reverse-engineered code for further investigation and remediation. | ||
|
||
{{ output.txt }} | ||
|
||
### Evaluation | ||
|
||
The test fails since the output contains several instances of the ECB mode of AES in different transformations explicitly or implicitly (ECB is the default mode for AES if not specified). | ||
|
||
See @MASTG-TEST-0232 for more information. |
Oops, something went wrong.