From a9caa77b42e512d468f591140af1f76c8ac6b1bc Mon Sep 17 00:00:00 2001 From: Ben de Haan <53901866+bendehaan@users.noreply.github.com> Date: Mon, 13 Mar 2023 17:00:15 +0100 Subject: [PATCH 01/10] feat(#684): add DAST with ZAP --- .github/workflows/minikube-zap-test.yml | 43 +++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 .github/workflows/minikube-zap-test.yml diff --git a/.github/workflows/minikube-zap-test.yml b/.github/workflows/minikube-zap-test.yml new file mode 100644 index 000000000..23d549f5c --- /dev/null +++ b/.github/workflows/minikube-zap-test.yml @@ -0,0 +1,43 @@ +# This is a basic workflow to help you get started with Actions + +name: DAST with ZAP on minikube + +# Controls when the workflow will run +on: + pull_request: + branches: [master] + workflow_dispatch: + +permissions: + contents: read + issues: write + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + test-minikube: + name: Test with minikube and Vault + runs-on: ubuntu-latest + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + - uses: actions/checkout@v3 + - uses: eLco/setup-vault@v1 + - name: Start minikube + uses: medyagh/setup-minikube@master + with: + minikube-version: 1.29.0 + driver: docker + kubernetes-version: v1.25.6 + - name: Setup helm + uses: azure/setup-helm@v3.5 + id: install + - name: Setup application + run: | + ./k8s-vault-minkube-start.sh + - name: ZAP Scan + uses: zaproxy/action-baseline@v0.7.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + docker_name: "owasp/zap2docker-stable" + target: "https://localhost:8080" + - name: Teardown + run: minikube delete From bac8eab901db3d7b972dad70cd2a7522519dc1c8 Mon Sep 17 00:00:00 2001 From: Ben de Haan <53901866+bendehaan@users.noreply.github.com> Date: Mon, 13 Mar 2023 17:04:10 +0100 Subject: [PATCH 02/10] fix: change workflow name --- .github/workflows/minikube-zap-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/minikube-zap-test.yml b/.github/workflows/minikube-zap-test.yml index 23d549f5c..8bc4af32a 100644 --- a/.github/workflows/minikube-zap-test.yml +++ b/.github/workflows/minikube-zap-test.yml @@ -15,7 +15,7 @@ permissions: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: test-minikube: - name: Test with minikube and Vault + name: DAST test with minikube and ZAP runs-on: ubuntu-latest # Steps represent a sequence of tasks that will be executed as part of the job steps: From a00a91c1a5ff6bf29f7d9e11b8d67c67407fa808 Mon Sep 17 00:00:00 2001 From: Ben de Haan <53901866+bendehaan@users.noreply.github.com> Date: Mon, 13 Mar 2023 17:12:43 +0100 Subject: [PATCH 03/10] fix: set http target --- .github/workflows/minikube-zap-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/minikube-zap-test.yml b/.github/workflows/minikube-zap-test.yml index 8bc4af32a..aaa4074a2 100644 --- a/.github/workflows/minikube-zap-test.yml +++ b/.github/workflows/minikube-zap-test.yml @@ -38,6 +38,6 @@ jobs: with: token: ${{ secrets.GITHUB_TOKEN }} docker_name: "owasp/zap2docker-stable" - target: "https://localhost:8080" + target: "http://localhost:8080" - name: Teardown run: minikube delete From 361cdc330c8bb9512514840966d65c3057d1f65a Mon Sep 17 00:00:00 2001 From: Ben de Haan <53901866+bendehaan@users.noreply.github.com> Date: Mon, 13 Mar 2023 17:23:35 +0100 Subject: [PATCH 04/10] fix: add issue title for ZAP --- .github/workflows/minikube-zap-test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/minikube-zap-test.yml b/.github/workflows/minikube-zap-test.yml index aaa4074a2..b7c3792d5 100644 --- a/.github/workflows/minikube-zap-test.yml +++ b/.github/workflows/minikube-zap-test.yml @@ -37,6 +37,7 @@ jobs: uses: zaproxy/action-baseline@v0.7.0 with: token: ${{ secrets.GITHUB_TOKEN }} + issue_title: ZAP DAST scan findings docker_name: "owasp/zap2docker-stable" target: "http://localhost:8080" - name: Teardown From 6d7a02cfe011a8884214c95b2fa2e89b3d2cda2e Mon Sep 17 00:00:00 2001 From: Ben de Haan <53901866+bendehaan@users.noreply.github.com> Date: Mon, 13 Mar 2023 18:58:06 +0100 Subject: [PATCH 05/10] fix: change to run on code Instead of a container on minikube, run on the latest code. --- .github/workflows/dast-zap-test.yml | 31 +++++++++++++++++ .github/workflows/minikube-zap-test.yml | 44 ------------------------- 2 files changed, 31 insertions(+), 44 deletions(-) create mode 100644 .github/workflows/dast-zap-test.yml delete mode 100644 .github/workflows/minikube-zap-test.yml diff --git a/.github/workflows/dast-zap-test.yml b/.github/workflows/dast-zap-test.yml new file mode 100644 index 000000000..9bc75429b --- /dev/null +++ b/.github/workflows/dast-zap-test.yml @@ -0,0 +1,31 @@ +name: DAST with ZAP + +on: + pull_request: + branches: [master] + workflow_dispatch: + +permissions: + contents: read + +jobs: + test-minikube: + name: DAST test with minikube and ZAP + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 19 + uses: actions/setup-java@v3 + with: + java-version: "19" + distribution: "temurin" + - name: Clean install + run: ./mvnw clean install + - name: Start wrongsecrets + run: nohup ./mvnw spring-boot:run -Dspring-boot.run.profiles=without-vault & + - name: ZAP Scan + uses: zaproxy/action-baseline@v0.7.0 + with: + allow_issue_writing: false + docker_name: "owasp/zap2docker-stable" + target: "http://localhost:8080" diff --git a/.github/workflows/minikube-zap-test.yml b/.github/workflows/minikube-zap-test.yml deleted file mode 100644 index b7c3792d5..000000000 --- a/.github/workflows/minikube-zap-test.yml +++ /dev/null @@ -1,44 +0,0 @@ -# This is a basic workflow to help you get started with Actions - -name: DAST with ZAP on minikube - -# Controls when the workflow will run -on: - pull_request: - branches: [master] - workflow_dispatch: - -permissions: - contents: read - issues: write - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - test-minikube: - name: DAST test with minikube and ZAP - runs-on: ubuntu-latest - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - - uses: actions/checkout@v3 - - uses: eLco/setup-vault@v1 - - name: Start minikube - uses: medyagh/setup-minikube@master - with: - minikube-version: 1.29.0 - driver: docker - kubernetes-version: v1.25.6 - - name: Setup helm - uses: azure/setup-helm@v3.5 - id: install - - name: Setup application - run: | - ./k8s-vault-minkube-start.sh - - name: ZAP Scan - uses: zaproxy/action-baseline@v0.7.0 - with: - token: ${{ secrets.GITHUB_TOKEN }} - issue_title: ZAP DAST scan findings - docker_name: "owasp/zap2docker-stable" - target: "http://localhost:8080" - - name: Teardown - run: minikube delete From 863f9c63a66503bb68b161773b24127c2e999344 Mon Sep 17 00:00:00 2001 From: Ben de Haan <53901866+bendehaan@users.noreply.github.com> Date: Mon, 13 Mar 2023 19:01:43 +0100 Subject: [PATCH 06/10] fix: add rule ingore file --- .github/workflows/dast-zap-test.yml | 2 ++ .zap/rule-config.tsv | 10 ++++++++++ 2 files changed, 12 insertions(+) create mode 100644 .zap/rule-config.tsv diff --git a/.github/workflows/dast-zap-test.yml b/.github/workflows/dast-zap-test.yml index 9bc75429b..0ebe1e767 100644 --- a/.github/workflows/dast-zap-test.yml +++ b/.github/workflows/dast-zap-test.yml @@ -29,3 +29,5 @@ jobs: allow_issue_writing: false docker_name: "owasp/zap2docker-stable" target: "http://localhost:8080" + rules_file_name: .zap/rule-config.tsv + fail_action: true diff --git a/.zap/rule-config.tsv b/.zap/rule-config.tsv new file mode 100644 index 000000000..a52dce214 --- /dev/null +++ b/.zap/rule-config.tsv @@ -0,0 +1,10 @@ +10027 IGNORE (Information Disclosure - Suspicious Comments) +10049 IGNORE (Non-Storable Content) +10054 IGNORE (Cookie without SameSite Attribute) +10055 IGNORE (CSP: Wildcard Directive) +10055 IGNORE (CSP: script-src unsafe-inline) +10055 IGNORE (CSP: style-src unsafe-inline) +10063 IGNORE (Permissions Policy Header Not Set) +10109 IGNORE (Modern Web Application) +10110 IGNORE (Dangerous JS Functions) +90033 IGNORE (Loosely Scoped Cookie) \ No newline at end of file From a641d447dfae8831e8d4b92f28b4d90970e01883 Mon Sep 17 00:00:00 2001 From: Ben de Haan <53901866+bendehaan@users.noreply.github.com> Date: Mon, 13 Mar 2023 19:03:51 +0100 Subject: [PATCH 07/10] fix: precommit fixes --- .github/workflows/dast-zap-test.yml | 4 ++-- .zap/rule-config.tsv | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dast-zap-test.yml b/.github/workflows/dast-zap-test.yml index 0ebe1e767..2201c43bb 100644 --- a/.github/workflows/dast-zap-test.yml +++ b/.github/workflows/dast-zap-test.yml @@ -9,8 +9,8 @@ permissions: contents: read jobs: - test-minikube: - name: DAST test with minikube and ZAP + test-dast: + name: DAST test with ZAP runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 diff --git a/.zap/rule-config.tsv b/.zap/rule-config.tsv index a52dce214..620f91b41 100644 --- a/.zap/rule-config.tsv +++ b/.zap/rule-config.tsv @@ -7,4 +7,4 @@ 10063 IGNORE (Permissions Policy Header Not Set) 10109 IGNORE (Modern Web Application) 10110 IGNORE (Dangerous JS Functions) -90033 IGNORE (Loosely Scoped Cookie) \ No newline at end of file +90033 IGNORE (Loosely Scoped Cookie) From 96e715c2c5142206a51dce1e4ee0e0bbdb37889f Mon Sep 17 00:00:00 2001 From: Ben de Haan <53901866+bendehaan@users.noreply.github.com> Date: Tue, 14 Mar 2023 13:24:27 +0100 Subject: [PATCH 08/10] fix: add additional ignore --- .zap/rule-config.tsv | 1 + 1 file changed, 1 insertion(+) diff --git a/.zap/rule-config.tsv b/.zap/rule-config.tsv index 620f91b41..765c0a9f5 100644 --- a/.zap/rule-config.tsv +++ b/.zap/rule-config.tsv @@ -1,4 +1,5 @@ 10027 IGNORE (Information Disclosure - Suspicious Comments) +10031 IGNORE (Informational User Controllable HTML Element Attribute (Potential XSS)) 10049 IGNORE (Non-Storable Content) 10054 IGNORE (Cookie without SameSite Attribute) 10055 IGNORE (CSP: Wildcard Directive) From 2fab5de1038be65dbe005148b3edc5c0c9916096 Mon Sep 17 00:00:00 2001 From: Ben de Haan <53901866+bendehaan@users.noreply.github.com> Date: Tue, 14 Mar 2023 15:02:27 +0100 Subject: [PATCH 09/10] fix: throw 404 when challenge outside range --- .../challenges/ChallengesController.java | 25 +++++++++++++++++++ .../ChallengeAPiControllerTest.java | 2 +- .../ChallengesControllerTest.java | 10 ++++++++ .../canaries/CanaryCallbackTest.java | 4 +-- 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/owasp/wrongsecrets/challenges/ChallengesController.java b/src/main/java/org/owasp/wrongsecrets/challenges/ChallengesController.java index 1d045152c..da9f79396 100644 --- a/src/main/java/org/owasp/wrongsecrets/challenges/ChallengesController.java +++ b/src/main/java/org/owasp/wrongsecrets/challenges/ChallengesController.java @@ -6,6 +6,7 @@ import org.owasp.wrongsecrets.challenges.docker.Challenge0; import org.owasp.wrongsecrets.challenges.docker.Challenge8; import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; import org.springframework.security.crypto.codec.Hex; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.server.ResponseStatusException; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; @@ -53,6 +55,14 @@ public ChallengesController(ScoreCard scoreCard, List challenges, R this.runtimeEnvironment = runtimeEnvironment; } + private boolean checkId(int id) { + // If the id is either negative or larger than the amount of challenges, return false. + if (id < 0 || id >= challenges.size()) { + return false; + } + return true; + } + @GetMapping public String explanation(@PathVariable Integer id) { return challenges.get(id).getExplanation(); @@ -71,6 +81,11 @@ public String spoiler(Model model, @PathVariable Integer id) { @GetMapping("/challenge/{id}") public String challenge(Model model, @PathVariable Integer id) { + if (!checkId(id)) { + throw new ResponseStatusException( + HttpStatus.NOT_FOUND, "challenge not found" + ); + } var challenge = challenges.get(id); model.addAttribute("challengeForm", new ChallengeForm("")); @@ -98,6 +113,11 @@ public String challenge(Model model, @PathVariable Integer id) { @PostMapping(value = "/challenge/{id}", params = "action=reset") public String reset(@ModelAttribute ChallengeForm challengeForm, @PathVariable Integer id, Model model) { + if (!checkId(id)) { + throw new ResponseStatusException( + HttpStatus.NOT_FOUND, "challenge not found" + ); + } var challenge = challenges.get(id); scoreCard.reset(challenge.getChallenge()); @@ -110,6 +130,11 @@ public String reset(@ModelAttribute ChallengeForm challengeForm, @PathVariable I @PostMapping(value = "/challenge/{id}", params = "action=submit") public String postController(@ModelAttribute ChallengeForm challengeForm, Model model, @PathVariable Integer id) { + if (!checkId(id)) { + throw new ResponseStatusException( + HttpStatus.NOT_FOUND, "challenge not found" + ); + } var challenge = challenges.get(id); if (!challenge.isChallengeEnabled()) { diff --git a/src/test/java/org/owasp/wrongsecrets/ChallengeAPiControllerTest.java b/src/test/java/org/owasp/wrongsecrets/ChallengeAPiControllerTest.java index 821f8443d..86ec1c8dc 100644 --- a/src/test/java/org/owasp/wrongsecrets/ChallengeAPiControllerTest.java +++ b/src/test/java/org/owasp/wrongsecrets/ChallengeAPiControllerTest.java @@ -39,5 +39,5 @@ void shouldGetListOfChallenges() { } /* -"manageUrl" : "url", "memo" : "memo", "channel" : "channel", "time" : "time", "additionalData" : { "srcIp" : "soruce", "useragent" : "agent", "referer" : "referer", "location" : "locatoin"}} +"manageUrl" : "url", "memo" : "memo", "channel" : "channel", "time" : "time", "additionalData" : { "srcIp" : "source", "useragent" : "agent", "referer" : "referer", "location" : "location"}} */ diff --git a/src/test/java/org/owasp/wrongsecrets/ChallengesControllerTest.java b/src/test/java/org/owasp/wrongsecrets/ChallengesControllerTest.java index 24100f311..3407665a2 100644 --- a/src/test/java/org/owasp/wrongsecrets/ChallengesControllerTest.java +++ b/src/test/java/org/owasp/wrongsecrets/ChallengesControllerTest.java @@ -62,6 +62,16 @@ void shouldReturnSpoiler() throws Exception { .andExpect(model().attribute("spoiler", new Spoiler("solution"))); } + @Test + void shouldReturnNotFound() throws Exception { + // when(challenge.solved(anyString())).thenReturn(false); + // when(challenge.supportedRuntimeEnvironments()).thenReturn(List.of(Environment.DOCKER)); + this.mvc.perform(get("/challenge/-1")) + .andExpect(status().isNotFound()); + this.mvc.perform(get("/challenge/99999999")) + .andExpect(status().isNotFound()); + } + @Test void shouldReturnIncorrectAnswerMessageWhenChallengeIsNotSolved() throws Exception { when(challenge.solved(anyString())).thenReturn(false); diff --git a/src/test/java/org/owasp/wrongsecrets/canaries/CanaryCallbackTest.java b/src/test/java/org/owasp/wrongsecrets/canaries/CanaryCallbackTest.java index 054e732c7..4be9120ed 100644 --- a/src/test/java/org/owasp/wrongsecrets/canaries/CanaryCallbackTest.java +++ b/src/test/java/org/owasp/wrongsecrets/canaries/CanaryCallbackTest.java @@ -22,7 +22,7 @@ class CanaryCallbackTest { @Test void shouldAcceptPostOfMessage() { var restTemplate = builder.build(); - var additonalCanaryData = new AdditionalCanaryData("soruce", "agent", "referer", "locatoin"); + var additonalCanaryData = new AdditionalCanaryData("source", "agent", "referer", "location"); CanaryToken token = new CanaryToken("url", "memo", "channel", "time", additonalCanaryData); var callbackAdress = "http://localhost:" + port + "/canaries/tokencallback"; @@ -37,5 +37,5 @@ void shouldAcceptPostOfMessage() { } /* -"manageUrl" : "url", "memo" : "memo", "channel" : "channel", "time" : "time", "additionalData" : { "srcIp" : "soruce", "useragent" : "agent", "referer" : "referer", "location" : "locatoin"}} +"manageUrl" : "url", "memo" : "memo", "channel" : "channel", "time" : "time", "additionalData" : { "srcIp" : "source", "useragent" : "agent", "referer" : "referer", "location" : "location"}} */ From f87f62590e9ba822adb37da24c239ddbea70f030 Mon Sep 17 00:00:00 2001 From: Ben de Haan <53901866+bendehaan@users.noreply.github.com> Date: Tue, 14 Mar 2023 17:57:46 +0100 Subject: [PATCH 10/10] fix: change number of challenges --- README.md | 2 +- .../java/org/owasp/wrongsecrets/WrongSecretsApplication.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2d7802afa..43b8702a1 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Welcome to the OWASP WrongSecrets p0wnable app. With this app, we have packed va secrets. These can help you to realize whether your secret management is ok. The challenge is to find all the different secrets by means of various tools and techniques. -Can you solve all the 27 challenges? +Can you solve all the 28 challenges? ![screenshotOfChallenge1](/images/screenshot.png) diff --git a/src/main/java/org/owasp/wrongsecrets/WrongSecretsApplication.java b/src/main/java/org/owasp/wrongsecrets/WrongSecretsApplication.java index 426af9a3b..ab55c222f 100644 --- a/src/main/java/org/owasp/wrongsecrets/WrongSecretsApplication.java +++ b/src/main/java/org/owasp/wrongsecrets/WrongSecretsApplication.java @@ -19,7 +19,7 @@ public static void main(String[] args) { @Bean @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) public InMemoryScoreCard scoreCard() { - return new InMemoryScoreCard(27); + return new InMemoryScoreCard(28); }