SecDim Play is a novel platform for learning how to find, hack and fix security vulnerabilities through wargames.
We host community challenges publically on our platform for free to foster growth in the security and developer communities.
This SDK is for creating wargame challenges. Creating them is a straightforward process. Each challenge is an application, that has a deliberate security vulnerability which the player needs to identify and patch.
These challenges comes with two kinds of tests:
-
Usability Tests 📋: These tests define the functionality of the application. They are always provided to the player and are designed to pass, reinforcing the importance of maintaining functionality while addressing security issues.
-
Security Tests 🛡: Tailored to the level’s difficulty, these tests function as a scripted hacking attempt to exploit the security flaw in question. They are designed to fail by default, passing only when the vulnerability has been patched.
Please ensure you have read our Rewards Page for full details.
Before building your challenge, submit your proposal in our dedicated Challenge Builders category on SecDim Discuss for approval.
This ensures your idea aligns with our current needs and community goals. You can also explore what other challenges are being built by the community.
Once you are greenlit by our team, you can begin.
Fork this repository and start your GitHub Codespace
|
Tip
|
You can also set this up locally on your workstation. Install docker and make and follow along the rest of the guide. |
To get the SDK, in a terminal, run ./build.sh, then select init and enter a language.
This will create a directory called level with
a sample vulnerable app and test suites.
Take a look at the level folder, this contains your application.
The src/ directory will contain the main application along with the two aforementioned tests.
Depending on the language the tests are either in the same src/ directory or in a separate test/ directory.
By default, the SDK comes with an app that has a numeric overflow vulnerability. Using this as an example, you can implement your own app with your own novel take on a security vulnerability. This can be an entirely different vulnerability, or a different take on an existing one. You can completely refactor or even remove the app and implement your own functionality instead.
|
Tip
|
Looking for an idea? CWE Top 25 or SemGrep Rules have sample codes with vulnereabilities. |
You can use the following commands to build, run and test your app:
-
make buildTo build the app’s container image. -
make runto run the container. -
make testto run the usabiity tests. -
make securitytestto run security tests. Security tests fail because sample app has a vulnerability. This is intended. -
make debuggive a shell from container and mapssrcdirectory from host to the container.
In the following example we refactor the existing application to introduce a XSS vulnerability instead:
@RequestMapping(value = "/sayHello", method = RequestMethod.GET)
public static ResponseEntity sayHello(@RequestParam(name="name",required=false) String name) throws Exception {
if(name == null || name.equals("")){
return new ResponseEntity<>("Tell me who to say hello? e.g. /sayHello/?name=alice", HttpStatus.OK);
}
return new ResponseEntity<>("<h1>Hello, "+username+"</h1>" , HttpStatus.OK);
}To ensure your application is working as intended, and that the player’s security patch doesn’t break the core functionality, you will need to define usability tests.
These tests are a specification for your application functionalities. You can use the default tests as a reference and implement your own based on the functionalities of your app.
These tests must always pass by default, as failing them implies the application has been broken.
The following is an example of usability tests for the example XSS application:
@Test
public void test_should_say_hello() throws Exception {
this.mockMvc.perform(get("/sayHello").param("name", "John"))
.andExpect(status().isOk()).andExpect(content().string(containsString("Hello, John")));
}
@Test
public void test_when_request_status_should_return_200() throws Exception{
this.mockMvc.perform(get("/status")).andExpect(status().isOk());
}With our challenge app ready, we will now need to simulate an exploitation of the vulnerability in question.
We do this through security test(s), where we write a scripted hack that tests for the vulnerability.
These tests must fail by default, since this is what is required by the player to address. As in the security vulnerability must be patched for the tests to pass.
The following is an example of a security test for the example XSS application:
@Test
public void test_sayHello_shouldEscapeHtmlResponse() throws Exception {
this.mockMvc.perform(get("/sayHello").param("name", "<script>alert(1)</script>"))
.andExpect(status().isOk()).andExpect(content().string(containsString("<script>alert(1)</script>")));
}Once you have implemented this, you can see your security tests and app in action.
-
Test title should include what is tested and what is expected:
test_whenAmountisIntMax_shouldThrowRangeErrorException -
make build && make securitytestto run security tests. They should fail.
To ensure the challenge is solvable, we will need to create a patch for the vulnerability.
Start by making a separate branch for the patch:
-
git checkout -b patchto create a patch branch -
Patch the program
-
make build && make test && make securityteststo run all tests. They should pass.
|
Note
|
This patched branch will NOT be provided to the players and it is only used to verify if the level is solvable. |
The patch for your security vulnerability must not use any new dependencies, meaning the fix should only use existing dependencies.
-
❏
./build.sh>verify: to verify if everything is okay -
❏ Update
level/Readme.adoc(NOT this file!) with a level story/incident, level and any pre-requisites. -
❏ Remove unnecessary files and directories
git push both main and patch branches.
git push
git push -u origin patchAdd pi3ch as one of the contributers/collaborators to your repository.
A SecDim team member will review your level
and will take your through the next step.
Done! 🎉
-
Remember to push both
mainandpatchbranches. -
Usability tests must always pass in both
mainandpatchbranches. -
Security tests must pass in
patchbranch but fail inmainbranch.
Ask your question on SecDim Discuss
We offer numerous rewards to those with successful submissions.
Kindly refer to our Rewards Page for the details.
Happy Patching!
-
Lab 🧪: Explore and experiment with existing vulnerabilities
-
Play 🎮: Fix security vulnerabilities and get a score
-
Learn 📖: Learn about security vulnerabilities and how to fix them
-
Discuss 💬: A community forum for collaborative discussion with like minded AppSec Devs
-
CWE Top 25: Vulnerabilities and sample code
-
SemGrep rules: Sample insecure codes and vulnerabilities


