-
-
Notifications
You must be signed in to change notification settings - Fork 547
feat(challenge): add Challenge 63 hardcoded AES encryption key #2492
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
moeedrehman135
wants to merge
4
commits into
OWASP:master
Choose a base branch
from
moeedrehman135:feat/challenge63-hardcoded-encryption-key
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
91e3d4e
feat(challenge): add Challenge 63 hardcoded AES encryption key
moeedrehman135 35e02c4
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] 0e4cf24
fix(challenge63): add explicit constructor and document intentional C…
moeedrehman135 12ca170
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
47 changes: 47 additions & 0 deletions
47
src/main/java/org/owasp/wrongsecrets/challenges/docker/challenge63/Challenge63.java
This file contains hidden or 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,47 @@ | ||
| package org.owasp.wrongsecrets.challenges.docker.challenge63; | ||
|
|
||
| import lombok.extern.slf4j.Slf4j; | ||
| import org.owasp.wrongsecrets.challenges.Challenge; | ||
| import org.owasp.wrongsecrets.challenges.Spoiler; | ||
| import org.springframework.stereotype.Component; | ||
|
|
||
| import javax.crypto.Cipher; | ||
| import javax.crypto.spec.IvParameterSpec; | ||
| import javax.crypto.spec.SecretKeySpec; | ||
| import java.util.Base64; | ||
|
|
||
| @Slf4j | ||
| @Component | ||
| public class Challenge63 implements Challenge { | ||
|
|
||
| private static final String HARDCODED_KEY = "SuperSecretKey12"; | ||
| private static final String HARDCODED_IV = "InitVector123456"; | ||
| private static final String CIPHERTEXT = "TDPwOvcLsbCWV5erlk6OHFnlFoXNtdQOt2JQeq+i4Ho="; | ||
|
|
||
| @Override | ||
| public Spoiler spoiler() { | ||
| return new Spoiler(getAnswer()); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean answerCorrect(String answer) { | ||
| return getAnswer().equals(answer); | ||
| } | ||
|
|
||
| private String getAnswer() { | ||
| try { | ||
| byte[] keyBytes = HARDCODED_KEY.getBytes("UTF-8"); | ||
| byte[] ivBytes = HARDCODED_IV.getBytes("UTF-8"); | ||
| byte[] cipherBytes = Base64.getDecoder().decode(CIPHERTEXT); | ||
| SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); | ||
| IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); | ||
| Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); | ||
Check failureCode scanning / CodeQL Use of a broken or risky cryptographic algorithm High
Cryptographic algorithm
AES/CBC/PKCS5Padding Error loading related location Loading |
||
| cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); | ||
| byte[] decrypted = cipher.doFinal(cipherBytes); | ||
| return new String(decrypted, "UTF-8").trim(); | ||
| } catch (Exception e) { | ||
| log.error("Decryption failed", e); | ||
| return "decryption-error"; | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or 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,24 @@ | ||
| === Hardcoded Encryption Key Challenge | ||
| This challenge demonstrates a common but dangerous mistake: encrypting a secret while hardcoding the encryption key in the same source file. | ||
|
|
||
| A developer has attempted to protect a secret by encrypting it with AES. However, both the encryption key and the initialization vector (IV) are hardcoded directly in the Java source code alongside the ciphertext. This makes the encryption completely ineffective — anyone with access to the source code can decrypt the secret trivially. | ||
|
|
||
| **Your goal:** | ||
| 1. **Find the Java source file** for this challenge in the codebase | ||
| 2. **Locate the hardcoded AES key and IV** in the source code | ||
| 3. **Decrypt the ciphertext** using the key and IV you found | ||
| 4. **Submit the plaintext** as your answer | ||
|
|
||
| **How to decrypt:** | ||
| [source,bash] | ||
| ---- | ||
| echo "TDPwOvcLsbCWV5erlk6OHFnlFoXNtdQOt2JQeq+i4Ho=" | openssl enc -d -aes-128-cbc \ | ||
| -K $(echo -n "SuperSecretKey12" | xxd -p) \ | ||
| -iv $(echo -n "InitVector123456" | xxd -p) \ | ||
| -base64 | ||
| ---- | ||
|
|
||
| **** | ||
| *Note:* | ||
| The key insight here is that encryption does NOT protect a secret if the key is stored alongside the ciphertext. This is equivalent to locking a box and taping the key to the outside. | ||
| **** |
This file contains hidden or 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,26 @@ | ||
| === Hint for Challenge 63 | ||
| This challenge demonstrates bad encryption practices — specifically hardcoding an AES key in source code. | ||
|
|
||
| **Where to look:** | ||
| 1. **Find the Challenge63 Java source file** in the `challenges/docker/challenge63/` directory | ||
| 2. **Look for static final String constants** near the top of the class | ||
| 3. **You will find the AES key, IV, and ciphertext** all in the same file | ||
|
|
||
| **How to decrypt once you have the key:** | ||
| [source,python] | ||
| ---- | ||
| from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes | ||
| from cryptography.hazmat.backends import default_backend | ||
| import base64 | ||
|
|
||
| key = b'SuperSecretKey12' | ||
| iv = b'InitVector123456' | ||
| ciphertext = base64.b64decode("TDPwOvcLsbCWV5erlk6OHFnlFoXNtdQOt2JQeq+i4Ho=") | ||
|
|
||
| cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) | ||
| decryptor = cipher.decryptor() | ||
| plaintext = decryptor.update(ciphertext) + decryptor.finalize() | ||
| print(plaintext.strip()) | ||
| ---- | ||
|
|
||
| **Remember:** If an attacker can read your source code, hardcoded keys offer zero protection. |
This file contains hidden or 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,21 @@ | ||
| === Reason for Challenge 63 | ||
| This challenge highlights a widespread mistake in software development: using encryption while storing the key in the same location as the ciphertext. | ||
|
|
||
| **Why this is dangerous:** | ||
| - Encryption is only as strong as the secrecy of the key | ||
| - Hardcoding the key in source code means anyone with repository access can decrypt the secret | ||
| - Source code is often more widely accessible than developers realize — through Git history, leaked repos, or insider access | ||
| - Many secret scanning tools will detect both the key and ciphertext patterns | ||
|
|
||
| **The correct approach:** | ||
| - Store encryption keys in a dedicated secrets manager (AWS Secrets Manager, HashiCorp Vault, etc.) | ||
| - Never commit keys to version control | ||
| - Use environment variables for keys, not source code constants | ||
| - Consider whether encryption is even necessary if the key must live near the data | ||
|
|
||
| **Real world examples:** | ||
| This exact pattern has been found in numerous data breaches where developers believed their secrets were "safe" because they were encrypted, not realizing the key was equally exposed. | ||
|
|
||
| **References:** | ||
| - https://owasp.org/www-project-top-ten/[OWASP Top 10] | ||
| - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html[OWASP Secrets Management Cheat Sheet] |
This file contains hidden or 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
28 changes: 28 additions & 0 deletions
28
src/test/java/org/owasp/wrongsecrets/challenges/docker/Challenge63Test.java
This file contains hidden or 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,28 @@ | ||
| package org.owasp.wrongsecrets.challenges.docker; | ||
|
|
||
| import org.junit.jupiter.api.Test; | ||
| import org.owasp.wrongsecrets.challenges.docker.challenge63.Challenge63; | ||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||
| import static org.junit.jupiter.api.Assertions.assertTrue; | ||
| import static org.junit.jupiter.api.Assertions.assertFalse; | ||
|
|
||
| class Challenge63Test { | ||
|
|
||
| @Test | ||
| void testAnswerIsCorrect() { | ||
| Challenge63 challenge = new Challenge63(); | ||
| assertTrue(challenge.answerCorrect("wh0sp1ay1ngwrongs3cr3ts")); | ||
| } | ||
|
|
||
| @Test | ||
| void testWrongAnswerIsRejected() { | ||
| Challenge63 challenge = new Challenge63(); | ||
| assertFalse(challenge.answerCorrect("wronganswer")); | ||
| } | ||
|
|
||
| @Test | ||
| void testSpoilerRevealsAnswer() { | ||
| Challenge63 challenge = new Challenge63(); | ||
| assertEquals("wh0sp1ay1ngwrongs3cr3ts", challenge.spoiler().solution()); | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.