Skip to content

Commit a98867c

Browse files
authored
Merge pull request #2164 from OWASP/copilot/fix-2163
Setup Copilot instructions and pre-commit workflow for OWASP WrongSecrets
2 parents 131b11f + a4629f4 commit a98867c

File tree

3 files changed

+340
-1
lines changed

3 files changed

+340
-1
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.

.github/scripts/setup-precommit.sh

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/bin/bash
2+
3+
# Setup pre-commit hooks for OWASP WrongSecrets contributors
4+
# This script ensures that all pre-commit checks are installed and configured
5+
6+
set -e
7+
8+
echo "🔧 Setting up pre-commit hooks for OWASP WrongSecrets..."
9+
10+
# Check if pre-commit is installed
11+
if ! command -v pre-commit &> /dev/null; then
12+
echo "📦 Installing pre-commit..."
13+
python3 -m pip install --user pre-commit
14+
fi
15+
16+
# Install pre-commit hooks
17+
echo "⚡ Installing pre-commit hooks..."
18+
pre-commit install
19+
20+
# Install commit-msg hook for commitlint
21+
echo "📝 Installing commit-msg hook..."
22+
pre-commit install --hook-type commit-msg
23+
24+
echo "✅ Pre-commit setup complete!"
25+
echo ""
26+
echo "📋 Available commands:"
27+
echo " pre-commit run --all-files # Run all hooks on all files"
28+
echo " pre-commit run <hook-name> # Run specific hook"
29+
echo " pre-commit autoupdate # Update hook versions"
30+
echo ""
31+
echo "💡 Pre-commit will now run automatically on every commit!"
32+
echo " To bypass pre-commit checks (not recommended): git commit --no-verify"

CONTRIBUTING.md

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ cd wrongsecrets
3232
./mvnw clean compile
3333
./mvnw test -Dtest=ChallengesControllerTest
3434

35-
# 3. Run the application locally
35+
# 3. Setup pre-commit hooks (recommended)
36+
./.github/scripts/setup-precommit.sh
37+
38+
# 4. Run the application locally
3639
./mvnw spring-boot:run
3740
# Visit http://localhost:8080 to see the app running
3841
```
@@ -108,6 +111,41 @@ The minimum requirements for code contributions are:
108111

109112
And please note that this project has *three months* implementation windows. So once you've been assigned to a task/issue, try to make your PR accepted within this period.
110113

114+
### 🔧 Pre-commit Hooks Setup
115+
116+
**Important:** Always run pre-commit checks before submitting your PR to avoid CI failures.
117+
118+
#### Quick Setup
119+
```bash
120+
# Automated setup (recommended)
121+
./.github/scripts/setup-precommit.sh
122+
123+
# Manual setup
124+
pip install pre-commit
125+
pre-commit install
126+
pre-commit install --hook-type commit-msg
127+
```
128+
129+
#### Running Checks
130+
```bash
131+
# Check all files
132+
pre-commit run --all-files
133+
134+
# Check specific file
135+
pre-commit run --files path/to/your/file.md
136+
137+
# Check what will run on next commit
138+
pre-commit run
139+
```
140+
141+
#### Common Issues & Fixes
142+
- **Trailing whitespace**: Automatically fixed by pre-commit
143+
- **Missing newlines**: Automatically fixed by pre-commit
144+
- **Java formatting**: Run `./mvnw spotless:apply`
145+
- **Commit message format**: Follow [Conventional Commits](https://www.conventionalcommits.org/)
146+
147+
💡 **Tip**: Pre-commit hooks will run automatically on every commit after installation!
148+
111149
Additionally, the following guidelines can help:
112150

113151
### Keep your pull requests limited to a single issue

0 commit comments

Comments
 (0)