-
-
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.
Browse files
Browse the repository at this point in the history
* added weaknesss * updated weakness * added MASTG-DEMO, rule, MASTG-TEST * updated weakness.md * fix spelling * Update weaknesses/MASVS-CRYPTO/MASWE-0020.md * Update weaknesses/MASVS-CRYPTO/MASWE-0020.md * Update weaknesses/MASVS-CRYPTO/MASWE-0020.md * Update weaknesses/MASVS-CRYPTO/MASWE-0020.md * Update weaknesses/MASVS-CRYPTO/MASWE-0020.md * Update weaknesses/MASVS-CRYPTO/MASWE-0020.md * removed duplicate * change status to new * updated title MASTG-TEST-0211.md * updated title MASTG-DEMO-0016.md * updated tests-beta * fix lint * updated MASWE-0020.md * updated mitigations * updated changes * removed MASTG-TEST-0211.md * added new Demo * 2 demo added * renamed semgrep files * updated * rename * updated * updated MASWE-0020.md * updated MASWE-0020.md * updated weak-encryption.yaml * Renamed files * updated Demo.md * rename rules filename * updated changes * updated changes * fix --------- Co-authored-by: Sven <sven@bsddaemon.org>
- Loading branch information
1 parent
74d9b6d
commit 23d106c
Showing
13 changed files
with
594 additions
and
9 deletions.
There are no files selected for viewing
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 Encryption Algorithms in Cipher with semgrep | ||
id: MASTG-DEMO-0022 | ||
code: [kotlin] | ||
--- | ||
|
||
### 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 an insecure encryption is used. The specified line numbers are from the reversed code for further investigation and remediation. | ||
|
||
{{ output.txt }} | ||
|
||
### Evaluation | ||
|
||
The test fails since several instances of weak encryption algorithms were found: | ||
|
||
- Line 36 utilize insecure DES algorithm. | ||
- Line 59 utilize insecure 3DES algorithm. |
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,65 @@ | ||
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 | ||
|
||
class MastgTest(private val context: Context) { | ||
|
||
// Vulnerable encryption using DES (weak algorithm) | ||
fun vulnerableDesEncryption(data: String): String { | ||
try { | ||
// Weak key for DES | ||
val keySpec = DESKeySpec("12345678".toByteArray()) | ||
val keyFactory = SecretKeyFactory.getInstance("DES") | ||
val secretKey: Key = keyFactory.generateSecret(keySpec) | ||
|
||
// Weak encryption algorithm (DES) and weak mode (ECB) | ||
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 { | ||
// Weak key for 3DES (24-byte key) | ||
val keySpec = DESedeKeySpec("123456789012345678901234".toByteArray()) // 24 bytes key | ||
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}" | ||
} | ||
} | ||
|
||
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) | ||
|
||
// Returning the encrypted results | ||
return "DES Encrypted: $desEncryptedString\n3DES Encrypted: $tripleDesEncryptedString" | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
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,77 @@ | ||
package org.owasp.mastestapp; | ||
|
||
import android.content.Context; | ||
import android.util.Base64; | ||
import java.security.Key; | ||
import javax.crypto.Cipher; | ||
import javax.crypto.SecretKeyFactory; | ||
import javax.crypto.spec.DESKeySpec; | ||
import javax.crypto.spec.DESedeKeySpec; | ||
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\u0004\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\u0006R\u000e\u0010\u0002\u001a\u00020\u0003X\u0082\u0004¢\u0006\u0002\n\u0000¨\u0006\n"}, d2 = {"Lorg/owasp/mastestapp/MastgTest;", "", "context", "Landroid/content/Context;", "(Landroid/content/Context;)V", "mastgTest", "", "vulnerable3DesEncryption", "data", "vulnerableDesEncryption", "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[] bytes = "12345678".getBytes(Charsets.UTF_8); | ||
Intrinsics.checkNotNullExpressionValue(bytes, "this as java.lang.String).getBytes(charset)"); | ||
DESKeySpec keySpec = new DESKeySpec(bytes); | ||
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[] bytes2 = data.getBytes(Charsets.UTF_8); | ||
Intrinsics.checkNotNullExpressionValue(bytes2, "this as java.lang.String).getBytes(charset)"); | ||
byte[] encryptedData = cipher.doFinal(bytes2); | ||
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[] bytes = "123456789012345678901234".getBytes(Charsets.UTF_8); | ||
Intrinsics.checkNotNullExpressionValue(bytes, "this as java.lang.String).getBytes(charset)"); | ||
DESedeKeySpec keySpec = new DESedeKeySpec(bytes); | ||
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[] bytes2 = data.getBytes(Charsets.UTF_8); | ||
Intrinsics.checkNotNullExpressionValue(bytes2, "this as java.lang.String).getBytes(charset)"); | ||
byte[] encryptedData = cipher.doFinal(bytes2); | ||
String encodeToString = Base64.encodeToString(encryptedData, 0); | ||
Intrinsics.checkNotNullExpressionValue(encodeToString, "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."); | ||
return "DES Encrypted: " + desEncryptedString + "\n3DES Encrypted: " + tripleDesEncryptedString; | ||
} | ||
} |
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,13 @@ | ||
|
||
|
||
┌─────────────────┐ | ||
│ 2 Code Findings │ | ||
└─────────────────┘ | ||
|
||
MastgTest_reversed.java | ||
❯❱rules.weak-encryption-algorithms | ||
[MASVS-CRYPTO-1] Weak encryption algorithms found in use. | ||
|
||
36┆ Cipher cipher = Cipher.getInstance("DES"); | ||
⋮┆---------------------------------------- | ||
59┆ Cipher cipher = Cipher.getInstance("DESede"); |
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 -o output.txt |
38 changes: 38 additions & 0 deletions
38
demos/android/MASVS-CRYPTO/MASTG_DEMO-0016/MASTG-DEMO-0016.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,38 @@ | ||
--- | ||
platform: android | ||
title: Uses of Insecure Encryption Modes in Cipher with semgrep | ||
id: MASTG-DEMO-0016 | ||
code: [kotlin] | ||
test: MASTG-TEST-0221 | ||
--- | ||
|
||
### 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 }} | ||
|
||
{{ run.sh }} | ||
|
||
### Observation | ||
|
||
The rule has identified six instances in the code file, where insecure encryption modes are used. | ||
|
||
{{ output.txt }} | ||
|
||
### Evaluation | ||
|
||
The test fails since the output contains several instances of the ECB mode of AES: | ||
|
||
- Line 36 using Cipher.getInstance("AES") defaults to ECB. | ||
- Line 55 using Cipher.getInstance("AES/ECB/NoPadding");. | ||
- Line 76 using Cipher.getInstance("AES/ECB/PKCS5Padding");. | ||
- Line 95 using Cipher.getInstance("AES/ECB/ISO10126Padding");. | ||
- Line 118 using Cipher.getInstance("DES/ECB/PKCS5Padding");. | ||
- Line 141 using Cipher.getInstance("DESede/ECB/PKCS5Padding");. |
133 changes: 133 additions & 0 deletions
133
demos/android/MASVS-CRYPTO/MASTG_DEMO-0016/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,133 @@ | ||
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 | ||
|
||
class MastgTest(private val context: Context) { | ||
|
||
// Vulnerable AES encryption | ||
fun vulnerableAesEncryption(data: String): String { | ||
try { | ||
val key = "1234567890123456".toByteArray() // 16 bytes key for AES | ||
val secretKeySpec = SecretKeySpec(key, "AES") | ||
|
||
// Default mode for AES (ECB) | ||
val cipher = Cipher.getInstance("AES") | ||
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec) | ||
|
||
val encryptedData = cipher.doFinal(data.toByteArray()) | ||
return Base64.encodeToString(encryptedData, Base64.DEFAULT) | ||
} catch (e: Exception) { | ||
return "Encryption error: ${e.message}" | ||
} | ||
} | ||
|
||
// Vulnerable AES with ECB and NoPadding (manual padding applied) | ||
fun vulnerableAesEcbNoPadding(data: String): String { | ||
try { | ||
val key = "1234567890123456".toByteArray() | ||
val secretKeySpec = SecretKeySpec(key, "AES") | ||
|
||
val cipher = Cipher.getInstance("AES/ECB/NoPadding") | ||
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec) | ||
|
||
// Ensure the data is padded to match the block size | ||
val blockSize = 16 | ||
val paddingLength = blockSize - (data.length % blockSize) | ||
val paddedData = data + "\u0000".repeat(paddingLength) // Null padding | ||
|
||
val encryptedData = cipher.doFinal(paddedData.toByteArray()) | ||
return Base64.encodeToString(encryptedData, Base64.DEFAULT).trim() | ||
} catch (e: Exception) { | ||
return "Encryption error: ${e.message}" | ||
} | ||
} | ||
|
||
// Vulnerable AES with ECB and PKCS5Padding | ||
fun vulnerableAesEcbPkcs5Padding(data: String): String { | ||
try { | ||
val key = "1234567890123456".toByteArray() | ||
val secretKeySpec = SecretKeySpec(key, "AES") | ||
|
||
val cipher = Cipher.getInstance("AES/ECB/PKCS5Padding") | ||
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec) | ||
|
||
val encryptedData = cipher.doFinal(data.toByteArray()) | ||
return Base64.encodeToString(encryptedData, Base64.DEFAULT) | ||
} catch (e: Exception) { | ||
return "Encryption error: ${e.message}" | ||
} | ||
} | ||
|
||
// Vulnerable AES with ECB and ISO10126Padding | ||
fun vulnerableAesEcbIso10126Padding(data: String): String { | ||
try { | ||
val key = "1234567890123456".toByteArray() | ||
val secretKeySpec = SecretKeySpec(key, "AES") | ||
|
||
val cipher = Cipher.getInstance("AES/ECB/ISO10126Padding") | ||
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec) | ||
|
||
val encryptedData = cipher.doFinal(data.toByteArray()) | ||
return Base64.encodeToString(encryptedData, Base64.DEFAULT) | ||
} catch (e: Exception) { | ||
return "Encryption error: ${e.message}" | ||
} | ||
} | ||
|
||
// Vulnerable DES with ECB and PKCS5Padding | ||
fun vulnerableDesEcbPkcs5Padding(data: String): String { | ||
try { | ||
val keySpec = DESKeySpec("12345678".toByteArray()) | ||
val keyFactory = SecretKeyFactory.getInstance("DES") | ||
val secretKey: Key = keyFactory.generateSecret(keySpec) | ||
|
||
val cipher = Cipher.getInstance("DES/ECB/PKCS5Padding") | ||
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 3DES with ECB and PKCS5Padding | ||
fun vulnerable3DesEcbPkcs5Padding(data: String): String { | ||
try { | ||
val keySpec = DESedeKeySpec("123456789012345678901234".toByteArray()) | ||
val keyFactory = SecretKeyFactory.getInstance("DESede") | ||
val secretKey: Key = keyFactory.generateSecret(keySpec) | ||
|
||
val cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding") | ||
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}" | ||
} | ||
} | ||
|
||
// Test and return results | ||
fun mastgTest(): String { | ||
val sensitiveString = "Hello from OWASP MASTG!" | ||
|
||
val results = listOf( | ||
"AES Default: ${vulnerableAesEncryption(sensitiveString)}", | ||
"AES ECB NoPadding: ${vulnerableAesEcbNoPadding(sensitiveString)}", | ||
"AES ECB PKCS5Padding: ${vulnerableAesEcbPkcs5Padding(sensitiveString)}", | ||
"AES ECB ISO10126Padding: ${vulnerableAesEcbIso10126Padding(sensitiveString)}", | ||
"DES ECB PKCS5Padding: ${vulnerableDesEcbPkcs5Padding(sensitiveString)}", | ||
"3DES ECB PKCS5Padding: ${vulnerable3DesEcbPkcs5Padding(sensitiveString)}" | ||
) | ||
|
||
return results.joinToString("\n") | ||
} | ||
} |
Oops, something went wrong.