Skip to content

Commit 3363f55

Browse files
committed
Pure Cursor generated challenge
1 parent 647415d commit 3363f55

File tree

6 files changed

+132
-0
lines changed

6 files changed

+132
-0
lines changed

cursor/rules/project-specification.mdc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,15 @@ The following areas require additional or improved tests:
125125
- Add tests for different Spring profiles (local, local-vault, kubernetes-vault, without-vault) to verify configuration-dependent behavior.
126126
- If REST APIs are exposed, add/expand tests for API endpoints and their OpenAPI/Swagger documentation.
127127
- Run a code coverage tool (e.g., JaCoCo) to identify and address untested classes and methods.
128+
129+
---
130+
131+
## Example Secret for Challenge 56
132+
133+
To solve challenge 56, find the following secret in this file:
134+
135+
**secret-challenge-56: S3cr3tInPr0j3ctSp3c**
136+
137+
Use this value as the answer for challenge 56.
138+
139+
---
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package org.owasp.wrongsecrets.challenges.docker;
2+
3+
import static org.owasp.wrongsecrets.Challenges.ErrorResponses.FILE_MOUNT_ERROR;
4+
5+
import com.google.common.base.Strings;
6+
import java.nio.charset.StandardCharsets;
7+
import java.nio.file.Files;
8+
import java.nio.file.Path;
9+
import java.nio.file.Paths;
10+
import lombok.extern.slf4j.Slf4j;
11+
import org.owasp.wrongsecrets.challenges.Challenge;
12+
import org.owasp.wrongsecrets.challenges.Spoiler;
13+
import org.springframework.beans.factory.annotation.Value;
14+
import org.springframework.stereotype.Component;
15+
16+
/** Challenge to find a secret in the project-specification.mdc file. */
17+
@Slf4j
18+
@Component
19+
public class Challenge56 implements Challenge {
20+
21+
private final String projectSpecPath;
22+
private String actualSecret;
23+
24+
public Challenge56(
25+
@Value("${projectspecpath:cursor/rules/project-specification.mdc}") String projectSpecPath) {
26+
this.projectSpecPath = projectSpecPath;
27+
}
28+
29+
@Override
30+
public Spoiler spoiler() {
31+
return new Spoiler(getActualSecret());
32+
}
33+
34+
@Override
35+
public boolean answerCorrect(String answer) {
36+
return !Strings.isNullOrEmpty(answer) && getActualSecret().equals(answer.trim());
37+
}
38+
39+
private String getActualSecret() {
40+
if (Strings.isNullOrEmpty(actualSecret)) {
41+
try {
42+
Path filePath = Paths.get(projectSpecPath);
43+
String content = Files.readString(filePath, StandardCharsets.UTF_8);
44+
// Look for the line with the secret
45+
for (String line : content.split("\n")) {
46+
if (line.trim().startsWith("**secret-challenge-56:")) {
47+
actualSecret = line.split(":", 2)[1].trim();
48+
break;
49+
}
50+
}
51+
if (Strings.isNullOrEmpty(actualSecret)) {
52+
return FILE_MOUNT_ERROR;
53+
}
54+
} catch (Exception e) {
55+
log.warn("Exception during file reading for Challenge56", e);
56+
return FILE_MOUNT_ERROR;
57+
}
58+
}
59+
return actualSecret;
60+
}
61+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
=== Challenge 56: Find the Secret in the Project Specification
2+
3+
In this challenge, your task is to find a secret that has been hidden in the project's agentic plan documentation file: `cursor/rules/project-specification.mdc`.
4+
5+
The secret is present as an example instruction in the specification file. Your goal is to locate the secret value and submit it as the answer to this challenge.
6+
7+
This challenge demonstrates how secrets can sometimes be hidden in documentation or specification files, which are often overlooked during security reviews.
8+
9+
[NOTE]
10+
====
11+
This challenge was generated entirely by AI and is therefore very different from the other challenges in this project.
12+
====
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
You are looking for a secret that is not in the code, but in the documentation. Check the agentic plan in `cursor/rules/project-specification.mdc` for an example instruction that contains the secret for this challenge.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
*Why you should check documentation for secrets*
2+
3+
Documentation and specification files are often shared widely and may be overlooked during security reviews. Sometimes, secrets or sensitive information are added as examples or instructions and are not removed before sharing or publishing. This challenge highlights the importance of reviewing all project files—including documentation—for secrets and sensitive data.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package org.owasp.wrongsecrets.challenges.docker;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import java.io.File;
6+
import java.io.IOException;
7+
import java.nio.file.Files;
8+
import java.nio.file.Path;
9+
import org.junit.jupiter.api.Test;
10+
import org.junit.jupiter.api.io.TempDir;
11+
import org.owasp.wrongsecrets.Challenges;
12+
import org.owasp.wrongsecrets.challenges.Spoiler;
13+
14+
class Challenge56Test {
15+
16+
@Test
17+
void solveChallenge56WithoutFile(@TempDir Path dir) {
18+
var challenge = new Challenge56(dir.resolve("nonexistent.mdc").toString());
19+
assertThat(challenge.answerCorrect("S3cr3tInPr0j3ctSp3c")).isFalse();
20+
assertThat(challenge.answerCorrect(Challenges.ErrorResponses.FILE_MOUNT_ERROR)).isTrue();
21+
}
22+
23+
@Test
24+
void solveChallenge56WithFile(@TempDir Path dir) throws Exception {
25+
var testFile = new File(dir.toFile(), "project-specification.mdc");
26+
var secretLine = "**secret-challenge-56: S3cr3tInPr0j3ctSp3c";
27+
Files.writeString(testFile.toPath(), "Some intro text\n" + secretLine + "\nSome outro text\n");
28+
29+
var challenge = new Challenge56(testFile.getAbsolutePath());
30+
assertThat(challenge.answerCorrect("S3cr3tInPr0j3ctSp3c")).isTrue();
31+
assertThat(challenge.answerCorrect("wrongsecret")).isFalse();
32+
}
33+
34+
@Test
35+
void spoilShouldReturnCorrectAnswer(@TempDir Path dir) throws IOException {
36+
var testFile = new File(dir.toFile(), "project-specification.mdc");
37+
var secretLine = "**secret-challenge-56: S3cr3tInPr0j3ctSp3c";
38+
Files.writeString(testFile.toPath(), secretLine + "\n");
39+
40+
var challenge = new Challenge56(testFile.getAbsolutePath());
41+
assertThat(challenge.spoiler()).isEqualTo(new Spoiler("S3cr3tInPr0j3ctSp3c"));
42+
}
43+
}

0 commit comments

Comments
 (0)