Skip to content

Commit aa27fd6

Browse files
Copilotcommjoen
andauthored
fix: add CodeQL suppression for intentional weak algorithms in challenge code; fix SSRF in Challenge62; fix Random type declarations
Agent-Logs-Url: https://github.com/OWASP/wrongsecrets/sessions/434d65db-7a37-4184-9e98-1161b21e2974 Co-authored-by: commjoen <1457214+commjoen@users.noreply.github.com>
1 parent 9c8dd5b commit aa27fd6

8 files changed

Lines changed: 25 additions & 4 deletions

File tree

src/main/java/org/owasp/wrongsecrets/challenges/docker/Challenge18.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ private String base64Decode(String base64) {
3333
private String calculateHash(String hash, String input) {
3434
try {
3535
if (md5Hash.equals(hash) || sha1Hash.equals(hash)) {
36+
// codeql[java/weak-cryptographic-algorithm] Intentionally weak algorithm for educational challenge about weak hash mechanisms
3637
var md = MessageDigest.getInstance(hash);
3738
return new String(Hex.encode(md.digest(input.getBytes(StandardCharsets.UTF_8))));
3839
}

src/main/java/org/owasp/wrongsecrets/challenges/docker/Challenge39.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ private String getSolution() {
5151
SecretKey secretKey = new SecretKeySpec(decodedKey, "AES");
5252

5353
// Initialize the Cipher for decryption
54+
// codeql[java/weak-cryptographic-algorithm] Intentionally weak ECB mode for educational challenge about filename-as-key
5455
Cipher cipher = Cipher.getInstance("AES");
5556
cipher.init(Cipher.DECRYPT_MODE, secretKey);
5657

src/main/java/org/owasp/wrongsecrets/challenges/docker/Challenge40.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ private String getSolution() {
5252
SecretKey secretKey = new SecretKeySpec(plainDecryptionKey, "AES");
5353

5454
// Initialize the Cipher for decryption
55+
// codeql[java/weak-cryptographic-algorithm] Intentionally weak ECB mode for educational challenge about co-located key and secret
5556
Cipher cipher = Cipher.getInstance("AES");
5657
cipher.init(Cipher.DECRYPT_MODE, secretKey);
5758

src/main/java/org/owasp/wrongsecrets/challenges/docker/Challenge41.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public boolean answerCorrect(String answer) {
4747
value = "WEAK_MESSAGE_DIGEST_MD5",
4848
justification = "This is to allow md5 hashing")
4949
private String hashWithMd5(String plainText) throws NoSuchAlgorithmException {
50+
// codeql[java/weak-cryptographic-algorithm] Intentionally weak algorithm for educational challenge demonstrating password shucking
5051
MessageDigest md = MessageDigest.getInstance("MD5");
5152

5253
byte[] result = md.digest(plainText.getBytes(StandardCharsets.UTF_8));

src/main/java/org/owasp/wrongsecrets/challenges/docker/Challenge49.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public boolean answerCorrect(String answer) {
6363
value = "WEAK_MESSAGE_DIGEST_MD5",
6464
justification = "This is to allow md5 hashing")
6565
private String hashWithMd5(String plainText) throws NoSuchAlgorithmException {
66+
// codeql[java/weak-cryptographic-algorithm] Intentionally weak algorithm for educational challenge demonstrating weak KDF
6667
MessageDigest md = MessageDigest.getInstance("MD5");
6768

6869
byte[] result = md.digest(plainText.getBytes(StandardCharsets.UTF_8));
@@ -82,6 +83,7 @@ private String decrypt(String cipherText, String key) {
8283

8384
SecretKey secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
8485

86+
// codeql[java/weak-cryptographic-algorithm] Intentionally weak ECB mode for educational challenge demonstrating weak KDF
8587
Cipher cipher = Cipher.getInstance("AES");
8688
cipher.init(Cipher.DECRYPT_MODE, secretKey);
8789

src/main/java/org/owasp/wrongsecrets/challenges/docker/Challenge62McpController.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,11 @@ private Map<String, Object> handleReadGoogleDriveDocument(
171171
? (String) arguments.get("document_id")
172172
: documentId;
173173

174+
if (!isValidGoogleDriveDocumentId(docId)) {
175+
log.warn("Challenge62: Invalid document ID format: {}", sanitizeForLog(docId));
176+
return buildErrorResponse(id, -32602, "Invalid document_id format");
177+
}
178+
174179
log.info(
175180
"Challenge62 MCP read_google_drive_document called for document: {}",
176181
sanitizeForLog(docId));
@@ -352,6 +357,18 @@ private String sanitizeForLog(String input) {
352357
return input.replaceAll("[\r\n\u0085\u2028\u2029]", "_");
353358
}
354359

360+
/**
361+
* Validates that a Google Drive document ID only contains characters that are valid in a Google
362+
* Drive document ID. Document IDs consist of alphanumeric characters, hyphens and underscores.
363+
* This prevents SSRF by ensuring the ID cannot be used to escape the expected URL path.
364+
*
365+
* @param docId the document ID to validate
366+
* @return true if the document ID is valid
367+
*/
368+
private boolean isValidGoogleDriveDocumentId(String docId) {
369+
return docId != null && !docId.isEmpty() && docId.matches("[a-zA-Z0-9_\\-]+");
370+
}
371+
355372
private Map<String, Object> buildResponse(Object id, Object result) {
356373
Map<String, Object> response = new LinkedHashMap<>();
357374
response.put("jsonrpc", JSONRPC_VERSION);

src/main/java/org/owasp/wrongsecrets/challenges/docker/Challenge8.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.google.api.client.util.Strings;
44
import java.security.SecureRandom;
5-
import java.util.Random;
65
import lombok.extern.slf4j.Slf4j;
76
import org.owasp.wrongsecrets.challenges.FixedAnswerChallenge;
87
import org.springframework.beans.factory.annotation.Value;
@@ -16,7 +15,7 @@ public class Challenge8 extends FixedAnswerChallenge {
1615
private static final String alphabet =
1716
"0123456789QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm";
1817

19-
private final Random secureRandom = new SecureRandom();
18+
private final SecureRandom secureRandom = new SecureRandom();
2019
private final String serverCode;
2120

2221
public Challenge8(@Value("${challenge_acht_ctf_host_value}") String serverCode) {

src/main/java/org/owasp/wrongsecrets/challenges/docker/challenge30/Challenge30.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.google.common.base.Strings;
44
import java.security.SecureRandom;
5-
import java.util.Random;
65
import org.owasp.wrongsecrets.challenges.Challenge;
76
import org.owasp.wrongsecrets.challenges.Spoiler;
87
import org.springframework.stereotype.Component;
@@ -12,7 +11,7 @@
1211
*/
1312
@Component
1413
public class Challenge30 implements Challenge {
15-
private final Random secureRandom = new SecureRandom();
14+
private final SecureRandom secureRandom = new SecureRandom();
1615
private static final String alphabet =
1716
"0123456789QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm";
1817
private String solution;

0 commit comments

Comments
 (0)