Skip to content

Commit 6badb8c

Browse files
Copilotcommjoen
andcommitted
Add comprehensive GitHub Copilot instructions for OWASP WrongSecrets
Co-authored-by: commjoen <[email protected]>
1 parent d337db3 commit 6badb8c

File tree

1 file changed

+269
-0
lines changed

1 file changed

+269
-0
lines changed

.github/copilot-instructions.md

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
# OWASP WrongSecrets - Copilot Instructions
2+
3+
Welcome to the OWASP WrongSecrets project! This document provides GitHub Copilot with essential context to help you contribute effectively to this educational cybersecurity project.
4+
5+
## Project Overview
6+
7+
**WrongSecrets** is an intentionally vulnerable Spring Boot application designed to teach secrets management through real-world examples of what NOT to do. The project contains 56+ challenges where developers must find exposed secrets in code, configuration files, containers, and cloud deployments.
8+
9+
**⚠️ Important**: This repository contains **intentionally vulnerable code** for educational purposes. When contributing, maintain this educational intent while following secure coding practices in the framework itself.
10+
11+
## Repository Structure
12+
13+
```
14+
wrongsecrets/
15+
├── src/main/java/org/owasp/wrongsecrets/
16+
│ ├── challenges/ # Challenge implementations
17+
│ │ ├── docker/ # Docker-specific challenges
18+
│ │ ├── cloud/ # Cloud provider challenges (AWS/GCP/Azure)
19+
│ │ ├── kubernetes/ # K8s and Vault challenges
20+
│ │ └── FixedAnswerChallenge.java # Base class for simple challenges
21+
│ ├── definitions/ # Challenge metadata and configuration
22+
│ ├── oauth/ # Authentication components
23+
│ └── WrongSecretsApplication.java # Main Spring Boot application
24+
├── src/test/java/ # Test files mirroring main structure
25+
├── src/main/resources/ # Configuration files and web assets
26+
├── .github/workflows/ # CI/CD pipelines
27+
├── docs/ # Project documentation
28+
└── k8s/, aws/, gcp/, azure/ # Deployment configurations
29+
```
30+
31+
## Technology Stack
32+
33+
- **Framework**: Spring Boot 3.5.x
34+
- **Java Version**: 23 (configured in pom.xml)
35+
- **Build Tool**: Maven (use `./mvnw`)
36+
- **Testing**: JUnit 5, Spring Boot Test
37+
- **Container**: Docker + Kubernetes
38+
- **Cloud**: AWS, GCP, Azure integrations
39+
- **Frontend**: Thymeleaf templates, Bootstrap CSS
40+
41+
## Development Patterns
42+
43+
### Challenge Implementation
44+
45+
**For challenges with fixed answers** (most common):
46+
47+
```java
48+
@Component
49+
public class Challenge[Number] extends FixedAnswerChallenge {
50+
51+
private final RuntimeEnvironment runtimeEnvironment;
52+
53+
public Challenge[Number](RuntimeEnvironment runtimeEnvironment) {
54+
this.runtimeEnvironment = runtimeEnvironment;
55+
}
56+
57+
@Override
58+
public String getAnswer() {
59+
// Return the secret that users need to find
60+
return "the-secret-value";
61+
}
62+
63+
@Override
64+
public boolean canRunInCTFMode() {
65+
return true; // Set to false if challenge can't run in CTF mode
66+
}
67+
68+
@Override
69+
public RuntimeEnvironment.Environment supportedRuntimeEnvironments() {
70+
return RuntimeEnvironment.Environment.DOCKER; // or ALL, K8S, etc.
71+
}
72+
}
73+
```
74+
75+
**For challenges with dynamic answers**:
76+
77+
```java
78+
@Component
79+
public class Challenge[Number] implements Challenge {
80+
81+
@Override
82+
public Spoiler spoiler() {
83+
return new Spoiler(calculateAnswer());
84+
}
85+
86+
@Override
87+
public boolean answerCorrect(String answer) {
88+
return Objects.equals(calculateAnswer(), answer);
89+
}
90+
91+
private String calculateAnswer() {
92+
// Complex logic here
93+
}
94+
}
95+
```
96+
97+
### Testing Patterns
98+
99+
**Challenge tests should**:
100+
101+
```java
102+
@ExtendWith(MockitoExtension.class)
103+
class Challenge[Number]Test {
104+
105+
@Mock
106+
private RuntimeEnvironment runtimeEnvironment;
107+
108+
@InjectMocks
109+
private Challenge[Number] challenge;
110+
111+
@Test
112+
void answerCorrect() {
113+
// Test the correct answer
114+
assertTrue(challenge.answerCorrect(challenge.spoiler().solution()));
115+
}
116+
117+
@Test
118+
void answerIncorrect() {
119+
// Test incorrect answers
120+
assertFalse(challenge.answerCorrect("wrong-answer"));
121+
}
122+
123+
@Test
124+
void canRunInCTFMode() {
125+
// Test CTF mode support
126+
assertTrue(challenge.canRunInCTFMode());
127+
}
128+
}
129+
```
130+
131+
## Code Style Guidelines
132+
133+
### Java Conventions
134+
135+
- **Package naming**: Follow existing structure under `org.owasp.wrongsecrets`
136+
- **Class naming**:
137+
- Challenges: `Challenge[Number]` (e.g., `Challenge1`, `Challenge42`)
138+
- Tests: `Challenge[Number]Test`
139+
- **Formatting**: Use standard Spring Boot/Google Java style
140+
- **Imports**: Avoid wildcard imports, group logically
141+
- **Documentation**: JavaDoc for public APIs, inline comments for complex logic
142+
143+
### Spring Boot Patterns
144+
145+
- **Configuration**: Use `@ConfigurationProperties` for external config
146+
- **Profiles**: Support `docker`, `k8s`, `aws`, `gcp`, `azure` profiles
147+
- **Components**: Use `@Component`, `@Service`, `@Controller` appropriately
148+
- **Environment**: Access via `RuntimeEnvironment` service, not direct `@Value`
149+
150+
### Security Considerations
151+
152+
**When writing framework code** (not challenge vulnerabilities):
153+
154+
- ✅ Use parameterized queries
155+
- ✅ Validate and sanitize inputs
156+
- ✅ Implement proper authentication/authorization
157+
- ✅ Follow OWASP secure coding practices
158+
- ✅ Use secure random generators
159+
- ✅ Avoid hardcoded credentials in framework code
160+
161+
**When creating challenge vulnerabilities** (educational content):
162+
163+
- ✅ Document the vulnerability type clearly
164+
- ✅ Ensure vulnerability is realistic and educational
165+
- ✅ Include hints and explanations for learners
166+
- ✅ Make secrets discoverable but not trivial
167+
168+
## Common Tasks
169+
170+
### Adding a New Challenge
171+
172+
1. **Determine challenge type**: Fixed answer or dynamic?
173+
2. **Choose appropriate package**: `docker/`, `cloud/`, `kubernetes/`
174+
3. **Implement challenge class**: Extend `FixedAnswerChallenge` or implement `Challenge`
175+
4. **Add corresponding test**: Mirror the package structure in `src/test/`
176+
5. **Update configuration**: Add to `ChallengeDefinitionsConfiguration` if needed
177+
6. **Document**: Add challenge description and hints
178+
179+
### Running the Application
180+
181+
```bash
182+
# Build and compile
183+
./mvnw clean compile
184+
185+
# Run tests
186+
./mvnw test
187+
188+
# Run application locally
189+
./mvnw spring-boot:run
190+
191+
# Run with specific profile
192+
./mvnw spring-boot:run -Dspring.profiles.active=docker
193+
194+
# Run specific test
195+
./mvnw test -Dtest=Challenge1Test
196+
```
197+
198+
### Docker Commands
199+
200+
```bash
201+
# Build container
202+
docker build -t wrongsecrets .
203+
204+
# Run locally
205+
docker run -p 8080:8080 wrongsecrets
206+
```
207+
208+
## Testing Guidelines
209+
210+
- **Unit tests**: Test challenge logic, answer validation
211+
- **Integration tests**: Test Spring context, controller endpoints
212+
- **E2E tests**: Cypress tests for UI interactions
213+
- **Profile tests**: Test different environment configurations
214+
215+
### Test Structure
216+
217+
```java
218+
// Arrange
219+
when(runtimeEnvironment.getRuntimeEnvironment())
220+
.thenReturn(RuntimeEnvironment.Environment.DOCKER);
221+
222+
// Act
223+
String result = challenge.getAnswer();
224+
225+
// Assert
226+
assertThat(result).isEqualTo("expected-secret");
227+
```
228+
229+
## Environment Variables
230+
231+
Common environment variables used in challenges:
232+
233+
- `SPRING_PROFILES_ACTIVE`: Runtime environment (docker, k8s, aws, etc.)
234+
- `K8S_ENV`: Kubernetes environment flag
235+
- `wrongsecret[number]`: Challenge-specific secrets
236+
- Cloud-specific: AWS/GCP/Azure credentials and configurations
237+
238+
## Performance Considerations
239+
240+
- **Fixed challenges**: Use caching via `FixedAnswerChallenge`
241+
- **Heavy operations**: Cache results, use lazy initialization
242+
- **External calls**: Mock in tests, handle failures gracefully
243+
- **Memory**: Be mindful of static collections and caching
244+
245+
## Documentation
246+
247+
- **README.md**: Keep setup instructions current
248+
- **CONTRIBUTING.md**: Follow established patterns
249+
- **JavaDoc**: Document public APIs and complex logic
250+
- **Challenge hints**: Provide educational guidance without giving away answers
251+
252+
## Common Pitfalls to Avoid
253+
254+
- ❌ Don't expose real secrets in challenge code
255+
- ❌ Don't break existing challenge numbering
256+
- ❌ Don't hardcode environment-specific values
257+
- ❌ Don't skip tests for new functionality
258+
- ❌ Don't ignore existing code patterns
259+
- ❌ Don't modify unrelated challenges when adding new ones
260+
261+
## Getting Help
262+
263+
- **Documentation**: Check `docs/` directory for detailed guides
264+
- **Existing code**: Look at similar challenges for patterns
265+
- **Tests**: Examine test files for usage examples
266+
- **GitHub Issues**: Search existing issues and discussions
267+
- **OWASP Slack**: Join #project-wrongsecrets channel
268+
269+
Remember: This is an educational project teaching security through intentionally vulnerable examples. Balance realistic vulnerabilities with clear learning outcomes while keeping the framework itself secure and maintainable.

0 commit comments

Comments
 (0)