diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4834f4562c..c11aafb4e6 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -436,8 +436,6 @@ jobs: - trivy-sbom - whatweb - wpscan - - zap - - zap-advanced - zap-automation-framework steps: - name: Checkout diff --git a/.github/workflows/release-build.yaml b/.github/workflows/release-build.yaml index fd6f88a72f..123a866f45 100644 --- a/.github/workflows/release-build.yaml +++ b/.github/workflows/release-build.yaml @@ -341,7 +341,6 @@ jobs: - trivy-sbom - whatweb - wpscan - - zap - zap-automation-framework steps: @@ -491,7 +490,6 @@ jobs: - git-repo-scanner - screenshooter - test-scan - - zap-advanced steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/scb-bot.yaml b/.github/workflows/scb-bot.yaml index c1d9113be2..7b8d97a580 100644 --- a/.github/workflows/scb-bot.yaml +++ b/.github/workflows/scb-bot.yaml @@ -41,8 +41,6 @@ jobs: - trivy-sbom - whatweb - wpscan - - zap - - zap-advanced - zap-automation-framework # missing scanners are : nmap, nikto steps: diff --git a/documentation/docs/11-telemetry.md b/documentation/docs/11-telemetry.md index 7f6c36927f..e259a5f79f 100644 --- a/documentation/docs/11-telemetry.md +++ b/documentation/docs/11-telemetry.md @@ -14,7 +14,7 @@ The secureCodeBox Operator collects and submits anonymized data to give the deve The total number of datapoints collected is extremely small, and they are individually evaluated to ensure that the submitted data is as anonymous as possible. - Installed version of the secureCodeBox Operator (e.g. `v2.0.0`) -- List of installed ScanTypes across all kubernetes Namespaces: (e.g. `['nmap', 'zap-baseline']`). Unofficial ScanTypes are reported as `other`, to avoid submission of confidential data. +- List of installed ScanTypes across all kubernetes Namespaces: (e.g. `['nmap', 'zap-automation-framework']`). Unofficial ScanTypes are reported as `other`, to avoid submission of confidential data. ## Collection Interval diff --git a/documentation/docs/api/crds/cascading-rule.md b/documentation/docs/api/crds/cascading-rule.md index 7a8e3b9782..a91d0d6e46 100644 --- a/documentation/docs/api/crds/cascading-rule.md +++ b/documentation/docs/api/crds/cascading-rule.md @@ -52,29 +52,20 @@ This helper object has the following attributes: apiVersion: "cascading.securecodebox.io/v1" kind: CascadingRule metadata: - name: "zap-http" + name: "nmap-hostscan" labels: securecodebox.io/invasive: non-invasive - securecodebox.io/intensive: medium + securecodebox.io/intensive: light spec: matches: anyOf: - - category: "Open Port" - attributes: - service: http - state: open - - category: "Open Port" - attributes: - service: https - state: open - scanLabels: - mynewlabel: {{ metadata.name }} - scanAnnotations: - defectdojo.securecodebox.io/product-name: "{{$.hostOrIP}}" - defectdojo.securecodebox.io/product-type-name: "{{metadata.labels.organization}}" - defectdojo.securecodebox.io/engagement-name: "{{metadata.name}}" - mynewannotation: "{{category}}" + - category: "Subdomain" + osi_layer: "NETWORK" scanSpec: - scanType: "zap-baseline" - parameters: ["-t", "{{attributes.service}}://{{$.hostOrIP}}"] + scanType: "nmap" + parameters: + # Treat all hosts as online -- skip host discovery + - "-Pn" + # Target Port of the finding + - "{{location}}" ``` diff --git a/documentation/docs/api/crds/parse-definition.md b/documentation/docs/api/crds/parse-definition.md index 1c77e3639e..94093f3a9a 100644 --- a/documentation/docs/api/crds/parse-definition.md +++ b/documentation/docs/api/crds/parse-definition.md @@ -85,21 +85,22 @@ resources: apiVersion: execution.securecodebox.io/v1 kind: ParseDefinition metadata: - name: zap-json + name: zap-xml spec: - image: docker.io/securecodebox/parser-zap + affinity: + foo: bar + env: [] + image: docker.io/securecodebox/parser-zap-automation-framework:0.0.0 + imagePullPolicy: IfNotPresent imagePullSecrets: - - name: dockerhub-token - ttlSecondsAfterFinished: 60 - scopeLimiterAliases: - domain: "{{attributes.host}}" + - name: foo resources: - requests: - cpu: 42mi - memory: 256Mi - limits: - cpu: 4 - memory: 4Gi + foo: bar + scopeLimiterAliases: + foo: bar + tolerations: + - foo: bar + ttlSecondsAfterFinished: null ``` The Parse definition is different when integrating a new scanner. We use specific conventions when adding new ParseDefinitions to the secureCodeBox repository. diff --git a/documentation/docs/architecture/06_runtime_view.md b/documentation/docs/architecture/06_runtime_view.md index ee80e8c0fa..089a6edcc6 100644 --- a/documentation/docs/architecture/06_runtime_view.md +++ b/documentation/docs/architecture/06_runtime_view.md @@ -15,7 +15,7 @@ Since sequence diagrams are hard to maintain and tend to be very complicated we ## Runtime Scenario 1: Basic Scan with kubectl {#__runtime_scenario_1} -This scenario describes a simple [ZAP](/docs/scanners/zap) scan which is initialized by a _Developer_ actor and which persists the _findings_ in [Elastic][elastic] and [DefectDojo][defectdojo]. +This scenario describes a simple [ZAP](/docs/scanners/zap-automation-framework) scan which is initialized by a _Developer_ actor and which persists the _findings_ in [Elastic][elastic] and [DefectDojo][defectdojo]. ![Runtime view diagram](/img/docs/architecture/runtime-basic-scan-via-kubectl.png) diff --git a/documentation/docs/auto-discovery/installation.md b/documentation/docs/auto-discovery/installation.md index 10109835cc..d2d0497c7e 100644 --- a/documentation/docs/auto-discovery/installation.md +++ b/documentation/docs/auto-discovery/installation.md @@ -65,6 +65,6 @@ You should now see a ZAP Automation Framework [ScheduledScan](/docs/api/crds/sch ```bash $ kubectl get scheduledscans.execution.securecodebox.io -NAME TYPE INTERVAL FINDINGS -juice-shop-service-port-3000 zap-automation-framework 168h0m0s 5 +NAME TYPE INTERVAL FINDINGS +juice-shop-service-port-3000 zap-automation-framework 168h0m0s 5 ``` \ No newline at end of file diff --git a/documentation/docs/contributing/integrating-a-scanner/makefile.md b/documentation/docs/contributing/integrating-a-scanner/makefile.md index b7e215b279..940cf2edd3 100644 --- a/documentation/docs/contributing/integrating-a-scanner/makefile.md +++ b/documentation/docs/contributing/integrating-a-scanner/makefile.md @@ -77,45 +77,3 @@ deploy-test-deps: ``` Furthermore, it overrides the deploy-test-deps target such that juice-shop is installed in the correct namespace (nmap-tests). - -### Reusing components from other scanners - -```makefile -#!/usr/bin/make -f - -include_guard = set -scanner = zap-advanced -custom_scanner = set - -include ../../scanners.mk - -unit-tests: - @$(MAKE) -s unit-test-py - -unit-tests-parser: - $(MAKE) -s -f ../../scanners.mk unit-tests-parser include_guard=set scanner=zap - -install-deps: - cd ../zap/ && $(MAKE) -s install-deps - -docker-build-parser: - cd ../zap/ && $(MAKE) -s docker-build-parser - -docker-export-parser: - cd ../zap/ && $(MAKE) -s docker-export-parser - -kind-import-parser: - cd ../zap/ && $(MAKE) -s kind-import-parser - -deploy-with-scanner: - @echo ".: 💾 Deploying custom '$(scanner)' scanner HelmChart with the docker tag '$(IMG_TAG)' into kind namespace 'integration-tests'." - helm -n integration-tests upgrade --install $(scanner) ./ --wait \ - --set="parser.image.repository=docker.io/$(IMG_NS)/$(parser-prefix)-zap" \ - --set="parser.image.tag=$(IMG_TAG)" \ - --set="scanner.image.repository=docker.io/$(IMG_NS)/$(scanner-prefix)-$(scanner)" \ - --set="scanner.image.tag=$(IMG_TAG)" - -deploy-test-deps: deploy-test-dep-nginx deploy-test-dep-bodgeit deploy-test-dep-juiceshop deploy-test-dep-petstore -``` - -Zap-advanced reuses the parser container from zap scanner, thus in the makefile, we overwrite the targets for parser build so that they reference the makefile from zap. diff --git a/documentation/docs/getting-started/installation.md b/documentation/docs/getting-started/installation.md index 423a84dcc8..09745da488 100644 --- a/documentation/docs/getting-started/installation.md +++ b/documentation/docs/getting-started/installation.md @@ -129,7 +129,7 @@ helm upgrade --install ssh-audit oci://ghcr.io/securecodebox/helm/ssh-audit helm upgrade --install sslyze oci://ghcr.io/securecodebox/helm/sslyze helm upgrade --install trivy oci://ghcr.io/securecodebox/helm/trivy helm upgrade --install wpscan oci://ghcr.io/securecodebox/helm/wpscan -helm upgrade --install zap oci://ghcr.io/securecodebox/helm/zap +helm upgrade --install zap-automation-framework oci://ghcr.io/securecodebox/helm/zap-automation-framework ``` ## Install some demo targets diff --git a/documentation/docs/getting-started/upgrading.md b/documentation/docs/getting-started/upgrading.md index 11bf33af89..5f77c14536 100644 --- a/documentation/docs/getting-started/upgrading.md +++ b/documentation/docs/getting-started/upgrading.md @@ -16,7 +16,8 @@ sidebar_position: 3 * `typo3scan` was removed as the scanner itself [isn't maintaned anymore](https://github.com/whoot/Typo3Scan?tab=readme-ov-file#unsupported). Most security aspects of typo3 are now hard to verify from the outside as it requires authentication (which is really good). Some typo3 security aspects (e.g. a incomplete installation) can be verified by [nuclei](https://www.securecodebox.io/docs/scanners/nuclei). * `kubeaudit` was removed as the scanner itself [isn't maintaned anymore](https://github.com/Shopify/kubeaudit?tab=readme-ov-file#-deprecation-notice-). As a replacement you can use the `trivy` with it's `k8s` scanning mode, see [trivy ScanType k8s example](https://www.securecodebox.io/docs/scanners/trivy#k8s). -* `doggo` was removed. Doggo was added primarily as an experimentation to be used to deduplicate duplicate scan target from cascading rules based on DNS entries. That approach hasn't worked out unfortunately. The doggo integration has been non-functional for a while (see: https://github.com/secureCodeBox/secureCodeBox/issues/2853). As a alternative, nuclei already includes some DNS record based checks, if checks for specific records are required custom nuclei rules could be used to fulfil those requirements. +* `doggo` was removed. Doggo was added primarily as an experimentation to be used to deduplicate duplicate scan target from cascading rules based on DNS entries. That approach hasn't worked out unfortunately. The doggo integration has been non-functional for a while (see: https://github.com/secureCodeBox/secureCodeBox/issues/2853). As an alternative, nuclei already includes some DNS record based checks, if checks for specific records are required custom nuclei rules could be used to fulfil those requirements. +* `zap-baseline-scan` and `zap-advanced` in favor of the `zap-automation-framework`. The `zap-automation-framework` ScanTpye includes all functionalities of the removed ScanTypes and can be customized easily. The default ScanType for the AutoDiscovery has been changed to the `zap-automation-framework` as well. For migrating to the `zap-automation-framework` please refer to [migration to zap-automation framework](/docs/scanners/zap-automation-framework#migration-to-zap-automation-framework) guide. ➡️ [Reference: #2670](https://github.com/secureCodeBox/secureCodeBox/issues/2670) diff --git a/documentation/docs/how-tos/scanning-web-applications.md b/documentation/docs/how-tos/scanning-web-applications.md index c775b3680a..c681934e4a 100644 --- a/documentation/docs/how-tos/scanning-web-applications.md +++ b/documentation/docs/how-tos/scanning-web-applications.md @@ -16,10 +16,10 @@ In this step-by-step tutorial, we will go through all the required stages to set For the sake of the tutorial, we assume that you have your Kubernetes cluster already up and running and that we can work in your default namespace. If not, check out the [installation](/docs/getting-started/installation/) for more information. -We will start by installing the ZAP-Advanced scanner: +We will start by installing the ZAP Automation Framework scanner: ```bash -helm upgrade --install zap-advanced oci://ghcr.io/securecodebox/helm/zap-advanced +helm upgrade --install zap-automation-framework oci://ghcr.io/securecodebox/helm/zap-automation-framework ``` And the juice-shop demo-target. @@ -28,49 +28,54 @@ And the juice-shop demo-target. helm upgrade --install juice-shop oci://ghcr.io/securecodebox/helm/juice-shop ``` -## Creating the ZAP-Advanced scan +## Creating the ZAP Automation Framework scan -We can first start with a basic `zap-advanced` scan. We use here our CRD (Custom Resource definition) [Scan](/docs/api/crds/scan) and a [ConfigMap](https://kubernetes.io/docs/concepts/configuration/configmap/) to configure our scan. +We can first start with a basic `zap-automation-framework` scan. We use here our CRD (Custom Resource definition) [Scan](/docs/api/crds/scan) and a [ConfigMap](https://kubernetes.io/docs/concepts/configuration/configmap/) to configure our scan. ```yaml title="scan.yaml" apiVersion: v1 kind: ConfigMap metadata: - name: zap-advanced-scan-config + name: baseline-config data: - 2-zap-advanced-scan.yaml: |- - - # ZAP Contexts Configuration - contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: scb-juiceshop-context - # The top level url, mandatory, everything under this will be included - url: http://juice-shop.default.svc:3000/ + automation.yaml: |- + + env: # The environment, mandatory + contexts: # List of 1 or more contexts, mandatory + - name: baseline-config # Name to be used to refer to this context in other jobs, mandatory + # A mandatory list of top level urls, everything under each url will be included + urls: ["http://juice-shop.demo-targets.svc:3000/"] + jobs: + - type: report # Report generation + parameters: + template: traditional-xml # String: The template id, default : modern + reportDir: /home/securecodebox/ # String: The directory into which the report will be written + reportFile: zap-results # String: The report file name pattern, default: {{yyyy-MM-dd}}-ZAP-Report-[[site]] + --- apiVersion: "execution.securecodebox.io/v1" kind: Scan metadata: - name: "zap-authenticated-full-scan-juiceshop-basic" + name: "zap-automation-framework-juice-shop" labels: organization: "OWASP" spec: - scanType: "zap-advanced-scan" + scanType: "zap-automation-framework" parameters: - # target URL including the protocol - - "-t" - - "http://juice-shop.default.svc:3000/" + - "-autorun" + - "/home/securecodebox/scb-automation/automation.yaml" volumeMounts: - - name: zap-advanced-scan-config - mountPath: /home/securecodebox/configs/2-zap-advanced-scan.yaml - subPath: 2-zap-advanced-scan.yaml - readOnly: true + - name: baseline-config + mountPath: /home/securecodebox/scb-automation/automation.yaml + subPath: automation.yaml volumes: - - name: zap-advanced-scan-config + - name: baseline-config configMap: - name: zap-advanced-scan-config + name: baseline-config ``` -We use `volumeMounts` and `volumes` to attach the configMap to our scan in `scan.yaml`. We also set up a context for our `zap-advanced` scan. This is where we can input ZAP related parameters. +We use `volumeMounts` and `volumes` to attach the configMap to our scan in `scan.yaml`. We also set up a context for our `zap-automation-framework` scan. This is where we can input ZAP related parameters. +The field `jobs.type: report` describes the output format and directory of the result file. This is a mendadory field. We can do a test run via: @@ -86,180 +91,222 @@ Our ConfigMap will then look like this. apiVersion: v1 kind: ConfigMap metadata: - name: zap-advanced-scan-config + name: baseline-config data: - 2-zap-advanced-scan.yaml: |- - - # ZAP Contexts Configuration - contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: scb-juiceshop-context - # The top level url, mandatory, everything under this will be included - url: http://juice-shop.default.svc:3000/ - # An optional list of regexes to include - includePaths: - - "http://juice-shop.default.svc:3000.*" - # An optional list of regexes to exclude - excludePaths: - - ".*socket\\.io.*" - - ".*\\.png" - - ".*\\.jpeg" - - ".*\\.jpg" - - ".*\\.woff" - - ".*\\.woff2" - - ".*\\.ttf" - - ".*\\.ico" + automation.yaml: |- + + env: # The environment, mandatory + contexts : # List of 1 or more contexts, mandatory + - name: baseline-config # Name to be used to refer to this context in other jobs, mandatory + # A mandatory list of top level urls, everything under each url will be included + urls: ["http://juice-shop.demo-targets.svc:3000/"] + + # An optional list of regexes to include + includePaths: + - "http://juice-shop.default.svc:3000.*" + # An optional list of regexes to exclude + excludePaths: + - ".*socket\\.io.*" + - ".*\\.png" + - ".*\\.jpeg" + - ".*\\.jpg" + - ".*\\.woff" + - ".*\\.woff2" + - ".*\\.ttf" + - ".*\\.ico" + jobs: + - type: report # Report generation + parameters: + template: traditional-xml # String: The template id, default : modern + reportDir: /home/securecodebox/ # String: The directory into which the report will be written + reportFile: zap-results # String: The report file name pattern, default: {{yyyy-MM-dd}}-ZAP-Report-[[site]] ``` -ZAP uses a [Spider-Tool](https://www.zaproxy.org/docs/desktop/start/features/spider/) to automatically discover new resources (URLs) on a particular site. We can configure its mode of operation through the parameter `spiders`. A possible configuration can look like this: +ZAP uses a [Spider-Tool](https://www.zaproxy.org/docs/desktop/start/features/spider/) to automatically discover new resources (URLs) on a particular site. We can configure its mode of operation through `jobs.type`. Here we use the Ajax scanner as it is more suitable for modern web-applications. For a faster run you can use the default spider with `type: spider`. + +A possible configuration can look like this: ```yaml apiVersion: v1 kind: ConfigMap metadata: - name: zap-advanced-scan-config + name: baseline-config data: - 2-zap-advanced-scan.yaml: |- - - # ZAP Contexts Configuration - contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: scb-juiceshop-context - # The top level url, mandatory, everything under this will be included - url: http://juice-shop.default.svc:3000/ - # An optional list of regexes to include - includePaths: - - "http://juice-shop.default.svc:3000.*" - # An optional list of regexes to exclude - excludePaths: - - ".*socket\\.io.*" - - ".*\\.png" - - ".*\\.jpeg" - - ".*\\.jpg" - - ".*\\.woff" - - ".*\\.woff2" - - ".*\\.ttf" - - ".*\\.ico" + automation.yaml: |- + + env: # The environment, mandatory + contexts : # List of 1 or more contexts, mandatory + - name: baseline-config # Name to be used to refer to this context in other jobs, mandatory + # A mandatory list of top level urls, everything under each url will be included + urls: ["http://juice-shop.demo-targets.svc:3000/"] + + # An optional list of regexes to include + includePaths: + - "http://juice-shop.demo-targets.svc:3000.*" + # An optional list of regexes to exclude + excludePaths: + - ".*socket\\.io.*" + - ".*\\.png" + - ".*\\.jpeg" + - ".*\\.jpg" + - ".*\\.woff" + - ".*\\.woff2" + - ".*\\.ttf" + - ".*\\.ico" # ZAP Spiders Configuration - spiders: - - name: scb-juiceshop-spider - # String: Name of the context to spider, default: first context - context: scb-juiceshop-context - # String: Name of the user to authenticate with and used to spider - user: juiceshop-user-1 - # String: Url to start spidering from, default: first context URL - url: http://juice-shop.default.svc:3000/ - # zapConfiguration.spiders[0].ajax -- Bool: Whether to use the ZAP ajax spider, default: false - ajax: true - # Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 5 - # Int: The maximum tree depth to explore, default 5 - maxDepth: 10 + jobs: + - type: spiderAjax # We use a modern spider since the juice-shop is a modern web-application + parameters: + # String: Name of the context to spider, default: first context + context: scb-juiceshop-context + # String: Name of the user to authenticate with and used to spider + user: "admin@juice-sh.op" + # String: Url to start spidering from, default: first context URL + url: http://juice-shop.default.svc:3000/ + browserId: firefox-headless + # Elemets to exclude from the spider + excludedElements: + - description: Logout + element: span + text: Logout + # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited + maxDuration: 5 + + - type: report # Report generation + parameters: + template: traditional-xml # String: The template id, default : modern + reportDir: /home/securecodebox/ # String: The directory into which the report will be written + reportFile: zap-results ``` ZAP also has the option for an [Active Scan](https://www.zaproxy.org/docs/desktop/start/features/ascan/). -Active scanning attempts to find potential vulnerabilities by using known attacks against the selected targets. Its rules can be modified in the `scanners` parameter. An example for that would be: +Active scanning attempts to find potential vulnerabilities by using known attacks against the selected targets. Its rules can be modified in the `jobs.types: activeScan` parameter. An example for that would be: ```yaml # ZAP ActiveScans Configuration -scanners: - - name: scb-juiceshop-scan - # String: Name of the context to attack, default: first context - context: scb-juiceshop-context - # String: Name of the user to authenticate with and used to spider - user: juiceshop-user-1 - # String: Url to start scaning from, default: first context URL - url: http://juice-shop.default.svc:3000/ - # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 1 - # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 10 - # Int: The max number of threads per host, default: 2 - threadPerHost: 5 - # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false +jobs: + # The active scanner - this actively attacks the target so should only be used with permission + type: activeScan + parameters: + name: scb-juiceshop-scan + # String: Name of the context to attack, default: first context + context: scb-juiceshop-context + # String: Name of the user to authenticate with and used to spider + user: "test@test.com" + # String: Url to start scaning from, default: first context URL + url: http://juice-shop.default.svc:3000/ + # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited + maxRuleDurationInMins: 1 + # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited + maxScanDurationInMins: 10 + # Int: The max number of threads per host, default: 2 + threadPerHost: 5 + # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 + delayInMs: 0 + # Bool: If set will add an extra query parameter to requests that do not have one, default: false + addQueryParam: false + # Bool: If set then automatically handle anti CSRF tokens, default: false + handleAntiCSRFTokens: false + # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false + injectPluginIdInHeader: false + # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false + scanHeadersAllRequests: false ``` -Some URLs may not be reachable without privileged user rights. In this case, it makes sense to provide authentications credentials. This is done through the `authentication`, `users` and `session` parameters in our ConfigMap context. In our case here, we use custom zap scripts to authenticate into juice-shop. The scripts used can be found [here](https://github.com/secureCodeBox/secureCodeBox/tree/main/scanners/zap-advanced/scanner/scripts/). -:::note -It can be required to configure your own scripts to fit your scan target: more information on how these scripts integrate into ZAP can be found [here](https://www.zaproxy.org/docs/desktop/start/features/scripts/). -::: +Some URLs may not be reachable without privileged user rights. In this case, it makes sense to provide authentications credentials. This is done through the `authentication`, `users` and `session` parameters in our ConfigMap context. For the Juice Shop there is an example for authentication on the [ZAP website](https://www.zaproxy.org/docs/testapps/juiceshop/) Our `contexts` parameter in our scan would then look something like this: ```yaml apiVersion: v1 kind: ConfigMap metadata: - name: zap-advanced-scan-config + name: baseline-config data: - 2-zap-advanced-scan.yaml: |- - - # ZAP Contexts Configuration - contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: scb-juiceshop-context - # The top level url, mandatory, everything under this will be included - url: http://juice-shop.default.svc:3000/ - # An optional list of regexes to include - includePaths: - - "http://juice-shop.default.svc:3000.*" - # An optional list of regexes to exclude - excludePaths: - - ".*socket\\.io.*" - - ".*\\.png" - - ".*\\.jpeg" - - ".*\\.jpg" - - ".*\\.woff" - - ".*\\.woff2" - - ".*\\.ttf" - - ".*\\.ico" - # Auth Credentials for the scanner to access the application - # Can be either basicAuth or a oidc token. - # If both are set, the oidc token takes precedent - authentication: - # Currently supports "basic-auth", "form-based", "json-based", "script-based" - type: "json-based" - # json-based requires no further configuration - # zapConfiguration.contexts[0].authentication.json-based -- Configure `type: json-based` authentication (more: https://www.zaproxy.org/docs/api/#json-based-authentication). - json-based: - loginUrl: "http://juice-shop.default.svc:3000/rest/user/login" - # must be escaped already to prevent yaml parser colidations '{"user":{"id":1,"email":"test@test.com"}}'' - loginRequestData: '{"email":"admin@juice-sh.op","password":"admin123"}' - # Indicates if the current Zap User Session is based on a valid authentication (loggedIn) or not (loggedOut) - verification: - # isLoggedInIndicator: "\Q\E" - isLoggedOutIndicator: '\Q{"user":{}}\E' - users: - - name: juiceshop-user-1 - username: admin@juice-sh.op - password: admin123 - forced: true - session: - # Currently supports "scriptBasedSessionManagement", "cookieBasedSessionManagement", "httpAuthSessionManagement" - type: "scriptBasedSessionManagement" - # scriptBasedSessionManagement configuration details - scriptBasedSessionManagement: - name: "juiceshop-session-management.js" - # -- Enables the script if true, otherwise false - enabled: true - # Script engine values: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - engine: "Oracle Nashorn" - # Must be a full path to the script file inside the ZAP container (corresponding to the configMap FileMount) - filePath: "/home/zap/.ZAP_D/scripts/scripts/session/juiceshop-session-management.js" - # A short description for the script. - description: "This is a JuiceShop specific SessionManagement Script used to handle JWT." + automation.yaml: |- + + env: # The environment, mandatory + contexts: # List of 1 or more contexts, mandatory + - name: scb-juiceshop-context # Name to be used to refer to this context in other jobs, mandatory + # A mandatory list of top level urls, everything under each url will be included + urls: ["http://juice-shop.demo-targets.svc:3000/"] + # An optional list of regexes to include + includePaths: + - "http://juice-shop.default.svc:3000.*" + # An optional list of regexes to exclude + excludePaths: + - ".*socket\\.io.*" + - ".*\\.png" + - ".*\\.jpeg" + - ".*\\.jpg" + - ".*\\.woff" + - ".*\\.woff2" + - ".*\\.ttf" + - ".*\\.ico" + # Auth Credentials for the scanner to access the application + authentication: + method: "browser" + parameters: + loginPageUrl: "http://juice-shop.demo-targets.svc:3000/#/login" + browserId: "firefox-headless" + loginPageWait: 5 + verification: + method: "poll" + loggedInRegex: "\\Qadmin@juice-sh.op\\E" + loggedOutRegex: "" + pollFrequency: 60 + pollUnits: "requests" + pollUrl: "http://juice-shop.demo-targets.svc:3000/rest/user/whoami" + pollPostData: "" + sessionManagement: + method: headers + parameters: + Authorization: "Bearer {%json:authentication.token%}" + cookie: "token={%json:authentication.token%}" + users: + - name: "admin@juice-sh.op" + credentials: + password: "admin123" + username: "admin@juice-sh.op" + # ZAP Spiders Configuration + jobs: + - type: spiderAjax # We use a modern spider since the juice-shop is a modern web-application + parameters: + # String: Name of the context to spider, default: first context + context: scb-juiceshop-context + # String: Name of the user to authenticate with and used to spider + user: "admin@juice-sh.op" + # String: Url to start spidering from, default: first context URL + url: http://juice-shop.default.svc:3000/ + browserId: firefox-headless + # Elemets to exclude from the spider + excludedElements: + - description: Logout + element: span + text: Logout + # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited + maxDuration: 5 + + # ZAP ActiveScans Configuration + - type: activeScan # The active scanner - this actively attacks the target so should only be used with permission + parameters: + # String: Name of the context to attack, default: first context + context: scb-juiceshop-context + # String: Name of the user to authenticate with and used to spider + user: "admin@juice-sh.op" + # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited + maxRuleDurationInMins: 3 # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited + maxScanDurationInMins: 10 # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited + addQueryParam: false # Bool: If set will add an extra query parameter to requests that do not have one, default: false + delayInMs: 0 # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 + handleAntiCSRFTokens: false # Bool: If set then automatically handle anti CSRF tokens, default: false + injectPluginIdInHeader: false # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false + scanHeadersAllRequests: false # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false + threadPerHost: 2 # Int: The max number of threads per host, default: 2 + - type: report # Report generation + parameters: + template: traditional-xml # String: The template id, default : modern + reportDir: /home/securecodebox/ # String: The directory into which the report will be written + reportFile: zap-results ``` :::note @@ -272,133 +319,113 @@ Our complete ZAP Scan file is then the following : apiVersion: v1 kind: ConfigMap metadata: - name: zap-advanced-scan-config + name: baseline-config data: - 2-zap-advanced-scan.yaml: |- - - # ZAP Contexts Configuration - contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: scb-juiceshop-context - # The top level url, mandatory, everything under this will be included - url: http://juice-shop.default.svc:3000/ - # An optional list of regexes to include - includePaths: - - "http://juice-shop.default.svc:3000.*" - # An optional list of regexes to exclude - excludePaths: - - ".*socket\\.io.*" - - ".*\\.png" - - ".*\\.jpeg" - - ".*\\.jpg" - - ".*\\.woff" - - ".*\\.woff2" - - ".*\\.ttf" - - ".*\\.ico" - # Auth Credentials for the scanner to access the application - # Can be either basicAuth or a oidc token. - # If both are set, the oidc token takes precedent - authentication: - # Currently supports "basic-auth", "form-based", "json-based", "script-based" - type: "json-based" - # json-based requires no further configuration - # zapConfiguration.contexts[0].authentication.json-based -- Configure `type: json-based` authentication (more: https://www.zaproxy.org/docs/api/#json-based-authentication). - json-based: - loginUrl: "http://juice-shop.default.svc:3000/rest/user/login" - # must be escaped already to prevent yaml parser colidations '{"user":{"id":1,"email":"test@test.com"}}'' - loginRequestData: '{"email":"admin@juice-sh.op","password":"admin123"}' - # Indicates if the current Zap User Session is based on a valid authentication (loggedIn) or not (loggedOut) - verification: - # isLoggedInIndicator: "\Q\E" - isLoggedOutIndicator: '\Q{"user":{}}\E' - users: - - name: juiceshop-user-1 - username: admin@juice-sh.op - password: admin123 - forced: true - session: - # Currently supports "scriptBasedSessionManagement", "cookieBasedSessionManagement", "httpAuthSessionManagement" - type: "scriptBasedSessionManagement" - # scriptBasedSessionManagement configuration details - scriptBasedSessionManagement: - name: "juiceshop-session-management.js" - # -- Enables the script if true, otherwise false - enabled: true - # Script engine values: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - engine: "Oracle Nashorn" - # Must be a full path to the script file inside the ZAP container (corresponding to the configMap FileMount) - filePath: "/home/zap/.ZAP_D/scripts/scripts/session/juiceshop-session-management.js" - # A short description for the script. - description: "This is a JuiceShop specific SessionManagement Script used to handle JWT." - + automation.yaml: |- + + env: # The environment, mandatory + contexts : # List of 1 or more contexts, mandatory + - name: scb-juiceshop-context # Name to be used to refer to this context in other jobs, mandatory + # A mandatory list of top level urls, everything under each url will be included + urls: ["http://juice-shop.demo-targets.svc:3000/"] + # An optional list of regexes to include + includePaths: + - "http://juice-shop.default.svc:3000.*" + # An optional list of regexes to exclude + excludePaths: + - ".*socket\\.io.*" + - ".*\\.png" + - ".*\\.jpeg" + - ".*\\.jpg" + - ".*\\.woff" + - ".*\\.woff2" + - ".*\\.ttf" + - ".*\\.ico" + # Auth Credentials for the scanner to access the application + authentication: + method: "browser" + parameters: + loginPageUrl: "http://juice-shop.demo-targets.svc:3000/#/login" + browserId: "firefox-headless" + loginPageWait: 5 + verification: + method: "poll" + loggedInRegex: "\\Qadmin@juice-sh.op\\E" + loggedOutRegex: "" + pollFrequency: 60 + pollUnits: "requests" + pollUrl: "http://juice-shop.demo-targets.svc:3000/rest/user/whoami" + pollPostData: "" + sessionManagement: + method: headers + parameters: + Authorization: "Bearer {%json:authentication.token%}" + cookie: "token={%json:authentication.token%}" + users: + - name: "admin@juice-sh.op" + credentials: + password: "admin123" + username: "admin@juice-sh.op" # ZAP Spiders Configuration - spiders: - - name: scb-juiceshop-spider - # String: Name of the context to spider, default: first context - context: scb-juiceshop-context - # String: Name of the user to authenticate with and used to spider - user: juiceshop-user-1 - # String: Url to start spidering from, default: first context URL - url: http://juice-shop.default.svc:3000/ - # zapConfiguration.spiders[0].ajax -- Bool: Whether to use the ZAP ajax spider, default: false - ajax: true - # Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 5 - # Int: The maximum tree depth to explore, default 5 - maxDepth: 10 - - # ZAP ActiveScans Configuration - scanners: - - name: scb-juiceshop-scan - # String: Name of the context to attack, default: first context - context: scb-juiceshop-context - # String: Name of the user to authenticate with and used to spider - user: juiceshop-user-1 - # String: Url to start scaning from, default: first context URL - url: http://juice-shop.default.svc:3000/ - # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 1 - # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 10 - # Int: The max number of threads per host, default: 2 - threadPerHost: 5 - # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false - + jobs: + - type: spiderAjax # We use a modern spider since the juice-shop is a modern web-application + parameters: + # String: Name of the context to spider, default: first context + context: scb-juiceshop-context + # String: Name of the user to authenticate with and used to spider + user: "admin@juice-sh.op" + # String: Url to start spidering from, default: first context URL + url: http://juice-shop.default.svc:3000/ + browserId: firefox-headless + # Elemets to exclude from the spider + excludedElements: + - description: Logout + element: span + text: Logout + # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited + maxDuration: 5 + + # ZAP ActiveScans Configuration + - type: activeScan # The active scanner - this actively attacks the target so should only be used with permission + parameters: + # String: Name of the context to attack, default: first context + context: scb-juiceshop-context + # String: Name of the user to authenticate with and used to spider + user: "admin@juice-sh.op" + # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited + maxRuleDurationInMins: 3 # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited + maxScanDurationInMins: 10 # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited + addQueryParam: false # Bool: If set will add an extra query parameter to requests that do not have one, default: false + delayInMs: 0 # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 + handleAntiCSRFTokens: false # Bool: If set then automatically handle anti CSRF tokens, default: false + injectPluginIdInHeader: false # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false + scanHeadersAllRequests: false # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false + threadPerHost: 2 # Int: The max number of threads per host, default: 2 + - type: report # Report generation + parameters: + template: traditional-xml # String: The template id, default : modern + reportDir: /home/securecodebox/ # String: The directory into which the report will be written + reportFile: zap-results --- apiVersion: "execution.securecodebox.io/v1" kind: Scan metadata: - name: "zap-authenticated-full-scan-juiceshop" + name: "zap-automation-framework-juice-shop" labels: organization: "OWASP" spec: - scanType: "zap-advanced-scan" + scanType: "zap-automation-framework" parameters: - # target URL including the protocol - - "-t" - - "http://juice-shop.default.svc:3000/" + - "-autorun" + - "/home/securecodebox/scb-automation/automation.yaml" volumeMounts: - - name: zap-advanced-scan-config - mountPath: /home/securecodebox/configs/2-zap-advanced-scan.yaml - subPath: 2-zap-advanced-scan.yaml - readOnly: true + - name: baseline-config + mountPath: /home/securecodebox/scb-automation/automation.yaml + subPath: automation.yaml volumes: - - name: zap-advanced-scan-config + - name: baseline-config configMap: - name: zap-advanced-scan-config + name: baseline-config ``` Let's delete our first test scan and run a new one via : @@ -414,8 +441,8 @@ We can check on our scan via: ```bash $ kubectl get scans -NAME TYPE STATE FINDINGS -zap-authenticated-full-scan-juiceshop zap-advanced-scan Done 14 +NAME TYPE STATE FINDINGS +zap-automation-framework-juice-shop zap-automation-framework Done 14 ``` If the scan's `STATE` is set to done, We can see our findings via the S3 bucket. If you've used the default installation method you can follow the [guide](/docs/getting-started/installation#accessing-the-included-minio-instance) to access the integrated Minio S3 Bucket to view the findings. diff --git a/documentation/src/integrations.js b/documentation/src/integrations.js index 79c2db96b2..02dbd6c67f 100644 --- a/documentation/src/integrations.js +++ b/documentation/src/integrations.js @@ -203,14 +203,7 @@ export const Scanners = [ path: "docs/scanners/wpscan", imageUrl: "img/integrationIcons/WPScan.svg", }, - { - title: "ZAP Advanced", - type: "WebApplication", - usecase: - "WebApp & OpenAPI Vulnerability Scanner extend with authentication features", - path: "docs/scanners/zap-advanced", - imageUrl: "img/integrationIcons/Default.svg", - }, + { title: "ZAP Automation Framework", type: "WebApplication", @@ -218,12 +211,5 @@ export const Scanners = [ path: "docs/scanners/zap-automation-framework", imageUrl: "img/integrationIcons/Default.svg", }, - { - title: "ZAP", - type: "WebApplication", - usecase: "WebApp & OpenAPI Vulnerability Scanner", - path: "docs/scanners/zap", - imageUrl: "img/integrationIcons/ZAP.svg", - }, ]; export default { Hooks, Scanners }; diff --git a/hooks/cascading-scans/.helm-docs.gotmpl b/hooks/cascading-scans/.helm-docs.gotmpl index 8df520bc9d..4218a58b00 100644 --- a/hooks/cascading-scans/.helm-docs.gotmpl +++ b/hooks/cascading-scans/.helm-docs.gotmpl @@ -60,15 +60,16 @@ There is a configuration option `cascadingRules.enabled` for each scanner to pre ```bash # Check your CascadingRules kubectl get CascadingRules -NAME STARTS INVASIVENESS INTENSIVENESS -https-tls-scan sslyze non-invasive light -imaps-tls-scan sslyze non-invasive light -nikto-http nikto non-invasive medium -nmap-smb nmap non-invasive light -pop3s-tls-scan sslyze non-invasive light -smtps-tls-scan sslyze non-invasive light -ssh-audit ssh-audit non-invasive light -zap-http zap-baseline-scan non-invasive medium +NAME STARTS INVASIVENESS INTENSIVENESS +https-tls-scan sslyze non-invasive light +imaps-tls-scan sslyze non-invasive light +nikto-http nikto non-invasive medium +nmap-smb nmap non-invasive light +pop3s-tls-scan sslyze non-invasive light +smtps-tls-scan sslyze non-invasive light +ssh-audit ssh-audit non-invasive light +zap-http zap-automation-framework non-invasive medium +zap-https zap-automation-framework non-invasive medium ``` ### Starting a cascading Scan @@ -104,7 +105,7 @@ imaps-tls-scan sslyze non-invasive light nmap-smb nmap non-invasive light pop3s-tls-scan sslyze non-invasive light smtps-tls-scan sslyze non-invasive light -ssh-audit ssh-audit non-invasive light +ssh-audit ssh-audit non-invasive light ``` The label selectors also allow the more powerful matchExpressions selectors: @@ -134,15 +135,16 @@ This selection can be replicated in kubectl using: ```bash kubectl get CascadingRules -l "securecodebox.io/intensive in (light,medium)" -NAME STARTS INVASIVENESS INTENSIVENESS -https-tls-scan sslyze non-invasive light -imaps-tls-scan sslyze non-invasive light -nikto-http nikto non-invasive medium -nmap-smb nmap non-invasive light -pop3s-tls-scan sslyze non-invasive light -smtps-tls-scan sslyze non-invasive light -ssh-audit ssh-audit non-invasive light -zap-http zap-baseline-scan non-invasive medium +NAME STARTS INVASIVENESS INTENSIVENESS +https-tls-scan sslyze non-invasive light +imaps-tls-scan sslyze non-invasive light +nikto-http nikto non-invasive medium +nmap-smb nmap non-invasive light +pop3s-tls-scan sslyze non-invasive light +smtps-tls-scan sslyze non-invasive light +ssh-audit ssh-audit non-invasive light +zap-http zap-automation-framework non-invasive medium +zap-https zap-automation-framework non-invasive mediumm ``` {{- end }} diff --git a/hooks/cascading-scans/README.md b/hooks/cascading-scans/README.md index 9d73038569..a5bf528f73 100644 --- a/hooks/cascading-scans/README.md +++ b/hooks/cascading-scans/README.md @@ -78,15 +78,16 @@ There is a configuration option `cascadingRules.enabled` for each scanner to pre ```bash # Check your CascadingRules kubectl get CascadingRules -NAME STARTS INVASIVENESS INTENSIVENESS -https-tls-scan sslyze non-invasive light -imaps-tls-scan sslyze non-invasive light -nikto-http nikto non-invasive medium -nmap-smb nmap non-invasive light -pop3s-tls-scan sslyze non-invasive light -smtps-tls-scan sslyze non-invasive light -ssh-audit ssh-audit non-invasive light -zap-http zap-baseline-scan non-invasive medium +NAME STARTS INVASIVENESS INTENSIVENESS +https-tls-scan sslyze non-invasive light +imaps-tls-scan sslyze non-invasive light +nikto-http nikto non-invasive medium +nmap-smb nmap non-invasive light +pop3s-tls-scan sslyze non-invasive light +smtps-tls-scan sslyze non-invasive light +ssh-audit ssh-audit non-invasive light +zap-http zap-automation-framework non-invasive medium +zap-https zap-automation-framework non-invasive medium ``` ### Starting a cascading Scan @@ -122,7 +123,7 @@ imaps-tls-scan sslyze non-invasive light nmap-smb nmap non-invasive light pop3s-tls-scan sslyze non-invasive light smtps-tls-scan sslyze non-invasive light -ssh-audit ssh-audit non-invasive light +ssh-audit ssh-audit non-invasive light ``` The label selectors also allow the more powerful matchExpressions selectors: @@ -152,15 +153,16 @@ This selection can be replicated in kubectl using: ```bash kubectl get CascadingRules -l "securecodebox.io/intensive in (light,medium)" -NAME STARTS INVASIVENESS INTENSIVENESS -https-tls-scan sslyze non-invasive light -imaps-tls-scan sslyze non-invasive light -nikto-http nikto non-invasive medium -nmap-smb nmap non-invasive light -pop3s-tls-scan sslyze non-invasive light -smtps-tls-scan sslyze non-invasive light -ssh-audit ssh-audit non-invasive light -zap-http zap-baseline-scan non-invasive medium +NAME STARTS INVASIVENESS INTENSIVENESS +https-tls-scan sslyze non-invasive light +imaps-tls-scan sslyze non-invasive light +nikto-http nikto non-invasive medium +nmap-smb nmap non-invasive light +pop3s-tls-scan sslyze non-invasive light +smtps-tls-scan sslyze non-invasive light +ssh-audit ssh-audit non-invasive light +zap-http zap-automation-framework non-invasive medium +zap-https zap-automation-framework non-invasive mediumm ``` ## Values diff --git a/hooks/cascading-scans/docs/README.ArtifactHub.md b/hooks/cascading-scans/docs/README.ArtifactHub.md index 8415986f2c..9f136e53d6 100644 --- a/hooks/cascading-scans/docs/README.ArtifactHub.md +++ b/hooks/cascading-scans/docs/README.ArtifactHub.md @@ -86,15 +86,16 @@ There is a configuration option `cascadingRules.enabled` for each scanner to pre ```bash # Check your CascadingRules kubectl get CascadingRules -NAME STARTS INVASIVENESS INTENSIVENESS -https-tls-scan sslyze non-invasive light -imaps-tls-scan sslyze non-invasive light -nikto-http nikto non-invasive medium -nmap-smb nmap non-invasive light -pop3s-tls-scan sslyze non-invasive light -smtps-tls-scan sslyze non-invasive light -ssh-audit ssh-audit non-invasive light -zap-http zap-baseline-scan non-invasive medium +NAME STARTS INVASIVENESS INTENSIVENESS +https-tls-scan sslyze non-invasive light +imaps-tls-scan sslyze non-invasive light +nikto-http nikto non-invasive medium +nmap-smb nmap non-invasive light +pop3s-tls-scan sslyze non-invasive light +smtps-tls-scan sslyze non-invasive light +ssh-audit ssh-audit non-invasive light +zap-http zap-automation-framework non-invasive medium +zap-https zap-automation-framework non-invasive medium ``` ### Starting a cascading Scan @@ -130,7 +131,7 @@ imaps-tls-scan sslyze non-invasive light nmap-smb nmap non-invasive light pop3s-tls-scan sslyze non-invasive light smtps-tls-scan sslyze non-invasive light -ssh-audit ssh-audit non-invasive light +ssh-audit ssh-audit non-invasive light ``` The label selectors also allow the more powerful matchExpressions selectors: @@ -160,15 +161,16 @@ This selection can be replicated in kubectl using: ```bash kubectl get CascadingRules -l "securecodebox.io/intensive in (light,medium)" -NAME STARTS INVASIVENESS INTENSIVENESS -https-tls-scan sslyze non-invasive light -imaps-tls-scan sslyze non-invasive light -nikto-http nikto non-invasive medium -nmap-smb nmap non-invasive light -pop3s-tls-scan sslyze non-invasive light -smtps-tls-scan sslyze non-invasive light -ssh-audit ssh-audit non-invasive light -zap-http zap-baseline-scan non-invasive medium +NAME STARTS INVASIVENESS INTENSIVENESS +https-tls-scan sslyze non-invasive light +imaps-tls-scan sslyze non-invasive light +nikto-http nikto non-invasive medium +nmap-smb nmap non-invasive light +pop3s-tls-scan sslyze non-invasive light +smtps-tls-scan sslyze non-invasive light +ssh-audit ssh-audit non-invasive light +zap-http zap-automation-framework non-invasive medium +zap-https zap-automation-framework non-invasive mediumm ``` ## Values diff --git a/hooks/persistence-defectdojo/.helm-docs.gotmpl b/hooks/persistence-defectdojo/.helm-docs.gotmpl index 4081729d18..8f8297895e 100644 --- a/hooks/persistence-defectdojo/.helm-docs.gotmpl +++ b/hooks/persistence-defectdojo/.helm-docs.gotmpl @@ -30,8 +30,7 @@ like deduplication. These scan types are (see up-to-date list in [Java source][d - Nmap - Nikto -- ZAP (Baseline, API Scan and Full Scan) -- ZAP Advanced +- ZAP Automation Scan - SSLyze - Trivy - Gitleaks @@ -179,36 +178,38 @@ It has come to our attention, that _DefectDojo_ become slow when handling a lot apiVersion: "execution.securecodebox.io/v1" kind: ScheduledScan metadata: - name: "zap-juiceshop" + name: "nmap-juice-shop-cluster-internal" annotations: - defectdojo.securecodebox.io/minimum_severity: "Low" + defectdojo.securecodebox.io/minimum_severity: "Low" spec: interval: 24h scanSpec: - scanType: "zap-full-scan" + scanType: "nmap" parameters: - - "-t" - - "http://juice-shop.demo-targets.svc:3000" + - "-Pn" + - "-sV" + - juice-shop.demo-targets.svc.cluster.local ``` In this example only for scan findings with a severity of "Low" or higher there are findings in _DefectDojo_ created. ### Simple Example Scans -This will run a daily scan using ZAP on a demo target. The results will be imported using the name "zap-juiceshop-$UNIX_TIMESTAMP" (Name of the Scan created by the ScheduledScan), in a product called "zap-juiceshop" in the default _DefectDojo_ product type. +This will run a daily scan using Nmap on a demo target. The results will be imported using the name "nmap-juiceshop-$UNIX_TIMESTAMP" (Name of the Scan created by the ScheduledScan), in a product called "nmap-juiceshop" in the default _DefectDojo_ product type. ```yaml apiVersion: "execution.securecodebox.io/v1" kind: ScheduledScan metadata: - name: "zap-juiceshop" + name: "nmap-juice-shop" spec: interval: 24h scanSpec: - scanType: "zap-full-scan" + scanType: "nmap" parameters: - - "-t" - - "http://juice-shop.demo-targets.svc:3000" + - "-Pn" + - "-sV" + - juice-shop.demo-targets.svc.cluster.local ``` ### Complete Example Scan @@ -219,7 +220,7 @@ This will import the results into engagement, product and product type following apiVersion: "execution.securecodebox.io/v1" kind: ScheduledScan metadata: - name: "zap-full-scan-juiceshop" + name: "nmap-juiceshop" annotations: defectdojo.securecodebox.io/product-type-name: "OWASP" defectdojo.securecodebox.io/product-name: "Juice Shop" @@ -229,17 +230,18 @@ metadata: Juice Shop encompasses vulnerabilities from the entire OWASP Top Ten along with many other security flaws found in real-world applications! defectdojo.securecodebox.io/product-tags: vulnerable,appsec,owasp-top-ten,vulnapp defectdojo.securecodebox.io/engagement-name: "Juice Shop" - defectdojo.securecodebox.io/engagement-version: "v12.6.1" + defectdojo.securecodebox.io/engagement-version: "v13.0.3" defectdojo.securecodebox.io/engagement-tags: "automated,daily" defectdojo.securecodebox.io/engagement-deduplicate-on-engagement: "true" - defectdojo.securecodebox.io/test-title: "Juice Shop - v12.6.1" + defectdojo.securecodebox.io/test-title: "Juice Shop - v13.0.3" spec: interval: 24h scanSpec: - scanType: "zap-full-scan" + scanType: "nmap" parameters: - - "-t" - - "http://juice-shop.demo-targets.svc:3000" + - "-Pn" + - "-sV" + - juice-shop.demo-targets.svc.cluster.local ``` ## Assinging more resources (CPU/Memory) to the Hook diff --git a/hooks/persistence-defectdojo/README.md b/hooks/persistence-defectdojo/README.md index 4a125dc42a..8022097df9 100644 --- a/hooks/persistence-defectdojo/README.md +++ b/hooks/persistence-defectdojo/README.md @@ -41,8 +41,7 @@ like deduplication. These scan types are (see up-to-date list in [Java source][d - Nmap - Nikto -- ZAP (Baseline, API Scan and Full Scan) -- ZAP Advanced +- ZAP Automation Scan - SSLyze - Trivy - Gitleaks @@ -197,35 +196,37 @@ It has come to our attention, that _DefectDojo_ become slow when handling a lot apiVersion: "execution.securecodebox.io/v1" kind: ScheduledScan metadata: - name: "zap-juiceshop" + name: "nmap-juice-shop-cluster-internal" annotations: - defectdojo.securecodebox.io/minimum_severity: "Low" + defectdojo.securecodebox.io/minimum_severity: "Low" spec: interval: 24h scanSpec: - scanType: "zap-full-scan" + scanType: "nmap" parameters: - - "-t" - - "http://juice-shop.demo-targets.svc:3000" + - "-Pn" + - "-sV" + - juice-shop.demo-targets.svc.cluster.local ``` In this example only for scan findings with a severity of "Low" or higher there are findings in _DefectDojo_ created. ### Simple Example Scans -This will run a daily scan using ZAP on a demo target. The results will be imported using the name "zap-juiceshop-$UNIX_TIMESTAMP" (Name of the Scan created by the ScheduledScan), in a product called "zap-juiceshop" in the default _DefectDojo_ product type. +This will run a daily scan using Nmap on a demo target. The results will be imported using the name "nmap-juiceshop-$UNIX_TIMESTAMP" (Name of the Scan created by the ScheduledScan), in a product called "nmap-juiceshop" in the default _DefectDojo_ product type. ```yaml apiVersion: "execution.securecodebox.io/v1" kind: ScheduledScan metadata: - name: "zap-juiceshop" + name: "nmap-juice-shop" spec: interval: 24h scanSpec: - scanType: "zap-full-scan" + scanType: "nmap" parameters: - - "-t" - - "http://juice-shop.demo-targets.svc:3000" + - "-Pn" + - "-sV" + - juice-shop.demo-targets.svc.cluster.local ``` ### Complete Example Scan @@ -236,7 +237,7 @@ This will import the results into engagement, product and product type following apiVersion: "execution.securecodebox.io/v1" kind: ScheduledScan metadata: - name: "zap-full-scan-juiceshop" + name: "nmap-juiceshop" annotations: defectdojo.securecodebox.io/product-type-name: "OWASP" defectdojo.securecodebox.io/product-name: "Juice Shop" @@ -246,17 +247,18 @@ metadata: Juice Shop encompasses vulnerabilities from the entire OWASP Top Ten along with many other security flaws found in real-world applications! defectdojo.securecodebox.io/product-tags: vulnerable,appsec,owasp-top-ten,vulnapp defectdojo.securecodebox.io/engagement-name: "Juice Shop" - defectdojo.securecodebox.io/engagement-version: "v12.6.1" + defectdojo.securecodebox.io/engagement-version: "v13.0.3" defectdojo.securecodebox.io/engagement-tags: "automated,daily" defectdojo.securecodebox.io/engagement-deduplicate-on-engagement: "true" - defectdojo.securecodebox.io/test-title: "Juice Shop - v12.6.1" + defectdojo.securecodebox.io/test-title: "Juice Shop - v13.0.3" spec: interval: 24h scanSpec: - scanType: "zap-full-scan" + scanType: "nmap" parameters: - - "-t" - - "http://juice-shop.demo-targets.svc:3000" + - "-Pn" + - "-sV" + - juice-shop.demo-targets.svc.cluster.local ``` ## Assinging more resources (CPU/Memory) to the Hook diff --git a/hooks/persistence-defectdojo/docs/README.ArtifactHub.md b/hooks/persistence-defectdojo/docs/README.ArtifactHub.md index c7d3ac6074..8747fe4062 100644 --- a/hooks/persistence-defectdojo/docs/README.ArtifactHub.md +++ b/hooks/persistence-defectdojo/docs/README.ArtifactHub.md @@ -49,8 +49,7 @@ like deduplication. These scan types are (see up-to-date list in [Java source][d - Nmap - Nikto -- ZAP (Baseline, API Scan and Full Scan) -- ZAP Advanced +- ZAP Automation Scan - SSLyze - Trivy - Gitleaks @@ -205,35 +204,37 @@ It has come to our attention, that _DefectDojo_ become slow when handling a lot apiVersion: "execution.securecodebox.io/v1" kind: ScheduledScan metadata: - name: "zap-juiceshop" + name: "nmap-juice-shop-cluster-internal" annotations: - defectdojo.securecodebox.io/minimum_severity: "Low" + defectdojo.securecodebox.io/minimum_severity: "Low" spec: interval: 24h scanSpec: - scanType: "zap-full-scan" + scanType: "nmap" parameters: - - "-t" - - "http://juice-shop.demo-targets.svc:3000" + - "-Pn" + - "-sV" + - juice-shop.demo-targets.svc.cluster.local ``` In this example only for scan findings with a severity of "Low" or higher there are findings in _DefectDojo_ created. ### Simple Example Scans -This will run a daily scan using ZAP on a demo target. The results will be imported using the name "zap-juiceshop-$UNIX_TIMESTAMP" (Name of the Scan created by the ScheduledScan), in a product called "zap-juiceshop" in the default _DefectDojo_ product type. +This will run a daily scan using Nmap on a demo target. The results will be imported using the name "nmap-juiceshop-$UNIX_TIMESTAMP" (Name of the Scan created by the ScheduledScan), in a product called "nmap-juiceshop" in the default _DefectDojo_ product type. ```yaml apiVersion: "execution.securecodebox.io/v1" kind: ScheduledScan metadata: - name: "zap-juiceshop" + name: "nmap-juice-shop" spec: interval: 24h scanSpec: - scanType: "zap-full-scan" + scanType: "nmap" parameters: - - "-t" - - "http://juice-shop.demo-targets.svc:3000" + - "-Pn" + - "-sV" + - juice-shop.demo-targets.svc.cluster.local ``` ### Complete Example Scan @@ -244,7 +245,7 @@ This will import the results into engagement, product and product type following apiVersion: "execution.securecodebox.io/v1" kind: ScheduledScan metadata: - name: "zap-full-scan-juiceshop" + name: "nmap-juiceshop" annotations: defectdojo.securecodebox.io/product-type-name: "OWASP" defectdojo.securecodebox.io/product-name: "Juice Shop" @@ -254,17 +255,18 @@ metadata: Juice Shop encompasses vulnerabilities from the entire OWASP Top Ten along with many other security flaws found in real-world applications! defectdojo.securecodebox.io/product-tags: vulnerable,appsec,owasp-top-ten,vulnapp defectdojo.securecodebox.io/engagement-name: "Juice Shop" - defectdojo.securecodebox.io/engagement-version: "v12.6.1" + defectdojo.securecodebox.io/engagement-version: "v13.0.3" defectdojo.securecodebox.io/engagement-tags: "automated,daily" defectdojo.securecodebox.io/engagement-deduplicate-on-engagement: "true" - defectdojo.securecodebox.io/test-title: "Juice Shop - v12.6.1" + defectdojo.securecodebox.io/test-title: "Juice Shop - v13.0.3" spec: interval: 24h scanSpec: - scanType: "zap-full-scan" + scanType: "nmap" parameters: - - "-t" - - "http://juice-shop.demo-targets.svc:3000" + - "-Pn" + - "-sV" + - juice-shop.demo-targets.svc.cluster.local ``` ## Assinging more resources (CPU/Memory) to the Hook diff --git a/hooks/persistence-defectdojo/docs/README.DockerHub-Hook.md b/hooks/persistence-defectdojo/docs/README.DockerHub-Hook.md index ba3da3f6f9..b74197cc33 100644 --- a/hooks/persistence-defectdojo/docs/README.DockerHub-Hook.md +++ b/hooks/persistence-defectdojo/docs/README.DockerHub-Hook.md @@ -60,8 +60,7 @@ like deduplication. These scan types are (see up-to-date list in [Java source][d - Nmap - Nikto -- ZAP (Baseline, API Scan and Full Scan) -- ZAP Advanced +- ZAP Automation Scan - SSLyze - Trivy - Gitleaks diff --git a/hooks/persistence-defectdojo/hook/src/main/java/io/securecodebox/persistence/util/ScanNameMapping.java b/hooks/persistence-defectdojo/hook/src/main/java/io/securecodebox/persistence/util/ScanNameMapping.java index c37a8c9e84..17a62252ed 100644 --- a/hooks/persistence-defectdojo/hook/src/main/java/io/securecodebox/persistence/util/ScanNameMapping.java +++ b/hooks/persistence-defectdojo/hook/src/main/java/io/securecodebox/persistence/util/ScanNameMapping.java @@ -8,11 +8,6 @@ public enum ScanNameMapping { NMAP("nmap", ScanType.NMAP_XML_SCAN), - ZAP_BASELINE("zap-baseline-scan", ScanType.ZAP_SCAN), - ZAP_API_SCAN("zap-api-scan", ScanType.ZAP_SCAN), - ZAP_FULL_SCAN("zap-full-scan", ScanType.ZAP_SCAN), - ZAP_ADVANCED_SCAN("zap-advanced-scan", ScanType.ZAP_SCAN), - ZAP_AUTOMATION_SCAN("zap-automation-scan", ScanType.ZAP_SCAN), ZAP_AUTOMATION_FRAMEWORK("zap-automation-framework", ScanType.ZAP_SCAN), SSLYZE("sslyze", ScanType.SSLYZE_SCAN), SSH_AUDIT("ssh-audit", ScanType.SSH_AUDIT_IMPORTER), @@ -38,7 +33,7 @@ public enum ScanNameMapping { /** * secureCodeBox ScanType *

- * Examples: {@literal "nmap"}, {@literal }"zap-api-scan"}, {@literal "zap-baseline-scan"} + * Examples: {@literal "nmap"}, {@literal }"zap-automation-framework"} *

*/ public final String secureCodeBoxbScanType; diff --git a/operator/Chart.yaml b/operator/Chart.yaml index 50c7fb63d6..4f386b4375 100644 --- a/operator/Chart.yaml +++ b/operator/Chart.yaml @@ -133,24 +133,20 @@ annotations: - apiVersion: "cascading.securecodebox.io/v1" kind: CascadingRule metadata: - name: "zap-http" + name: "nmap-hostscan" labels: securecodebox.io/invasive: non-invasive - securecodebox.io/intensive: medium + securecodebox.io/intensive: light spec: matches: anyOf: - - category: "Open Port" - attributes: - service: http - state: open - - category: "Open Port" - attributes: - service: https - state: open + - category: "Subdomain" + osi_layer: "NETWORK" scanSpec: - scanType: "zap-baseline-scan" - parameters: ["-t", "{{attributes.service}}://{{$.hostOrIP}}"] + scanType: "nmap" + parameters: + - "-Pn" + - "{{location}}" artifacthub.io/license: Apache-2.0 artifacthub.io/links: | - name: Documentation diff --git a/operator/internal/telemetry/telemetry.go b/operator/internal/telemetry/telemetry.go index 9af2214dbc..cceaa45320 100644 --- a/operator/internal/telemetry/telemetry.go +++ b/operator/internal/telemetry/telemetry.go @@ -48,12 +48,12 @@ var officialScanTypes map[string]bool = map[string]bool{ "typo3scan": true, // deprecated. we'll keep it in this list to still recieve telemetry data from older versions "whatweb": true, "wpscan": true, - "zap-baseline-scan": true, + "zap-baseline-scan": true, // deprecated. we'll keep it in this list to still recieve telemetry data from older versions "zap-api-scan": true, "zap-full-scan": true, "zap-automation-scan": true, "zap-automation-framework": true, - "zap-advanced-scan": true, + "zap-advanced-scan": true, // deprecated. we'll keep it in this list to still recieve telemetry data from older versions } // telemetryData submitted by operator diff --git a/scanners/zap-advanced/.gitignore b/scanners/zap-advanced/.gitignore deleted file mode 100644 index cdda09d9f0..0000000000 --- a/scanners/zap-advanced/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -*.tar -/scanner/tests/results/* diff --git a/scanners/zap-advanced/.helm-docs.gotmpl b/scanners/zap-advanced/.helm-docs.gotmpl deleted file mode 100644 index 18106eaec4..0000000000 --- a/scanners/zap-advanced/.helm-docs.gotmpl +++ /dev/null @@ -1,467 +0,0 @@ -{{- /* -SPDX-FileCopyrightText: the secureCodeBox authors - -SPDX-License-Identifier: Apache-2.0 -*/ -}} - -{{- define "extra.docsSection" -}} ---- -title: "ZAP Advanced" -category: "scanner" -type: "WebApplication" -state: "released" -appVersion: "{{ template "chart.appVersion" . }}" -usecase: "WebApp & OpenAPI Vulnerability Scanner extend with authentication features" ---- - -![zap logo](https://raw.githubusercontent.com/wiki/zaproxy/zaproxy/images/zap32x32.png) - -{{- end }} - -{{- define "extra.dockerDeploymentSection" -}} -## Supported Tags -- `latest` (represents the latest stable release build) -- tagged releases, e.g. `3.0.0`, `2.9.0`, `2.8.0`, `2.7.0` -{{- end }} - -{{- define "extra.chartAboutSection" -}} -## What is ZAP? -:::caution Deprecation Notice -The `zap-advanced` and `zap` ScanType are being deprecated in favor of the `zap-automation-framework`, which encompasses all functionalities of the previous ScanTypes. We recommend transitioning to the "zap-automation-framework" as soon as possible. `zap-advanced` and `zap` ScanTypes will be removed in the upcoming v5 release. For guidance on migrating to "zap-automation-framework," please refer to [migration to zap-automation framework](/docs/scanners/zap-automation-framework#migration-to-zap-automation-framework). -::: - -The Zed Attack Proxy (ZAP) is one of the world’s most popular free security tools and is actively maintained by hundreds of international volunteers*. It can help you automatically find security vulnerabilities in your web applications while you are developing and testing your applications. It's also a great tool for experienced pentesters to use for manual security testing. - -To learn more about the ZAP scanner itself visit [https://www.zaproxy.org/](https://www.zaproxy.org/). -{{- end }} - -{{- define "extra.scannerConfigurationSection" -}} -## Scanner Configuration - -Listed below are the arguments supported by the `zap-advanced-scan` script. - -The command line interface can be used to easily run server scans: `-t www.example.com` - -```bash -usage: zap-client [-h] -z ZAP_URL [-a API_KEY] [-c CONFIG_FOLDER] -t TARGET [-o OUTPUT_FOLDER] [-r XML,XML-plus,JSON,JSON-plus,HTML,HTML-plus,MD] - -OWASP secureCodeBox ZAP Client (can be used to automate ZAP instances based on YAML configuration files.) - -optional arguments: - -h, --help show this help message and exit - -z ZAP_URL, --zap-url ZAP_URL - The ZAP API Url used to call the ZAP API. - -a API_KEY, --api-key API_KEY - The ZAP API Key used to call the ZAP API. - -c CONFIG_FOLDER, --config-folder CONFIG_FOLDER - The path to a local folder containing the additional ZAP configuration YAMLs used to configure ZAP. - -t TARGET, --target TARGET - The target to scan with ZAP. - -o OUTPUT_FOLDER, --output-folder OUTPUT_FOLDER - The path to a local folder used to store the output files, eg. the ZAP Report or logfiles. - -r XML,XML-plus,JSON,JSON-plus,HTML,HTML-plus,MD, --report-type XML,XML-plus,JSON,JSON-plus,HTML,HTML-plus,MD - The ZAP Report Type. -``` -{{- end }} - -{{- define "extra.chartConfigurationSection" -}} -## Additional Chart Configurations - -By default, the secureCodeBox ZAP Helm Chart installs the scanType `zap-advanced-scan` along with a minimal _default configuration_ based on the HelmChart value `zapConfiguration`. The configuration will be stored in a dedicate scanType specific _configMap_ named `zap-advanced-scantype-config`. Feel free to use the `configMap` or even the HelmChart values to adjust the advanced ZAP configuration settings according to your needs. Details about the different configuration options can be found below. - -Additionally, there will be some ZAP Scripts included, these are stored in the corresponding configMaps `zap-scripts-authentication` and `zap-scripts-session`. Scripts can be used to implement a specific behavior or even new authentication patterns, which are not supported by ZAP out of the box. Feel free to add additional scripts in your own, if you need them. - -```bash - ┌────────────────────────────────────────┐ -┌──────────────────────────────────────┐ │A YAML configuration file for ZAP that │ -│This CM contains ZAP authentication │ │relates to the scanType directly. │ -│scripts that are already included │ │- will be used for all scans by default │ -│within the zap-advanced scanner. │ │- can be configured via Helm Values: │ -│Feel free to add your own. │────────┐ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ┌───────│ zapConfiguration │ -│ │ │ │ │- add your baseline config here │ -│ConfigMap: zap-scripts-authentication │ │ │ ┌───────────────────┐ │ │ │ │ -└──────────────────────────────────────┘ │ │ │ │ │ConfigMap: zap-advanced-scantype-config │ - │ │ │ ZAP Client │ │ │ └────────────────────────────────────────┘ - All scripts are mounted as files │ │ Python3 Module │◀─────┤ - directly into the ZAP container. To use │ │ │ │ │ │ All referenced YAML files will be merged into - them add a corresponding script section │ └───────────────────┘ │ one single YAML configuration. The merged one - in your config YAML. │ │ │ │ │ will be used to configure the ZAP instance. - │ uses API │ -┌──────────────────────────────────────┐ │ │ │ │ │ ┌────────────────────────────────────────┐ -│This CM contains ZAP session │ │ ▼ │ │A YAML configuration for ZAP that │ -│scripts that are already included │ │ │ ┌───────────────────┐ │ │ │relates to a single scan execution. │ -│within the zap-advanced scanner. │ │ │ │ │ │- can by used for selected scans │ -│Feel free to add your own. │────────┼─────┼─▶│ ZAP Proxy │ │ │- not created by default │ -│ │ │ │ │ └───────│- add your scan target specific config │ -│ConfigMap: zap-scripts-session │ │ │ └───────────────────┘ │ │- needs to be referenced in Scan │ -└──────────────────────────────────────┘ │ │- please use SecretMap for credentials! │ -┌──────────────────────────────────────┐ │ │ secureCodeBox scanner │ │ │ -│Feel free to add your own scripts :) │ │ scanType: zap-advanced │ConfigMap: zap-advanced-scan-config │ -│ │────────┘ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ └────────────────────────────────────────┘ -│ConfigMap: zap-scripts-your-name │ -└──────────────────────────────────────┘ - -``` - -The following picture outlines the reference concept of the ZAP YAML configuration `zapConfiguration`. If you want to configure an `api` scan, `spider` or active `scan` you must at least add one `context` item with a `name` and `url` configured. The context `url` must match the target url used in the `Scan` execution: - -```yaml -spec: - scanType: "zap-advanced-scan" - parameters: - # target URL must match with `context.url` to identify the corresponding configurations. - - "-t" - - "http://bodgeit.default.svc:8080/bodgeit/" -``` - -If you want to configure the `api` scan, `spider` or active `scan` section it is mandatory to add the `context: ` reference the section. Otherwise it is not possible to identify which configuration must be used for a scan. The `url` in the `api` , `spider` or active 'scan` section can be different to the context.url (and scan target url). - -```bash -┌────────────────────────────────────────────────────────────────┐ -│ ZAP Configuration YAML - reference by "context name" │ -└────────────────────────────────────────────────────────────────┘ - -┌────────────────┐ ┌────────────────┐ -│ Context │ │ Context │ -│ - name: ABC │◀───┬─┬─┐ │ - name: XYZ │◀───┬─┬─┐ -│ url: ... │ │ │ │ │ url: ... │ │ │ │ -└────────────────┘ │ │ │ └────────────────┘ │ │ │ - ┌─────────────────┐ │ │ │ ┌─────────────────┐ │ │ │ - │ API: │ │ │ │ │ API: │ │ │ │ - │ - context: ABC │──┘ │ │ │ - context: XYZ │──┘ │ │ - │ - ... │ │ │ │ - ... │ │ │ - └─────────────────┘ │ │ └─────────────────┘ │ │ - ┌─────────────────┐ │ │ ┌─────────────────┐ │ │ - │ Spider: │ │ │ │ Spider: │ │ │ - │ - context: ABC │──┘ │ │ - context: XYZ │──┘ │ - │ - ... │ │ │ - ... │ │ - └─────────────────┘ │ └─────────────────┘ │ - ┌─────────────────┐ │ ┌─────────────────┐ │ - │ Scanner: │ │ │ Scanner: │ │ - │ - context: ABC │──┘ │ - context: XYZ │──┘ - │ - ... │ │ - ... │ - └─────────────────┘ └─────────────────┘ - -``` - -## ZAP Configuration -The following YAMl gives you an overview about all the different configuration options you have to configure the ZAP advanced scan. Please have a look into our `./examples/...` to find some working examples. We provide a list of working examples to scan our `demo-targets` with the `zap-advanced-scan`. - -:::note - -The YAML format is based on the new [ZAP Automation Framework](https://www.zaproxy.org/docs/desktop/addons/automation-framework/) but not exactly the same. The ZAP Automation Framework is a new approach of the ZAP Team to ease up the automation possibilities of the ZAP scanner itself. Since this ZAP Automation Framework is not ready yet we are not using it for now. We track the progress in this [issue #321](https://github.com/secureCodeBox/secureCodeBox/issues/321) for the future. - -The ZAP Automation format represents a more "imperative" semantic, due to the fact that you have to configure sequences of "jobs" containing the steps to configure and automate ZAP. In contrast to that has the secureCodeBox `zap-advanced` YAML format `zapConfiguration` a "declarative" semantic. The similarity of both YAML formats can help to migrate to the ZAP Automation Framework. - -::: - -```yaml -zapConfiguration: - # -- Optional general ZAP Configurations settings. - global: - # -- The ZAP internal Session name. Default: secureCodeBox - sessionName: secureCodeBox - # -- Updates all installed ZAP AddOns on startup if true, otherwise false. - addonUpdate: true - # -- Installs additional ZAP AddOns on startup, listed by their name: - addonInstall: - - pscanrulesBeta - - ascanrulesBeta - - pscanrulesAlpha - - ascanrulesAlpha - # -- An optional list of global regexes to include - includePaths: - - "https://example.com/.*" - # -- An optional list of global regexes to exclude - excludePaths: - # - "https://example.com/authserver/v1/.*" - - ".*\\.js" - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - # -- Configures a proxy for ZAP to tunnel the traffic somewhere else - proxy: - # -- Define if an outgoing proxy server is used. - enabled: false - # -- The proxy port to use - port: 8080 - # -- MANDATORY only if useProxyChain is True, ignored otherwise. Outgoing proxy address and port - address: my.corp.proxy - # -- Define the addresses to skip in case useProxyChain is True. Ignored otherwise. List can be empty. - skipProxyAddresses: - - "127.0.0.1" - - localhost - # -- MANDATORY only if proxy.enabled is True. Ignored otherwise. Define if proxy server needs authentication - authentication: - enabled: false - proxyUsername: "" - proxyPassword: "" - proxyRealm: "" - # -- Configures existings ZAP Scripts or add new ZAP Scripts. For example can be used if a proxy script must be loaded. Proxy scripts are executed for every request traversing ZAP - scripts: - - name: "Alert_on_HTTP_Response_Code_Errors.js" - # -- True if the script must be enabled, false otherwise - enabled: false - # -- The complete filepath (inside the ZAP Container!) to the script file. - filePath: "/home/zap/.ZAP_D/scripts/scripts/httpsender/Alert_on_HTTP_Response_Code_Errors.js" - # -- The script engine. Possible values are: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - engine: "Oracle Nashorn" - # -- The type of script engine used. Possible values are: 'httpsender', 'authentication', 'session', 'proxy', ... - type: "httpsender" - # -- A short description for the script. - description: "A HTTP Sender Script which will raise alerts based on HTTP Response codes." - - name: "Alert_on_Unexpected_Content_Types.js" - # -- True if the script must be enabled, false otherwise - enabled: false - # -- The complete filepath (inside the ZAP Container!) to the script file. - filePath: "/home/zap/.ZAP_D/scripts/scripts/httpsender/Alert_on_Unexpected_Content_Types.js" - # -- The type of script engine used. Possible values are: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - engine: "Oracle Nashorn" - # -- The type of the script. Possible values are: 'httpsender', 'authentication', 'session', 'proxy', ... - type: "httpsender" - # -- A short description for the script. - description: "A HTTP Sender Script which will raise alerts based on unexpected Content-Types." - - # -- Optional list of ZAP Context definitions - contexts: - # -- Name to be used to refer to this context in other jobs, mandatory - - name: scbcontext - # -- The top level URL - url: https://example.com/ - # -- An optional list of regexes to include in the ZAP context - includePaths: - - "https://example.com/.*" - # -- An optional list of regexes to exclude in the ZAP context - excludePaths: - # - "https://example.com/authserver/v1/.*" - - ".*\\.js" - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - # -- Optional technology list - technology: - # -- By default all technologies are enabed for each context by ZAP. You can use the following config to change that explicitly. - included: - - Db.CouchDB - - Db.Firebird - - Db.HypersonicSQL - - Language.ASP - - OS - # -- By default all technologies are enabed for each context by ZAP. You can use the following config to change that explicitly. - excluded: - - SCM - # -- Authentication Configuration that can be uses by ZAP Spider and/or Scanner. You need to reference the `context` name in the corresponding `zapConfiguration.spiders[0].context` and `zapConfiguration.scanners[0].context` section if you want to use them. - authentication: - # -- Currently supports "basic-auth", "form-based", "json-based", "script-based" - type: "script-based" - # -- Optional, only mandatory if zapConfiguration.contexts[0].authentication.type: "script-based". More ZAP details about 'script based' authentication can be found here: https://www.zaproxy.org/docs/api/#script-based-authentication. - script-based: - # -- The name of the authentication script - name: scb-oidc-password-grand-type.js - # -- Enables the script if true, otherwise false - enabled: true - # -- The type of script engine used. Possible values are: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - engine: "Oracle Nashorn" - # -- Must be a full path to the script file inside the ZAP container (corresponding to the configMap FileMount) - filePath: "/home/zap/.ZAP_D/scripts/scripts/authentication/scb-oidc-password-grand-type.js" - # -- A short description for the script. - description: "This is a description for the SCB OIDC Script." - # -- Optional list of all script arguments needed to be passed to the script. - arguments: - sub: "secureCodeBox@iteratec.com" - email: "secureCodeBox@teratec.com" - exp: "1609459140" - # -- Optional, only mandatory if zapConfiguration.contexts[0].authentication.type: "basic-auth". More ZAP details about 'basic auth' based authentication can be found here: https://www.zaproxy.org/docs/api/?python#general-steps. - basic-auth: - # -- The hostname that must be for the basic authentication - hostname: "https://example.com/" - # -- The realm that must be for the basic authentication - realm: "Realm" - # -- The port that must be for the basic authentication - port: 8080 - # -- Optional, only mandatory if zapConfiguration.contexts[0].authentication.type: "form-based". More ZAP details about 'form-based' based authentication can be found here: https://www.zaproxy.org/docs/api/#form-based-authentication. - form-based: - # -- The URL to the login form that must be used - loginUrl: "http://localhost:8090/bodgeit/login.jsp" - # -- The mapping of username and password to HTTP post parameters. Hint: the value must be escaped already to prevent YAML parser colidations. Example the intended value 'username={%username%}&password={%password%}' must be ''username%3D%7B%25username%25%7D%26password%3D%7B%25password%25%7D. - loginRequestData: "username%3D%7B%25username%25%7D%26password%3D%7B%25password%25%7D" - # -- Optional, only mandatory if zapConfiguration.contexts[0].authentication.type: "json-based". More ZAP details about 'json-based' based authentication can be found here: https://www.zaproxy.org/docs/api/#json-based-authentication. - json-based: - loginUrl: "http://localhost:3000/rest/user/login" - # must be escaped already to prevent yaml parser colidations '{"user":{"id":1,"email":"test@test.com"}}'' - loginRequestData: '{"user":{"id":1,"email":"test@test.com"}}' - # -- Indicates if the current Zap User Session is based on a valid authentication (loggedIn) or not (loggedOut) - verification: - # -- The optional ZAP indiator string for loggedIn Users - isLoggedInIndicator: "" - # -- The optional ZAP indiator string for loggedOut Users - isLoggedOutIndicator: "" - # -- A list of users with credentials which can be referenced by spider or scanner configurations to run them authenticated (you have to configure the authentiation settings). Hint: you can use secretMaps to seperate credentails. - users: - # -- The name of this user configuration - - name: test-user-1 - # -- The username used to authenticate this user - username: user1 - # -- The password used to authenticate this user - password: password1 - # -- Optional, could be set to True only once in the users list. If not defined the first user in the list will be forced by default. - forced: true - # -- The name of this user configuration - - name: test-user-2 - # -- The username used to authenticate this user - username: user2 - # -- The password used to authenticate this user - password: password2 - # -- The optional ZAP session configuration - session: - # -- The ZAP Session type indicates how Zap identifies sessions. Currently supports the following types: "scriptBasedSessionManagement", "cookieBasedSessionManagement", "httpAuthSessionManagement" - type: "scriptBasedSessionManagement" - # -- Optional, only mandatory if zapConfiguration.contexts[0].session.type: "scriptBasedSessionManagement". Additional configrations for the session type "scriptBasedSessionManagement" - scriptBasedSessionManagement: - # -- The name of the session script to be used. - name: "juiceshop-session-management.js" - # -- Enables the script if true, otherwise false - enabled: true - # -- The type of script engine used. Possible values are: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - engine: "Oracle Nashorn" - # -- Must be a full path to the script file inside the ZAP container (corresponding to the configMap FileMount) - fileName: "/home/zap/.ZAP_D/scripts/scripts/session/juiceshop-session-management.js" - # -- An optional description used for the script. - description: "This is a JuiceShop specific SessionManagement Script used to handle JWT." - - # -- Optional list of ZAP OpenAPI configurations - apis: - # -- The name of the api configuration - - name: scb-petstore-api - # -- The Name of the context (zapConfiguration.contexts[x].name) to reference, default: the first context available - context: scb-petstore-context - # -- The used format of the API. Possible values are: 'openapi', 'grapql', 'soap' - format: openapi - # -- Url to start importing the API from, default: first context URL - url: http://localhost:8000/v2/swagger.json - # -- Optional: Override host setting in the API (e.g. swagger.json) if your API is using some kind of internal routing. - hostOverride: http://localhost:8000 - # -- Optional: Assumes that the API Spec has been saved to a configmap in the namespace of the scan / this release. Should be null if not used. - configMap: - # Object with two keys: "name" name of the config map, and "key" which is the key / property in the configmap which holds the openapi spec file. - name: my-configmap-with-openapi-spec - key: openapi.yaml - # -- Allows to embed the entire yaml / json API spec in the values (e.g. OpenAPI YAML spec). Should be null if not used. - spec: null - # -- Configures existings ZAP Scripts or add new ZAP Scripts. For example can be used if a proxy script must be loaded. Proxy scripts are executed for every request traversing ZAP - scripts: - - name: "Alert_on_HTTP_Response_Code_Errors.js" - # -- True if the script must be enabled, false otherwise - enabled: true - - name: "Alert_on_Unexpected_Content_Types.js" - # -- True if the script must be enabled, false otherwise - enabled: true - - # -- Optional list of ZAP Spider configurations - spiders: - # -- String: The name of the spider configuration - - name: scbspider - # -- String: The Name of the context (zapConfiguration.contexts[x].name) to spider, default: first context available - context: scbcontext - # -- String: The Name of the user (zapConfiguration.contexts[0].users[0].name) used to authenticate the spider with - user: "test-user-1" - # -- String: Url to start spidering from, default: first context URL - url: https://example.com/ - # -- Bool: Whether to use the ZAP ajax spider, default: false - ajax: false - # -- Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # -- Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # -- Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 0 - # -- Int: The maximum tree depth to explore, default 5 - maxDepth: 5 - # -- Int: The maximum number of children to add to each node in the tree - maxChildren: 10 - # -- Bool: Whether the spider will accept cookies, default: true - acceptCookies: true - # -- Bool: Whether the spider will handle OData responses, default: false - handleODataParametersVisited: false - # -- Enum [ignore_completely, ignore_value, use_all]: How query string parameters are used when checking if a URI has already been visited, default: use_all - handleParameters: use_all - # -- Int: The max size of a response that will be parsed, default: 2621440 - 2.5 Mb - maxParseSizeBytes: 2621440 - # -- Bool: Whether the spider will parse HTML comments in order to find URLs, default: true - parseComments: true - # Bool: Whether the spider will parse Git metadata in order to find URLs, default: false - parseGit: false - # -- Bool: Whether the spider will parse 'robots.txt' files in order to find URLs, default: true - parseRobotsTxt: true - # -- Bool: Whether the spider will parse 'sitemap.xml' files in order to find URLs, default: true - parseSitemapXml: true - # -- Bool: Whether the spider will parse SVN metadata in order to find URLs, default: false - parseSVNEntries: false - # -- Bool: Whether the spider will submit POST forms, default: true - postForm: true - # -- Bool: Whether the spider will process forms, default: true - processForm: true - # -- Int: The time between the requests sent to a server in milliseconds, default: 200 - requestWaitTime: 200 - # -- Bool: Whether the spider will send the referer header, default: true - sendRefererHeader: true - # -- Int: The number of spider threads, default: 2 - threadCount: 2 - # -- String: The user agent to use in requests, default: '' - use the default ZAP one - userAgent: "secureCodeBox / ZAP Spider" - # -- Configures existings ZAP Scripts or add new ZAP Scripts. For example can be used if a proxy script must be loaded. Proxy scripts are executed for every request traversing ZAP - scripts: {} - - # -- Optional list of ZAP Active Scanner configurations - scanners: - # -- String: Name of the context to attack, default: first context - - name: scbscan - # -- String: Name of the context to attack, default: first context - context: scbcontext - # -- String: Url to start scaning from, default: first context URL - url: https://example.com/ - # -- String: The name of the default scan policy to use, default: Default Policy - defaultPolicy: "Default Policy" - # -- String: Name of the scan policy to be used, default: Default Policy - policy: "Default Policy" - # -- Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 0 - # -- Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 0 - # -- Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # -- Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # -- Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # -- Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # -- Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false - # -- Int: The max number of threads per host, default: 2 - threadPerHost: 2 - # -- The policy definition, only used if the 'policy' is not set - NOT YET IMPLEMENTED - policyDefinition: - # -- String: The default Attack Strength for all rules, one of Low, Medium, High, Insane (not recommended), default: Medium - defaultStrength: Medium - # -- String: The default Alert Threshold for all rules, one of Off, Low, Medium, High, default: Medium - defaultThreshold: Medium - # -- A list of one or more active scan rules and associated settings which override the defaults - rules: - # -- Int: The rule id as per https://www.zaproxy.org/docs/alerts/ - - id: 10106 - # -- The name of the rule for documentation purposes - this is not required or actually used - name: "rule" - # -- String: The Attack Strength for this rule, one of Low, Medium, High, Insane, default: Medium - strength: Medium - # -- String: The Alert Threshold for this rule, one of Off, Low, Medium, High, default: Medium - threshold: Low - # -- Configures existings ZAP Scripts or add new ZAP Scripts. For example can be used if a proxy script must be loaded. Proxy scripts are executed for every request traversing ZAP - scripts: {} -``` -{{- end }} - -{{- define "extra.scannerLinksSection" -}} -[zap github]: https://github.com/zaproxy/zaproxy/ -[zap user guide]: https://www.zaproxy.org/docs/ -{{- end }} diff --git a/scanners/zap-advanced/.helmignore b/scanners/zap-advanced/.helmignore deleted file mode 100644 index 73ddd6eb2c..0000000000 --- a/scanners/zap-advanced/.helmignore +++ /dev/null @@ -1,46 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*~ -# Various IDEs -.project -.idea/ -*.tmproj -.vscode/ -# Node.js files -node_modules/* -package.json -package-lock.json -src/* -config/* -Dockerfile -.dockerignore -*.tar -parser/* -# this doesn't look too good but is required so that the scanners/scripts folder is included -scanner/*.* -scanner/zapclient/ -scanner/tests/ -scanner/venv/ -scanner/.pytest_cache/ -scanner/.idea/ -integration-tests/* -examples/* -docs/* -Makefile diff --git a/scanners/zap-advanced/Chart.yaml b/scanners/zap-advanced/Chart.yaml deleted file mode 100644 index a6bcd27c88..0000000000 --- a/scanners/zap-advanced/Chart.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -apiVersion: v2 -name: zap-advanced -description: A Helm chart for the ZAP (extended with advanced authentication features) security scanner that integrates with the secureCodeBox. -type: application -# version - gets automatically set to the secureCodeBox release version when the helm charts gets published -version: v3.1.0-alpha1 -appVersion: "2.16.1" -kubeVersion: ">=v1.11.0-0" -annotations: - versionApi: https://api.github.com/repos/zaproxy/zaproxy/releases/latest -keywords: - - security - - ZAP - - OWASP - - scanner - - secureCodeBox -home: https://www.securecodebox.io/docs/scanners/ZAP -icon: https://www.securecodebox.io/img/integrationIcons/ZAP.svg -sources: - - https://github.com/secureCodeBox/secureCodeBox -maintainers: - - name: iteratec GmbH - email: secureCodeBox@iteratec.com diff --git a/scanners/zap-advanced/Makefile b/scanners/zap-advanced/Makefile deleted file mode 100644 index e582962f3c..0000000000 --- a/scanners/zap-advanced/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/make -f -# -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 -# - -include_guard = set -scanner = zap-advanced -custom_scanner = set - -include ../../scanners.mk - -unit-tests: - @$(MAKE) -s unit-test-py - -unit-tests-parser: - $(MAKE) -s -f ../../scanners.mk unit-tests-parser include_guard=set scanner=zap - -install-deps: - cd $(SCANNERS_DIR)/zap/ && $(MAKE) -s install-deps - -docker-build-parser: - cd $(SCANNERS_DIR)/zap/ && $(MAKE) -s docker-build-parser - -docker-export-parser: - cd $(SCANNERS_DIR)/zap/ && $(MAKE) -s docker-export-parser - -kind-import-parser: - cd $(SCANNERS_DIR)/zap/ && $(MAKE) -s kind-import-parser - -deploy-with-scanner: - @echo ".: 💾 Deploying custom '$(scanner)' scanner HelmChart with the docker tag '$(IMG_TAG)' into kind namespace 'integration-tests'." - helm -n integration-tests upgrade --install $(scanner) ./ --wait \ - --set="parser.image.repository=docker.io/$(IMG_NS)/$(parser-prefix)-zap" \ - --set="parser.image.tag=$(IMG_TAG)" \ - --set="scanner.image.repository=docker.io/$(IMG_NS)/$(scanner-prefix)-$(scanner)" \ - --set="scanner.image.tag=$(IMG_TAG)" - -deploy-test-deps: deploy-test-dep-bodgeit deploy-test-dep-juiceshop deploy-test-dep-petstore - -integration-tests: - @echo ".: 🩺 Starting integration test in kind namespace 'integration-tests'." - kubectl -n integration-tests delete scans --all - kubectl apply -f ./integration-tests/scantype-configMap.yaml -n integration-tests - cd $(SCANNERS_DIR) && npm ci && cd $(scanner)/integration-tests && npm run test:integration -- $(scanner)/integration-tests diff --git a/scanners/zap-advanced/README.md b/scanners/zap-advanced/README.md deleted file mode 100644 index 97178085b6..0000000000 --- a/scanners/zap-advanced/README.md +++ /dev/null @@ -1,549 +0,0 @@ ---- -title: "ZAP Advanced" -category: "scanner" -type: "WebApplication" -state: "released" -appVersion: "2.16.1" -usecase: "WebApp & OpenAPI Vulnerability Scanner extend with authentication features" ---- - -![zap logo](https://raw.githubusercontent.com/wiki/zaproxy/zaproxy/images/zap32x32.png) - - - - -

- License Apache-2.0 - GitHub release (latest SemVer) - OWASP Lab Project - Artifact HUB - GitHub Repo stars - Mastodon Follower -

- -## What is ZAP? -:::caution Deprecation Notice -The `zap-advanced` and `zap` ScanType are being deprecated in favor of the `zap-automation-framework`, which encompasses all functionalities of the previous ScanTypes. We recommend transitioning to the "zap-automation-framework" as soon as possible. `zap-advanced` and `zap` ScanTypes will be removed in the upcoming v5 release. For guidance on migrating to "zap-automation-framework," please refer to [migration to zap-automation framework](/docs/scanners/zap-automation-framework#migration-to-zap-automation-framework). -::: - -The Zed Attack Proxy (ZAP) is one of the world’s most popular free security tools and is actively maintained by hundreds of international volunteers*. It can help you automatically find security vulnerabilities in your web applications while you are developing and testing your applications. It's also a great tool for experienced pentesters to use for manual security testing. - -To learn more about the ZAP scanner itself visit [https://www.zaproxy.org/](https://www.zaproxy.org/). - -## Deployment -The zap-advanced chart can be deployed via helm: - -```bash -# Install HelmChart (use -n to configure another namespace) -helm upgrade --install zap-advanced oci://ghcr.io/securecodebox/helm/zap-advanced -``` - -## Scanner Configuration - -Listed below are the arguments supported by the `zap-advanced-scan` script. - -The command line interface can be used to easily run server scans: `-t www.example.com` - -```bash -usage: zap-client [-h] -z ZAP_URL [-a API_KEY] [-c CONFIG_FOLDER] -t TARGET [-o OUTPUT_FOLDER] [-r XML,XML-plus,JSON,JSON-plus,HTML,HTML-plus,MD] - -OWASP secureCodeBox ZAP Client (can be used to automate ZAP instances based on YAML configuration files.) - -optional arguments: - -h, --help show this help message and exit - -z ZAP_URL, --zap-url ZAP_URL - The ZAP API Url used to call the ZAP API. - -a API_KEY, --api-key API_KEY - The ZAP API Key used to call the ZAP API. - -c CONFIG_FOLDER, --config-folder CONFIG_FOLDER - The path to a local folder containing the additional ZAP configuration YAMLs used to configure ZAP. - -t TARGET, --target TARGET - The target to scan with ZAP. - -o OUTPUT_FOLDER, --output-folder OUTPUT_FOLDER - The path to a local folder used to store the output files, eg. the ZAP Report or logfiles. - -r XML,XML-plus,JSON,JSON-plus,HTML,HTML-plus,MD, --report-type XML,XML-plus,JSON,JSON-plus,HTML,HTML-plus,MD - The ZAP Report Type. -``` - -## Requirements - -Kubernetes: `>=v1.11.0-0` - -## Additional Chart Configurations - -By default, the secureCodeBox ZAP Helm Chart installs the scanType `zap-advanced-scan` along with a minimal _default configuration_ based on the HelmChart value `zapConfiguration`. The configuration will be stored in a dedicate scanType specific _configMap_ named `zap-advanced-scantype-config`. Feel free to use the `configMap` or even the HelmChart values to adjust the advanced ZAP configuration settings according to your needs. Details about the different configuration options can be found below. - -Additionally, there will be some ZAP Scripts included, these are stored in the corresponding configMaps `zap-scripts-authentication` and `zap-scripts-session`. Scripts can be used to implement a specific behavior or even new authentication patterns, which are not supported by ZAP out of the box. Feel free to add additional scripts in your own, if you need them. - -```bash - ┌────────────────────────────────────────┐ -┌──────────────────────────────────────┐ │A YAML configuration file for ZAP that │ -│This CM contains ZAP authentication │ │relates to the scanType directly. │ -│scripts that are already included │ │- will be used for all scans by default │ -│within the zap-advanced scanner. │ │- can be configured via Helm Values: │ -│Feel free to add your own. │────────┐ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ┌───────│ zapConfiguration │ -│ │ │ │ │- add your baseline config here │ -│ConfigMap: zap-scripts-authentication │ │ │ ┌───────────────────┐ │ │ │ │ -└──────────────────────────────────────┘ │ │ │ │ │ConfigMap: zap-advanced-scantype-config │ - │ │ │ ZAP Client │ │ │ └────────────────────────────────────────┘ - All scripts are mounted as files │ │ Python3 Module │◀─────┤ - directly into the ZAP container. To use │ │ │ │ │ │ All referenced YAML files will be merged into - them add a corresponding script section │ └───────────────────┘ │ one single YAML configuration. The merged one - in your config YAML. │ │ │ │ │ will be used to configure the ZAP instance. - │ uses API │ -┌──────────────────────────────────────┐ │ │ │ │ │ ┌────────────────────────────────────────┐ -│This CM contains ZAP session │ │ ▼ │ │A YAML configuration for ZAP that │ -│scripts that are already included │ │ │ ┌───────────────────┐ │ │ │relates to a single scan execution. │ -│within the zap-advanced scanner. │ │ │ │ │ │- can by used for selected scans │ -│Feel free to add your own. │────────┼─────┼─▶│ ZAP Proxy │ │ │- not created by default │ -│ │ │ │ │ └───────│- add your scan target specific config │ -│ConfigMap: zap-scripts-session │ │ │ └───────────────────┘ │ │- needs to be referenced in Scan │ -└──────────────────────────────────────┘ │ │- please use SecretMap for credentials! │ -┌──────────────────────────────────────┐ │ │ secureCodeBox scanner │ │ │ -│Feel free to add your own scripts :) │ │ scanType: zap-advanced │ConfigMap: zap-advanced-scan-config │ -│ │────────┘ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ └────────────────────────────────────────┘ -│ConfigMap: zap-scripts-your-name │ -└──────────────────────────────────────┘ - -``` - -The following picture outlines the reference concept of the ZAP YAML configuration `zapConfiguration`. If you want to configure an `api` scan, `spider` or active `scan` you must at least add one `context` item with a `name` and `url` configured. The context `url` must match the target url used in the `Scan` execution: - -```yaml -spec: - scanType: "zap-advanced-scan" - parameters: - # target URL must match with `context.url` to identify the corresponding configurations. - - "-t" - - "http://bodgeit.default.svc:8080/bodgeit/" -``` - -If you want to configure the `api` scan, `spider` or active `scan` section it is mandatory to add the `context: ` reference the section. Otherwise it is not possible to identify which configuration must be used for a scan. The `url` in the `api` , `spider` or active 'scan` section can be different to the context.url (and scan target url). - -```bash -┌────────────────────────────────────────────────────────────────┐ -│ ZAP Configuration YAML - reference by "context name" │ -└────────────────────────────────────────────────────────────────┘ - -┌────────────────┐ ┌────────────────┐ -│ Context │ │ Context │ -│ - name: ABC │◀───┬─┬─┐ │ - name: XYZ │◀───┬─┬─┐ -│ url: ... │ │ │ │ │ url: ... │ │ │ │ -└────────────────┘ │ │ │ └────────────────┘ │ │ │ - ┌─────────────────┐ │ │ │ ┌─────────────────┐ │ │ │ - │ API: │ │ │ │ │ API: │ │ │ │ - │ - context: ABC │──┘ │ │ │ - context: XYZ │──┘ │ │ - │ - ... │ │ │ │ - ... │ │ │ - └─────────────────┘ │ │ └─────────────────┘ │ │ - ┌─────────────────┐ │ │ ┌─────────────────┐ │ │ - │ Spider: │ │ │ │ Spider: │ │ │ - │ - context: ABC │──┘ │ │ - context: XYZ │──┘ │ - │ - ... │ │ │ - ... │ │ - └─────────────────┘ │ └─────────────────┘ │ - ┌─────────────────┐ │ ┌─────────────────┐ │ - │ Scanner: │ │ │ Scanner: │ │ - │ - context: ABC │──┘ │ - context: XYZ │──┘ - │ - ... │ │ - ... │ - └─────────────────┘ └─────────────────┘ - -``` - -## ZAP Configuration -The following YAMl gives you an overview about all the different configuration options you have to configure the ZAP advanced scan. Please have a look into our `./examples/...` to find some working examples. We provide a list of working examples to scan our `demo-targets` with the `zap-advanced-scan`. - -:::note - -The YAML format is based on the new [ZAP Automation Framework](https://www.zaproxy.org/docs/desktop/addons/automation-framework/) but not exactly the same. The ZAP Automation Framework is a new approach of the ZAP Team to ease up the automation possibilities of the ZAP scanner itself. Since this ZAP Automation Framework is not ready yet we are not using it for now. We track the progress in this [issue #321](https://github.com/secureCodeBox/secureCodeBox/issues/321) for the future. - -The ZAP Automation format represents a more "imperative" semantic, due to the fact that you have to configure sequences of "jobs" containing the steps to configure and automate ZAP. In contrast to that has the secureCodeBox `zap-advanced` YAML format `zapConfiguration` a "declarative" semantic. The similarity of both YAML formats can help to migrate to the ZAP Automation Framework. - -::: - -```yaml -zapConfiguration: - # -- Optional general ZAP Configurations settings. - global: - # -- The ZAP internal Session name. Default: secureCodeBox - sessionName: secureCodeBox - # -- Updates all installed ZAP AddOns on startup if true, otherwise false. - addonUpdate: true - # -- Installs additional ZAP AddOns on startup, listed by their name: - addonInstall: - - pscanrulesBeta - - ascanrulesBeta - - pscanrulesAlpha - - ascanrulesAlpha - # -- An optional list of global regexes to include - includePaths: - - "https://example.com/.*" - # -- An optional list of global regexes to exclude - excludePaths: - # - "https://example.com/authserver/v1/.*" - - ".*\\.js" - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - # -- Configures a proxy for ZAP to tunnel the traffic somewhere else - proxy: - # -- Define if an outgoing proxy server is used. - enabled: false - # -- The proxy port to use - port: 8080 - # -- MANDATORY only if useProxyChain is True, ignored otherwise. Outgoing proxy address and port - address: my.corp.proxy - # -- Define the addresses to skip in case useProxyChain is True. Ignored otherwise. List can be empty. - skipProxyAddresses: - - "127.0.0.1" - - localhost - # -- MANDATORY only if proxy.enabled is True. Ignored otherwise. Define if proxy server needs authentication - authentication: - enabled: false - proxyUsername: "" - proxyPassword: "" - proxyRealm: "" - # -- Configures existings ZAP Scripts or add new ZAP Scripts. For example can be used if a proxy script must be loaded. Proxy scripts are executed for every request traversing ZAP - scripts: - - name: "Alert_on_HTTP_Response_Code_Errors.js" - # -- True if the script must be enabled, false otherwise - enabled: false - # -- The complete filepath (inside the ZAP Container!) to the script file. - filePath: "/home/zap/.ZAP_D/scripts/scripts/httpsender/Alert_on_HTTP_Response_Code_Errors.js" - # -- The script engine. Possible values are: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - engine: "Oracle Nashorn" - # -- The type of script engine used. Possible values are: 'httpsender', 'authentication', 'session', 'proxy', ... - type: "httpsender" - # -- A short description for the script. - description: "A HTTP Sender Script which will raise alerts based on HTTP Response codes." - - name: "Alert_on_Unexpected_Content_Types.js" - # -- True if the script must be enabled, false otherwise - enabled: false - # -- The complete filepath (inside the ZAP Container!) to the script file. - filePath: "/home/zap/.ZAP_D/scripts/scripts/httpsender/Alert_on_Unexpected_Content_Types.js" - # -- The type of script engine used. Possible values are: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - engine: "Oracle Nashorn" - # -- The type of the script. Possible values are: 'httpsender', 'authentication', 'session', 'proxy', ... - type: "httpsender" - # -- A short description for the script. - description: "A HTTP Sender Script which will raise alerts based on unexpected Content-Types." - - # -- Optional list of ZAP Context definitions - contexts: - # -- Name to be used to refer to this context in other jobs, mandatory - - name: scbcontext - # -- The top level URL - url: https://example.com/ - # -- An optional list of regexes to include in the ZAP context - includePaths: - - "https://example.com/.*" - # -- An optional list of regexes to exclude in the ZAP context - excludePaths: - # - "https://example.com/authserver/v1/.*" - - ".*\\.js" - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - # -- Optional technology list - technology: - # -- By default all technologies are enabed for each context by ZAP. You can use the following config to change that explicitly. - included: - - Db.CouchDB - - Db.Firebird - - Db.HypersonicSQL - - Language.ASP - - OS - # -- By default all technologies are enabed for each context by ZAP. You can use the following config to change that explicitly. - excluded: - - SCM - # -- Authentication Configuration that can be uses by ZAP Spider and/or Scanner. You need to reference the `context` name in the corresponding `zapConfiguration.spiders[0].context` and `zapConfiguration.scanners[0].context` section if you want to use them. - authentication: - # -- Currently supports "basic-auth", "form-based", "json-based", "script-based" - type: "script-based" - # -- Optional, only mandatory if zapConfiguration.contexts[0].authentication.type: "script-based". More ZAP details about 'script based' authentication can be found here: https://www.zaproxy.org/docs/api/#script-based-authentication. - script-based: - # -- The name of the authentication script - name: scb-oidc-password-grand-type.js - # -- Enables the script if true, otherwise false - enabled: true - # -- The type of script engine used. Possible values are: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - engine: "Oracle Nashorn" - # -- Must be a full path to the script file inside the ZAP container (corresponding to the configMap FileMount) - filePath: "/home/zap/.ZAP_D/scripts/scripts/authentication/scb-oidc-password-grand-type.js" - # -- A short description for the script. - description: "This is a description for the SCB OIDC Script." - # -- Optional list of all script arguments needed to be passed to the script. - arguments: - sub: "secureCodeBox@iteratec.com" - email: "secureCodeBox@teratec.com" - exp: "1609459140" - # -- Optional, only mandatory if zapConfiguration.contexts[0].authentication.type: "basic-auth". More ZAP details about 'basic auth' based authentication can be found here: https://www.zaproxy.org/docs/api/?python#general-steps. - basic-auth: - # -- The hostname that must be for the basic authentication - hostname: "https://example.com/" - # -- The realm that must be for the basic authentication - realm: "Realm" - # -- The port that must be for the basic authentication - port: 8080 - # -- Optional, only mandatory if zapConfiguration.contexts[0].authentication.type: "form-based". More ZAP details about 'form-based' based authentication can be found here: https://www.zaproxy.org/docs/api/#form-based-authentication. - form-based: - # -- The URL to the login form that must be used - loginUrl: "http://localhost:8090/bodgeit/login.jsp" - # -- The mapping of username and password to HTTP post parameters. Hint: the value must be escaped already to prevent YAML parser colidations. Example the intended value 'username={%username%}&password={%password%}' must be ''username%3D%7B%25username%25%7D%26password%3D%7B%25password%25%7D. - loginRequestData: "username%3D%7B%25username%25%7D%26password%3D%7B%25password%25%7D" - # -- Optional, only mandatory if zapConfiguration.contexts[0].authentication.type: "json-based". More ZAP details about 'json-based' based authentication can be found here: https://www.zaproxy.org/docs/api/#json-based-authentication. - json-based: - loginUrl: "http://localhost:3000/rest/user/login" - # must be escaped already to prevent yaml parser colidations '{"user":{"id":1,"email":"test@test.com"}}'' - loginRequestData: '{"user":{"id":1,"email":"test@test.com"}}' - # -- Indicates if the current Zap User Session is based on a valid authentication (loggedIn) or not (loggedOut) - verification: - # -- The optional ZAP indiator string for loggedIn Users - isLoggedInIndicator: "" - # -- The optional ZAP indiator string for loggedOut Users - isLoggedOutIndicator: "" - # -- A list of users with credentials which can be referenced by spider or scanner configurations to run them authenticated (you have to configure the authentiation settings). Hint: you can use secretMaps to seperate credentails. - users: - # -- The name of this user configuration - - name: test-user-1 - # -- The username used to authenticate this user - username: user1 - # -- The password used to authenticate this user - password: password1 - # -- Optional, could be set to True only once in the users list. If not defined the first user in the list will be forced by default. - forced: true - # -- The name of this user configuration - - name: test-user-2 - # -- The username used to authenticate this user - username: user2 - # -- The password used to authenticate this user - password: password2 - # -- The optional ZAP session configuration - session: - # -- The ZAP Session type indicates how Zap identifies sessions. Currently supports the following types: "scriptBasedSessionManagement", "cookieBasedSessionManagement", "httpAuthSessionManagement" - type: "scriptBasedSessionManagement" - # -- Optional, only mandatory if zapConfiguration.contexts[0].session.type: "scriptBasedSessionManagement". Additional configrations for the session type "scriptBasedSessionManagement" - scriptBasedSessionManagement: - # -- The name of the session script to be used. - name: "juiceshop-session-management.js" - # -- Enables the script if true, otherwise false - enabled: true - # -- The type of script engine used. Possible values are: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - engine: "Oracle Nashorn" - # -- Must be a full path to the script file inside the ZAP container (corresponding to the configMap FileMount) - fileName: "/home/zap/.ZAP_D/scripts/scripts/session/juiceshop-session-management.js" - # -- An optional description used for the script. - description: "This is a JuiceShop specific SessionManagement Script used to handle JWT." - - # -- Optional list of ZAP OpenAPI configurations - apis: - # -- The name of the api configuration - - name: scb-petstore-api - # -- The Name of the context (zapConfiguration.contexts[x].name) to reference, default: the first context available - context: scb-petstore-context - # -- The used format of the API. Possible values are: 'openapi', 'grapql', 'soap' - format: openapi - # -- Url to start importing the API from, default: first context URL - url: http://localhost:8000/v2/swagger.json - # -- Optional: Override host setting in the API (e.g. swagger.json) if your API is using some kind of internal routing. - hostOverride: http://localhost:8000 - # -- Optional: Assumes that the API Spec has been saved to a configmap in the namespace of the scan / this release. Should be null if not used. - configMap: - # Object with two keys: "name" name of the config map, and "key" which is the key / property in the configmap which holds the openapi spec file. - name: my-configmap-with-openapi-spec - key: openapi.yaml - # -- Allows to embed the entire yaml / json API spec in the values (e.g. OpenAPI YAML spec). Should be null if not used. - spec: null - # -- Configures existings ZAP Scripts or add new ZAP Scripts. For example can be used if a proxy script must be loaded. Proxy scripts are executed for every request traversing ZAP - scripts: - - name: "Alert_on_HTTP_Response_Code_Errors.js" - # -- True if the script must be enabled, false otherwise - enabled: true - - name: "Alert_on_Unexpected_Content_Types.js" - # -- True if the script must be enabled, false otherwise - enabled: true - - # -- Optional list of ZAP Spider configurations - spiders: - # -- String: The name of the spider configuration - - name: scbspider - # -- String: The Name of the context (zapConfiguration.contexts[x].name) to spider, default: first context available - context: scbcontext - # -- String: The Name of the user (zapConfiguration.contexts[0].users[0].name) used to authenticate the spider with - user: "test-user-1" - # -- String: Url to start spidering from, default: first context URL - url: https://example.com/ - # -- Bool: Whether to use the ZAP ajax spider, default: false - ajax: false - # -- Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # -- Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # -- Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 0 - # -- Int: The maximum tree depth to explore, default 5 - maxDepth: 5 - # -- Int: The maximum number of children to add to each node in the tree - maxChildren: 10 - # -- Bool: Whether the spider will accept cookies, default: true - acceptCookies: true - # -- Bool: Whether the spider will handle OData responses, default: false - handleODataParametersVisited: false - # -- Enum [ignore_completely, ignore_value, use_all]: How query string parameters are used when checking if a URI has already been visited, default: use_all - handleParameters: use_all - # -- Int: The max size of a response that will be parsed, default: 2621440 - 2.5 Mb - maxParseSizeBytes: 2621440 - # -- Bool: Whether the spider will parse HTML comments in order to find URLs, default: true - parseComments: true - # Bool: Whether the spider will parse Git metadata in order to find URLs, default: false - parseGit: false - # -- Bool: Whether the spider will parse 'robots.txt' files in order to find URLs, default: true - parseRobotsTxt: true - # -- Bool: Whether the spider will parse 'sitemap.xml' files in order to find URLs, default: true - parseSitemapXml: true - # -- Bool: Whether the spider will parse SVN metadata in order to find URLs, default: false - parseSVNEntries: false - # -- Bool: Whether the spider will submit POST forms, default: true - postForm: true - # -- Bool: Whether the spider will process forms, default: true - processForm: true - # -- Int: The time between the requests sent to a server in milliseconds, default: 200 - requestWaitTime: 200 - # -- Bool: Whether the spider will send the referer header, default: true - sendRefererHeader: true - # -- Int: The number of spider threads, default: 2 - threadCount: 2 - # -- String: The user agent to use in requests, default: '' - use the default ZAP one - userAgent: "secureCodeBox / ZAP Spider" - # -- Configures existings ZAP Scripts or add new ZAP Scripts. For example can be used if a proxy script must be loaded. Proxy scripts are executed for every request traversing ZAP - scripts: {} - - # -- Optional list of ZAP Active Scanner configurations - scanners: - # -- String: Name of the context to attack, default: first context - - name: scbscan - # -- String: Name of the context to attack, default: first context - context: scbcontext - # -- String: Url to start scaning from, default: first context URL - url: https://example.com/ - # -- String: The name of the default scan policy to use, default: Default Policy - defaultPolicy: "Default Policy" - # -- String: Name of the scan policy to be used, default: Default Policy - policy: "Default Policy" - # -- Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 0 - # -- Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 0 - # -- Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # -- Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # -- Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # -- Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # -- Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false - # -- Int: The max number of threads per host, default: 2 - threadPerHost: 2 - # -- The policy definition, only used if the 'policy' is not set - NOT YET IMPLEMENTED - policyDefinition: - # -- String: The default Attack Strength for all rules, one of Low, Medium, High, Insane (not recommended), default: Medium - defaultStrength: Medium - # -- String: The default Alert Threshold for all rules, one of Off, Low, Medium, High, default: Medium - defaultThreshold: Medium - # -- A list of one or more active scan rules and associated settings which override the defaults - rules: - # -- Int: The rule id as per https://www.zaproxy.org/docs/alerts/ - - id: 10106 - # -- The name of the rule for documentation purposes - this is not required or actually used - name: "rule" - # -- String: The Attack Strength for this rule, one of Low, Medium, High, Insane, default: Medium - strength: Medium - # -- String: The Alert Threshold for this rule, one of Off, Low, Medium, High, default: Medium - threshold: Low - # -- Configures existings ZAP Scripts or add new ZAP Scripts. For example can be used if a proxy script must be loaded. Proxy scripts are executed for every request traversing ZAP - scripts: {} -``` - -## Values - -| Key | Type | Default | Description | -|-----|------|---------|-------------| -| cascadingRules.enabled | bool | `false` | Enables or disables the installation of the default cascading rules for this scanner | -| imagePullSecrets | list | `[]` | Define imagePullSecrets when a private registry is used (see: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) | -| parser.affinity | object | `{}` | Optional affinity settings that control how the parser job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) | -| parser.env | list | `[]` | Optional environment variables mapped into each parseJob (see: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) | -| parser.image.pullPolicy | string | `"IfNotPresent"` | Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images | -| parser.image.repository | string | `"docker.io/securecodebox/parser-zap"` | Parser image repository | -| parser.image.tag | string | defaults to the charts version | Parser image tag | -| parser.nodeSelector | object | `{}` | Optional nodeSelector settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/) | -| parser.resources | object | `{ requests: { cpu: "200m", memory: "100Mi" }, limits: { cpu: "400m", memory: "200Mi" } }` | Optional resources lets you control resource limits and requests for the parser container. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | -| parser.scopeLimiterAliases | object | `{}` | Optional finding aliases to be used in the scopeLimiter. | -| parser.tolerations | list | `[]` | Optional tolerations settings that control how the parser job is scheduled (see: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) | -| parser.ttlSecondsAfterFinished | string | `nil` | seconds after which the Kubernetes job for the parser will be deleted. Requires the Kubernetes TTLAfterFinished controller: https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/ | -| scanner.activeDeadlineSeconds | string | `nil` | There are situations where you want to fail a scan Job after some amount of time. To do so, set activeDeadlineSeconds to define an active deadline (in seconds) when considering a scan Job as failed. (see: https://kubernetes.io/docs/concepts/workloads/controllers/job/#job-termination-and-cleanup) | -| scanner.affinity | object | `{}` | Optional affinity settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) | -| scanner.backoffLimit | int | 3 | There are situations where you want to fail a scan Job after some amount of retries due to a logical error in configuration etc. To do so, set backoffLimit to specify the number of retries before considering a scan Job as failed. (see: https://kubernetes.io/docs/concepts/workloads/controllers/job/#pod-backoff-failure-policy) | -| scanner.env | list | `[]` | Optional environment variables mapped into each scanJob (see: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) | -| scanner.envFrom | list | `[]` | Optional mount environment variables from configMaps or secrets (see: https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/#configure-all-key-value-pairs-in-a-secret-as-container-environment-variables) | -| scanner.extraContainers | list | `[]` | Optional additional Containers started with each scanJob (see: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/) | -| scanner.extraVolumeMounts | list | `[{"mountPath":"/home/securecodebox/configs/1-zap-advanced-scantype.yaml","name":"zap-advanced-scantype-config","readOnly":true,"subPath":"1-zap-advanced-scantype.yaml"}]` | Optional VolumeMounts mapped into each scanJob (see: https://kubernetes.io/docs/concepts/storage/volumes/) | -| scanner.extraVolumes | list | `[{"configMap":{"name":"zap-advanced-scantype-config","optional":true},"name":"zap-advanced-scantype-config"},{"configMap":{"name":"zap-scripts-authentication"},"name":"zap-scripts-authentication"},{"configMap":{"name":"zap-scripts-session"},"name":"zap-scripts-session"}]` | Optional Volumes mapped into each scanJob (see: https://kubernetes.io/docs/concepts/storage/volumes/) | -| scanner.image.pullPolicy | string | `"IfNotPresent"` | Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images | -| scanner.image.repository | string | `"docker.io/securecodebox/scanner-zap-advanced"` | Container Image to run the scan | -| scanner.image.tag | string | `nil` | defaults to the charts version | -| scanner.nameAppend | string | `nil` | append a string to the default scantype name. | -| scanner.nodeSelector | object | `{}` | Optional nodeSelector settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/) | -| scanner.podSecurityContext | object | `{}` | Optional securityContext set on scanner pod (see: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) | -| scanner.reportType | string | "XML" | Optional to configure the reportType of the scan ZAP Scan. Must be one of the supported formats: XML,XML-plus,JSON,JSON-plus,HTML,HTML-plus,MD | -| scanner.resources | object | `{}` | CPU/memory resource requests/limits (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/, https://kubernetes.io/docs/tasks/configure-pod-container/assign-cpu-resource/) | -| scanner.securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["all"]},"privileged":false,"readOnlyRootFilesystem":false,"runAsNonRoot":false}` | Optional securityContext set on scanner container (see: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) | -| scanner.securityContext.allowPrivilegeEscalation | bool | `false` | Ensure that users privileges cannot be escalated | -| scanner.securityContext.capabilities.drop[0] | string | `"all"` | This drops all linux privileges from the container. | -| scanner.securityContext.privileged | bool | `false` | Ensures that the scanner container is not run in privileged mode | -| scanner.securityContext.readOnlyRootFilesystem | bool | `false` | Prevents write access to the containers file system | -| scanner.securityContext.runAsNonRoot | bool | `false` | Enforces that the scanner image is run as a non root user | -| scanner.suspend | bool | `false` | if set to true the scan job will be suspended after creation. You can then resume the job using `kubectl resume ` or using a job scheduler like kueue | -| scanner.tolerations | list | `[]` | Optional tolerations settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) | -| scanner.ttlSecondsAfterFinished | string | `nil` | seconds after which the Kubernetes job for the scanner will be deleted. Requires the Kubernetes TTLAfterFinished controller: https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/ | -| zapConfiguration | object | `{}` | All `scanType` specific configuration options. Feel free to add more configuration options. All configuration options can be overridden by scan specific configurations if defined. Please have a look into the README.md to find more configuration options. | -| zapContainer.env | list | `[]` | Optional environment variables mapped into each scanJob (see: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) | -| zapContainer.envFrom | list | `[]` | Optional mount environment variables from configMaps or secrets (see: https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/#configure-all-key-value-pairs-in-a-secret-as-container-environment-variables) | -| zapContainer.extraVolumeMounts | list | `[{"mountPath":"/home/zap/.ZAP_D/scripts/scripts/authentication/","name":"zap-scripts-authentication","readOnly":true},{"mountPath":"/home/zap/.ZAP_D/scripts/scripts/session/","name":"zap-scripts-session","readOnly":true}]` | Optional VolumeMounts mapped into each scanJob (see: https://kubernetes.io/docs/concepts/storage/volumes/) | -| zapContainer.image.pullPolicy | string | `"IfNotPresent"` | Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images | -| zapContainer.image.repository | string | `"docker.io/zaproxy/zap-stable"` | Container Image to run the scan | -| zapContainer.image.tag | string | `nil` | defaults to the charts appVersion | -| zapContainer.resources | object | `{}` | CPU/memory resource requests/limits (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/, https://kubernetes.io/docs/tasks/configure-pod-container/assign-cpu-resource/) | -| zapContainer.securityContext.allowPrivilegeEscalation | bool | `false` | | -| zapContainer.securityContext.capabilities.drop[0] | string | `"all"` | | -| zapContainer.securityContext.privileged | bool | `false` | | -| zapContainer.securityContext.readOnlyRootFilesystem | bool | `false` | | -| zapContainer.securityContext.runAsNonRoot | bool | `false` | | - -## License -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) - -Code of secureCodeBox is licensed under the [Apache License 2.0][scb-license]. - -[scb-owasp]: https://www.owasp.org/index.php/OWASP_secureCodeBox -[scb-docs]: https://www.securecodebox.io/ -[scb-site]: https://www.securecodebox.io/ -[scb-github]: https://github.com/secureCodeBox/ -[scb-mastodon]: https://infosec.exchange/@secureCodeBox -[scb-slack]: https://owasp.org/slack/invite -[scb-license]: https://github.com/secureCodeBox/secureCodeBox/blob/master/LICENSE -[zap github]: https://github.com/zaproxy/zaproxy/ -[zap user guide]: https://www.zaproxy.org/docs/ diff --git a/scanners/zap-advanced/cascading-rules/http.yaml b/scanners/zap-advanced/cascading-rules/http.yaml deleted file mode 100644 index 756587ed36..0000000000 --- a/scanners/zap-advanced/cascading-rules/http.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -apiVersion: "cascading.securecodebox.io/v1" -kind: CascadingRule -metadata: - name: "zap-advanced-http" - labels: - securecodebox.io/invasive: non-invasive - securecodebox.io/intensive: medium -spec: - matches: - anyOf: - - category: "Open Port" - attributes: - service: http - state: open - - category: "Open Port" - attributes: - service: "http-*" - state: open - scanSpec: - scanType: "zap-advanced-scan" - parameters: ["-t", "http://{{$.hostOrIP}}:{{attributes.port}}"] diff --git a/scanners/zap-advanced/cascading-rules/https.yaml b/scanners/zap-advanced/cascading-rules/https.yaml deleted file mode 100644 index a07f39ce5a..0000000000 --- a/scanners/zap-advanced/cascading-rules/https.yaml +++ /dev/null @@ -1,21 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -apiVersion: "cascading.securecodebox.io/v1" -kind: CascadingRule -metadata: - name: "zap-advanced-https" - labels: - securecodebox.io/invasive: non-invasive - securecodebox.io/intensive: medium -spec: - matches: - anyOf: - - category: "Open Port" - attributes: - service: "https*" - state: open - scanSpec: - scanType: "zap-advanced-scan" - parameters: ["-t", "https://{{$.hostOrIP}}:{{attributes.port}}"] diff --git a/scanners/zap-advanced/docs/README.ArtifactHub.md b/scanners/zap-advanced/docs/README.ArtifactHub.md deleted file mode 100644 index e625ee9a78..0000000000 --- a/scanners/zap-advanced/docs/README.ArtifactHub.md +++ /dev/null @@ -1,569 +0,0 @@ - - - -

- License Apache-2.0 - GitHub release (latest SemVer) - OWASP Lab Project - Artifact HUB - GitHub Repo stars - Mastodon Follower -

- -## What is OWASP secureCodeBox? - -

- secureCodeBox Logo -

- -_[OWASP secureCodeBox][scb-github]_ is an automated and scalable open source solution that can be used to integrate various *security vulnerability scanners* with a simple and lightweight interface. The _secureCodeBox_ mission is to support *DevSecOps* Teams to make it easy to automate security vulnerability testing in different scenarios. - -With the _secureCodeBox_ we provide a toolchain for continuous scanning of applications to find the low-hanging fruit issues early in the development process and free the resources of the penetration tester to concentrate on the major security issues. - -The secureCodeBox project is running on [Kubernetes](https://kubernetes.io/). To install it you need [Helm](https://helm.sh), a package manager for Kubernetes. It is also possible to start the different integrated security vulnerability scanners based on a docker infrastructure. - -### Quickstart with secureCodeBox on Kubernetes - -You can find resources to help you get started on our [documentation website](https://www.securecodebox.io) including instruction on how to [install the secureCodeBox project](https://www.securecodebox.io/docs/getting-started/installation) and guides to help you [run your first scans](https://www.securecodebox.io/docs/getting-started/first-scans) with it. - -## What is ZAP? -:::caution Deprecation Notice -The `zap-advanced` and `zap` ScanType are being deprecated in favor of the `zap-automation-framework`, which encompasses all functionalities of the previous ScanTypes. We recommend transitioning to the "zap-automation-framework" as soon as possible. `zap-advanced` and `zap` ScanTypes will be removed in the upcoming v5 release. For guidance on migrating to "zap-automation-framework," please refer to [migration to zap-automation framework](/docs/scanners/zap-automation-framework#migration-to-zap-automation-framework). -::: - -The Zed Attack Proxy (ZAP) is one of the world’s most popular free security tools and is actively maintained by hundreds of international volunteers*. It can help you automatically find security vulnerabilities in your web applications while you are developing and testing your applications. It's also a great tool for experienced pentesters to use for manual security testing. - -To learn more about the ZAP scanner itself visit [https://www.zaproxy.org/](https://www.zaproxy.org/). - -## Deployment -The zap-advanced chart can be deployed via helm: - -```bash -# Install HelmChart (use -n to configure another namespace) -helm upgrade --install zap-advanced oci://ghcr.io/securecodebox/helm/zap-advanced -``` - -## Scanner Configuration - -Listed below are the arguments supported by the `zap-advanced-scan` script. - -The command line interface can be used to easily run server scans: `-t www.example.com` - -```bash -usage: zap-client [-h] -z ZAP_URL [-a API_KEY] [-c CONFIG_FOLDER] -t TARGET [-o OUTPUT_FOLDER] [-r XML,XML-plus,JSON,JSON-plus,HTML,HTML-plus,MD] - -OWASP secureCodeBox ZAP Client (can be used to automate ZAP instances based on YAML configuration files.) - -optional arguments: - -h, --help show this help message and exit - -z ZAP_URL, --zap-url ZAP_URL - The ZAP API Url used to call the ZAP API. - -a API_KEY, --api-key API_KEY - The ZAP API Key used to call the ZAP API. - -c CONFIG_FOLDER, --config-folder CONFIG_FOLDER - The path to a local folder containing the additional ZAP configuration YAMLs used to configure ZAP. - -t TARGET, --target TARGET - The target to scan with ZAP. - -o OUTPUT_FOLDER, --output-folder OUTPUT_FOLDER - The path to a local folder used to store the output files, eg. the ZAP Report or logfiles. - -r XML,XML-plus,JSON,JSON-plus,HTML,HTML-plus,MD, --report-type XML,XML-plus,JSON,JSON-plus,HTML,HTML-plus,MD - The ZAP Report Type. -``` - -## Requirements - -Kubernetes: `>=v1.11.0-0` - -## Additional Chart Configurations - -By default, the secureCodeBox ZAP Helm Chart installs the scanType `zap-advanced-scan` along with a minimal _default configuration_ based on the HelmChart value `zapConfiguration`. The configuration will be stored in a dedicate scanType specific _configMap_ named `zap-advanced-scantype-config`. Feel free to use the `configMap` or even the HelmChart values to adjust the advanced ZAP configuration settings according to your needs. Details about the different configuration options can be found below. - -Additionally, there will be some ZAP Scripts included, these are stored in the corresponding configMaps `zap-scripts-authentication` and `zap-scripts-session`. Scripts can be used to implement a specific behavior or even new authentication patterns, which are not supported by ZAP out of the box. Feel free to add additional scripts in your own, if you need them. - -```bash - ┌────────────────────────────────────────┐ -┌──────────────────────────────────────┐ │A YAML configuration file for ZAP that │ -│This CM contains ZAP authentication │ │relates to the scanType directly. │ -│scripts that are already included │ │- will be used for all scans by default │ -│within the zap-advanced scanner. │ │- can be configured via Helm Values: │ -│Feel free to add your own. │────────┐ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ┌───────│ zapConfiguration │ -│ │ │ │ │- add your baseline config here │ -│ConfigMap: zap-scripts-authentication │ │ │ ┌───────────────────┐ │ │ │ │ -└──────────────────────────────────────┘ │ │ │ │ │ConfigMap: zap-advanced-scantype-config │ - │ │ │ ZAP Client │ │ │ └────────────────────────────────────────┘ - All scripts are mounted as files │ │ Python3 Module │◀─────┤ - directly into the ZAP container. To use │ │ │ │ │ │ All referenced YAML files will be merged into - them add a corresponding script section │ └───────────────────┘ │ one single YAML configuration. The merged one - in your config YAML. │ │ │ │ │ will be used to configure the ZAP instance. - │ uses API │ -┌──────────────────────────────────────┐ │ │ │ │ │ ┌────────────────────────────────────────┐ -│This CM contains ZAP session │ │ ▼ │ │A YAML configuration for ZAP that │ -│scripts that are already included │ │ │ ┌───────────────────┐ │ │ │relates to a single scan execution. │ -│within the zap-advanced scanner. │ │ │ │ │ │- can by used for selected scans │ -│Feel free to add your own. │────────┼─────┼─▶│ ZAP Proxy │ │ │- not created by default │ -│ │ │ │ │ └───────│- add your scan target specific config │ -│ConfigMap: zap-scripts-session │ │ │ └───────────────────┘ │ │- needs to be referenced in Scan │ -└──────────────────────────────────────┘ │ │- please use SecretMap for credentials! │ -┌──────────────────────────────────────┐ │ │ secureCodeBox scanner │ │ │ -│Feel free to add your own scripts :) │ │ scanType: zap-advanced │ConfigMap: zap-advanced-scan-config │ -│ │────────┘ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ └────────────────────────────────────────┘ -│ConfigMap: zap-scripts-your-name │ -└──────────────────────────────────────┘ - -``` - -The following picture outlines the reference concept of the ZAP YAML configuration `zapConfiguration`. If you want to configure an `api` scan, `spider` or active `scan` you must at least add one `context` item with a `name` and `url` configured. The context `url` must match the target url used in the `Scan` execution: - -```yaml -spec: - scanType: "zap-advanced-scan" - parameters: - # target URL must match with `context.url` to identify the corresponding configurations. - - "-t" - - "http://bodgeit.default.svc:8080/bodgeit/" -``` - -If you want to configure the `api` scan, `spider` or active `scan` section it is mandatory to add the `context: ` reference the section. Otherwise it is not possible to identify which configuration must be used for a scan. The `url` in the `api` , `spider` or active 'scan` section can be different to the context.url (and scan target url). - -```bash -┌────────────────────────────────────────────────────────────────┐ -│ ZAP Configuration YAML - reference by "context name" │ -└────────────────────────────────────────────────────────────────┘ - -┌────────────────┐ ┌────────────────┐ -│ Context │ │ Context │ -│ - name: ABC │◀───┬─┬─┐ │ - name: XYZ │◀───┬─┬─┐ -│ url: ... │ │ │ │ │ url: ... │ │ │ │ -└────────────────┘ │ │ │ └────────────────┘ │ │ │ - ┌─────────────────┐ │ │ │ ┌─────────────────┐ │ │ │ - │ API: │ │ │ │ │ API: │ │ │ │ - │ - context: ABC │──┘ │ │ │ - context: XYZ │──┘ │ │ - │ - ... │ │ │ │ - ... │ │ │ - └─────────────────┘ │ │ └─────────────────┘ │ │ - ┌─────────────────┐ │ │ ┌─────────────────┐ │ │ - │ Spider: │ │ │ │ Spider: │ │ │ - │ - context: ABC │──┘ │ │ - context: XYZ │──┘ │ - │ - ... │ │ │ - ... │ │ - └─────────────────┘ │ └─────────────────┘ │ - ┌─────────────────┐ │ ┌─────────────────┐ │ - │ Scanner: │ │ │ Scanner: │ │ - │ - context: ABC │──┘ │ - context: XYZ │──┘ - │ - ... │ │ - ... │ - └─────────────────┘ └─────────────────┘ - -``` - -## ZAP Configuration -The following YAMl gives you an overview about all the different configuration options you have to configure the ZAP advanced scan. Please have a look into our `./examples/...` to find some working examples. We provide a list of working examples to scan our `demo-targets` with the `zap-advanced-scan`. - -:::note - -The YAML format is based on the new [ZAP Automation Framework](https://www.zaproxy.org/docs/desktop/addons/automation-framework/) but not exactly the same. The ZAP Automation Framework is a new approach of the ZAP Team to ease up the automation possibilities of the ZAP scanner itself. Since this ZAP Automation Framework is not ready yet we are not using it for now. We track the progress in this [issue #321](https://github.com/secureCodeBox/secureCodeBox/issues/321) for the future. - -The ZAP Automation format represents a more "imperative" semantic, due to the fact that you have to configure sequences of "jobs" containing the steps to configure and automate ZAP. In contrast to that has the secureCodeBox `zap-advanced` YAML format `zapConfiguration` a "declarative" semantic. The similarity of both YAML formats can help to migrate to the ZAP Automation Framework. - -::: - -```yaml -zapConfiguration: - # -- Optional general ZAP Configurations settings. - global: - # -- The ZAP internal Session name. Default: secureCodeBox - sessionName: secureCodeBox - # -- Updates all installed ZAP AddOns on startup if true, otherwise false. - addonUpdate: true - # -- Installs additional ZAP AddOns on startup, listed by their name: - addonInstall: - - pscanrulesBeta - - ascanrulesBeta - - pscanrulesAlpha - - ascanrulesAlpha - # -- An optional list of global regexes to include - includePaths: - - "https://example.com/.*" - # -- An optional list of global regexes to exclude - excludePaths: - # - "https://example.com/authserver/v1/.*" - - ".*\\.js" - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - # -- Configures a proxy for ZAP to tunnel the traffic somewhere else - proxy: - # -- Define if an outgoing proxy server is used. - enabled: false - # -- The proxy port to use - port: 8080 - # -- MANDATORY only if useProxyChain is True, ignored otherwise. Outgoing proxy address and port - address: my.corp.proxy - # -- Define the addresses to skip in case useProxyChain is True. Ignored otherwise. List can be empty. - skipProxyAddresses: - - "127.0.0.1" - - localhost - # -- MANDATORY only if proxy.enabled is True. Ignored otherwise. Define if proxy server needs authentication - authentication: - enabled: false - proxyUsername: "" - proxyPassword: "" - proxyRealm: "" - # -- Configures existings ZAP Scripts or add new ZAP Scripts. For example can be used if a proxy script must be loaded. Proxy scripts are executed for every request traversing ZAP - scripts: - - name: "Alert_on_HTTP_Response_Code_Errors.js" - # -- True if the script must be enabled, false otherwise - enabled: false - # -- The complete filepath (inside the ZAP Container!) to the script file. - filePath: "/home/zap/.ZAP_D/scripts/scripts/httpsender/Alert_on_HTTP_Response_Code_Errors.js" - # -- The script engine. Possible values are: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - engine: "Oracle Nashorn" - # -- The type of script engine used. Possible values are: 'httpsender', 'authentication', 'session', 'proxy', ... - type: "httpsender" - # -- A short description for the script. - description: "A HTTP Sender Script which will raise alerts based on HTTP Response codes." - - name: "Alert_on_Unexpected_Content_Types.js" - # -- True if the script must be enabled, false otherwise - enabled: false - # -- The complete filepath (inside the ZAP Container!) to the script file. - filePath: "/home/zap/.ZAP_D/scripts/scripts/httpsender/Alert_on_Unexpected_Content_Types.js" - # -- The type of script engine used. Possible values are: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - engine: "Oracle Nashorn" - # -- The type of the script. Possible values are: 'httpsender', 'authentication', 'session', 'proxy', ... - type: "httpsender" - # -- A short description for the script. - description: "A HTTP Sender Script which will raise alerts based on unexpected Content-Types." - - # -- Optional list of ZAP Context definitions - contexts: - # -- Name to be used to refer to this context in other jobs, mandatory - - name: scbcontext - # -- The top level URL - url: https://example.com/ - # -- An optional list of regexes to include in the ZAP context - includePaths: - - "https://example.com/.*" - # -- An optional list of regexes to exclude in the ZAP context - excludePaths: - # - "https://example.com/authserver/v1/.*" - - ".*\\.js" - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - # -- Optional technology list - technology: - # -- By default all technologies are enabed for each context by ZAP. You can use the following config to change that explicitly. - included: - - Db.CouchDB - - Db.Firebird - - Db.HypersonicSQL - - Language.ASP - - OS - # -- By default all technologies are enabed for each context by ZAP. You can use the following config to change that explicitly. - excluded: - - SCM - # -- Authentication Configuration that can be uses by ZAP Spider and/or Scanner. You need to reference the `context` name in the corresponding `zapConfiguration.spiders[0].context` and `zapConfiguration.scanners[0].context` section if you want to use them. - authentication: - # -- Currently supports "basic-auth", "form-based", "json-based", "script-based" - type: "script-based" - # -- Optional, only mandatory if zapConfiguration.contexts[0].authentication.type: "script-based". More ZAP details about 'script based' authentication can be found here: https://www.zaproxy.org/docs/api/#script-based-authentication. - script-based: - # -- The name of the authentication script - name: scb-oidc-password-grand-type.js - # -- Enables the script if true, otherwise false - enabled: true - # -- The type of script engine used. Possible values are: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - engine: "Oracle Nashorn" - # -- Must be a full path to the script file inside the ZAP container (corresponding to the configMap FileMount) - filePath: "/home/zap/.ZAP_D/scripts/scripts/authentication/scb-oidc-password-grand-type.js" - # -- A short description for the script. - description: "This is a description for the SCB OIDC Script." - # -- Optional list of all script arguments needed to be passed to the script. - arguments: - sub: "secureCodeBox@iteratec.com" - email: "secureCodeBox@teratec.com" - exp: "1609459140" - # -- Optional, only mandatory if zapConfiguration.contexts[0].authentication.type: "basic-auth". More ZAP details about 'basic auth' based authentication can be found here: https://www.zaproxy.org/docs/api/?python#general-steps. - basic-auth: - # -- The hostname that must be for the basic authentication - hostname: "https://example.com/" - # -- The realm that must be for the basic authentication - realm: "Realm" - # -- The port that must be for the basic authentication - port: 8080 - # -- Optional, only mandatory if zapConfiguration.contexts[0].authentication.type: "form-based". More ZAP details about 'form-based' based authentication can be found here: https://www.zaproxy.org/docs/api/#form-based-authentication. - form-based: - # -- The URL to the login form that must be used - loginUrl: "http://localhost:8090/bodgeit/login.jsp" - # -- The mapping of username and password to HTTP post parameters. Hint: the value must be escaped already to prevent YAML parser colidations. Example the intended value 'username={%username%}&password={%password%}' must be ''username%3D%7B%25username%25%7D%26password%3D%7B%25password%25%7D. - loginRequestData: "username%3D%7B%25username%25%7D%26password%3D%7B%25password%25%7D" - # -- Optional, only mandatory if zapConfiguration.contexts[0].authentication.type: "json-based". More ZAP details about 'json-based' based authentication can be found here: https://www.zaproxy.org/docs/api/#json-based-authentication. - json-based: - loginUrl: "http://localhost:3000/rest/user/login" - # must be escaped already to prevent yaml parser colidations '{"user":{"id":1,"email":"test@test.com"}}'' - loginRequestData: '{"user":{"id":1,"email":"test@test.com"}}' - # -- Indicates if the current Zap User Session is based on a valid authentication (loggedIn) or not (loggedOut) - verification: - # -- The optional ZAP indiator string for loggedIn Users - isLoggedInIndicator: "" - # -- The optional ZAP indiator string for loggedOut Users - isLoggedOutIndicator: "" - # -- A list of users with credentials which can be referenced by spider or scanner configurations to run them authenticated (you have to configure the authentiation settings). Hint: you can use secretMaps to seperate credentails. - users: - # -- The name of this user configuration - - name: test-user-1 - # -- The username used to authenticate this user - username: user1 - # -- The password used to authenticate this user - password: password1 - # -- Optional, could be set to True only once in the users list. If not defined the first user in the list will be forced by default. - forced: true - # -- The name of this user configuration - - name: test-user-2 - # -- The username used to authenticate this user - username: user2 - # -- The password used to authenticate this user - password: password2 - # -- The optional ZAP session configuration - session: - # -- The ZAP Session type indicates how Zap identifies sessions. Currently supports the following types: "scriptBasedSessionManagement", "cookieBasedSessionManagement", "httpAuthSessionManagement" - type: "scriptBasedSessionManagement" - # -- Optional, only mandatory if zapConfiguration.contexts[0].session.type: "scriptBasedSessionManagement". Additional configrations for the session type "scriptBasedSessionManagement" - scriptBasedSessionManagement: - # -- The name of the session script to be used. - name: "juiceshop-session-management.js" - # -- Enables the script if true, otherwise false - enabled: true - # -- The type of script engine used. Possible values are: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - engine: "Oracle Nashorn" - # -- Must be a full path to the script file inside the ZAP container (corresponding to the configMap FileMount) - fileName: "/home/zap/.ZAP_D/scripts/scripts/session/juiceshop-session-management.js" - # -- An optional description used for the script. - description: "This is a JuiceShop specific SessionManagement Script used to handle JWT." - - # -- Optional list of ZAP OpenAPI configurations - apis: - # -- The name of the api configuration - - name: scb-petstore-api - # -- The Name of the context (zapConfiguration.contexts[x].name) to reference, default: the first context available - context: scb-petstore-context - # -- The used format of the API. Possible values are: 'openapi', 'grapql', 'soap' - format: openapi - # -- Url to start importing the API from, default: first context URL - url: http://localhost:8000/v2/swagger.json - # -- Optional: Override host setting in the API (e.g. swagger.json) if your API is using some kind of internal routing. - hostOverride: http://localhost:8000 - # -- Optional: Assumes that the API Spec has been saved to a configmap in the namespace of the scan / this release. Should be null if not used. - configMap: - # Object with two keys: "name" name of the config map, and "key" which is the key / property in the configmap which holds the openapi spec file. - name: my-configmap-with-openapi-spec - key: openapi.yaml - # -- Allows to embed the entire yaml / json API spec in the values (e.g. OpenAPI YAML spec). Should be null if not used. - spec: null - # -- Configures existings ZAP Scripts or add new ZAP Scripts. For example can be used if a proxy script must be loaded. Proxy scripts are executed for every request traversing ZAP - scripts: - - name: "Alert_on_HTTP_Response_Code_Errors.js" - # -- True if the script must be enabled, false otherwise - enabled: true - - name: "Alert_on_Unexpected_Content_Types.js" - # -- True if the script must be enabled, false otherwise - enabled: true - - # -- Optional list of ZAP Spider configurations - spiders: - # -- String: The name of the spider configuration - - name: scbspider - # -- String: The Name of the context (zapConfiguration.contexts[x].name) to spider, default: first context available - context: scbcontext - # -- String: The Name of the user (zapConfiguration.contexts[0].users[0].name) used to authenticate the spider with - user: "test-user-1" - # -- String: Url to start spidering from, default: first context URL - url: https://example.com/ - # -- Bool: Whether to use the ZAP ajax spider, default: false - ajax: false - # -- Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # -- Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # -- Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 0 - # -- Int: The maximum tree depth to explore, default 5 - maxDepth: 5 - # -- Int: The maximum number of children to add to each node in the tree - maxChildren: 10 - # -- Bool: Whether the spider will accept cookies, default: true - acceptCookies: true - # -- Bool: Whether the spider will handle OData responses, default: false - handleODataParametersVisited: false - # -- Enum [ignore_completely, ignore_value, use_all]: How query string parameters are used when checking if a URI has already been visited, default: use_all - handleParameters: use_all - # -- Int: The max size of a response that will be parsed, default: 2621440 - 2.5 Mb - maxParseSizeBytes: 2621440 - # -- Bool: Whether the spider will parse HTML comments in order to find URLs, default: true - parseComments: true - # Bool: Whether the spider will parse Git metadata in order to find URLs, default: false - parseGit: false - # -- Bool: Whether the spider will parse 'robots.txt' files in order to find URLs, default: true - parseRobotsTxt: true - # -- Bool: Whether the spider will parse 'sitemap.xml' files in order to find URLs, default: true - parseSitemapXml: true - # -- Bool: Whether the spider will parse SVN metadata in order to find URLs, default: false - parseSVNEntries: false - # -- Bool: Whether the spider will submit POST forms, default: true - postForm: true - # -- Bool: Whether the spider will process forms, default: true - processForm: true - # -- Int: The time between the requests sent to a server in milliseconds, default: 200 - requestWaitTime: 200 - # -- Bool: Whether the spider will send the referer header, default: true - sendRefererHeader: true - # -- Int: The number of spider threads, default: 2 - threadCount: 2 - # -- String: The user agent to use in requests, default: '' - use the default ZAP one - userAgent: "secureCodeBox / ZAP Spider" - # -- Configures existings ZAP Scripts or add new ZAP Scripts. For example can be used if a proxy script must be loaded. Proxy scripts are executed for every request traversing ZAP - scripts: {} - - # -- Optional list of ZAP Active Scanner configurations - scanners: - # -- String: Name of the context to attack, default: first context - - name: scbscan - # -- String: Name of the context to attack, default: first context - context: scbcontext - # -- String: Url to start scaning from, default: first context URL - url: https://example.com/ - # -- String: The name of the default scan policy to use, default: Default Policy - defaultPolicy: "Default Policy" - # -- String: Name of the scan policy to be used, default: Default Policy - policy: "Default Policy" - # -- Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 0 - # -- Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 0 - # -- Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # -- Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # -- Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # -- Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # -- Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false - # -- Int: The max number of threads per host, default: 2 - threadPerHost: 2 - # -- The policy definition, only used if the 'policy' is not set - NOT YET IMPLEMENTED - policyDefinition: - # -- String: The default Attack Strength for all rules, one of Low, Medium, High, Insane (not recommended), default: Medium - defaultStrength: Medium - # -- String: The default Alert Threshold for all rules, one of Off, Low, Medium, High, default: Medium - defaultThreshold: Medium - # -- A list of one or more active scan rules and associated settings which override the defaults - rules: - # -- Int: The rule id as per https://www.zaproxy.org/docs/alerts/ - - id: 10106 - # -- The name of the rule for documentation purposes - this is not required or actually used - name: "rule" - # -- String: The Attack Strength for this rule, one of Low, Medium, High, Insane, default: Medium - strength: Medium - # -- String: The Alert Threshold for this rule, one of Off, Low, Medium, High, default: Medium - threshold: Low - # -- Configures existings ZAP Scripts or add new ZAP Scripts. For example can be used if a proxy script must be loaded. Proxy scripts are executed for every request traversing ZAP - scripts: {} -``` - -## Values - -| Key | Type | Default | Description | -|-----|------|---------|-------------| -| cascadingRules.enabled | bool | `false` | Enables or disables the installation of the default cascading rules for this scanner | -| imagePullSecrets | list | `[]` | Define imagePullSecrets when a private registry is used (see: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) | -| parser.affinity | object | `{}` | Optional affinity settings that control how the parser job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) | -| parser.env | list | `[]` | Optional environment variables mapped into each parseJob (see: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) | -| parser.image.pullPolicy | string | `"IfNotPresent"` | Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images | -| parser.image.repository | string | `"docker.io/securecodebox/parser-zap"` | Parser image repository | -| parser.image.tag | string | defaults to the charts version | Parser image tag | -| parser.nodeSelector | object | `{}` | Optional nodeSelector settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/) | -| parser.resources | object | `{ requests: { cpu: "200m", memory: "100Mi" }, limits: { cpu: "400m", memory: "200Mi" } }` | Optional resources lets you control resource limits and requests for the parser container. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | -| parser.scopeLimiterAliases | object | `{}` | Optional finding aliases to be used in the scopeLimiter. | -| parser.tolerations | list | `[]` | Optional tolerations settings that control how the parser job is scheduled (see: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) | -| parser.ttlSecondsAfterFinished | string | `nil` | seconds after which the Kubernetes job for the parser will be deleted. Requires the Kubernetes TTLAfterFinished controller: https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/ | -| scanner.activeDeadlineSeconds | string | `nil` | There are situations where you want to fail a scan Job after some amount of time. To do so, set activeDeadlineSeconds to define an active deadline (in seconds) when considering a scan Job as failed. (see: https://kubernetes.io/docs/concepts/workloads/controllers/job/#job-termination-and-cleanup) | -| scanner.affinity | object | `{}` | Optional affinity settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) | -| scanner.backoffLimit | int | 3 | There are situations where you want to fail a scan Job after some amount of retries due to a logical error in configuration etc. To do so, set backoffLimit to specify the number of retries before considering a scan Job as failed. (see: https://kubernetes.io/docs/concepts/workloads/controllers/job/#pod-backoff-failure-policy) | -| scanner.env | list | `[]` | Optional environment variables mapped into each scanJob (see: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) | -| scanner.envFrom | list | `[]` | Optional mount environment variables from configMaps or secrets (see: https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/#configure-all-key-value-pairs-in-a-secret-as-container-environment-variables) | -| scanner.extraContainers | list | `[]` | Optional additional Containers started with each scanJob (see: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/) | -| scanner.extraVolumeMounts | list | `[{"mountPath":"/home/securecodebox/configs/1-zap-advanced-scantype.yaml","name":"zap-advanced-scantype-config","readOnly":true,"subPath":"1-zap-advanced-scantype.yaml"}]` | Optional VolumeMounts mapped into each scanJob (see: https://kubernetes.io/docs/concepts/storage/volumes/) | -| scanner.extraVolumes | list | `[{"configMap":{"name":"zap-advanced-scantype-config","optional":true},"name":"zap-advanced-scantype-config"},{"configMap":{"name":"zap-scripts-authentication"},"name":"zap-scripts-authentication"},{"configMap":{"name":"zap-scripts-session"},"name":"zap-scripts-session"}]` | Optional Volumes mapped into each scanJob (see: https://kubernetes.io/docs/concepts/storage/volumes/) | -| scanner.image.pullPolicy | string | `"IfNotPresent"` | Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images | -| scanner.image.repository | string | `"docker.io/securecodebox/scanner-zap-advanced"` | Container Image to run the scan | -| scanner.image.tag | string | `nil` | defaults to the charts version | -| scanner.nameAppend | string | `nil` | append a string to the default scantype name. | -| scanner.nodeSelector | object | `{}` | Optional nodeSelector settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/) | -| scanner.podSecurityContext | object | `{}` | Optional securityContext set on scanner pod (see: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) | -| scanner.reportType | string | "XML" | Optional to configure the reportType of the scan ZAP Scan. Must be one of the supported formats: XML,XML-plus,JSON,JSON-plus,HTML,HTML-plus,MD | -| scanner.resources | object | `{}` | CPU/memory resource requests/limits (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/, https://kubernetes.io/docs/tasks/configure-pod-container/assign-cpu-resource/) | -| scanner.securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["all"]},"privileged":false,"readOnlyRootFilesystem":false,"runAsNonRoot":false}` | Optional securityContext set on scanner container (see: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) | -| scanner.securityContext.allowPrivilegeEscalation | bool | `false` | Ensure that users privileges cannot be escalated | -| scanner.securityContext.capabilities.drop[0] | string | `"all"` | This drops all linux privileges from the container. | -| scanner.securityContext.privileged | bool | `false` | Ensures that the scanner container is not run in privileged mode | -| scanner.securityContext.readOnlyRootFilesystem | bool | `false` | Prevents write access to the containers file system | -| scanner.securityContext.runAsNonRoot | bool | `false` | Enforces that the scanner image is run as a non root user | -| scanner.suspend | bool | `false` | if set to true the scan job will be suspended after creation. You can then resume the job using `kubectl resume ` or using a job scheduler like kueue | -| scanner.tolerations | list | `[]` | Optional tolerations settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) | -| scanner.ttlSecondsAfterFinished | string | `nil` | seconds after which the Kubernetes job for the scanner will be deleted. Requires the Kubernetes TTLAfterFinished controller: https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/ | -| zapConfiguration | object | `{}` | All `scanType` specific configuration options. Feel free to add more configuration options. All configuration options can be overridden by scan specific configurations if defined. Please have a look into the README.md to find more configuration options. | -| zapContainer.env | list | `[]` | Optional environment variables mapped into each scanJob (see: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) | -| zapContainer.envFrom | list | `[]` | Optional mount environment variables from configMaps or secrets (see: https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/#configure-all-key-value-pairs-in-a-secret-as-container-environment-variables) | -| zapContainer.extraVolumeMounts | list | `[{"mountPath":"/home/zap/.ZAP_D/scripts/scripts/authentication/","name":"zap-scripts-authentication","readOnly":true},{"mountPath":"/home/zap/.ZAP_D/scripts/scripts/session/","name":"zap-scripts-session","readOnly":true}]` | Optional VolumeMounts mapped into each scanJob (see: https://kubernetes.io/docs/concepts/storage/volumes/) | -| zapContainer.image.pullPolicy | string | `"IfNotPresent"` | Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images | -| zapContainer.image.repository | string | `"docker.io/zaproxy/zap-stable"` | Container Image to run the scan | -| zapContainer.image.tag | string | `nil` | defaults to the charts appVersion | -| zapContainer.resources | object | `{}` | CPU/memory resource requests/limits (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/, https://kubernetes.io/docs/tasks/configure-pod-container/assign-cpu-resource/) | -| zapContainer.securityContext.allowPrivilegeEscalation | bool | `false` | | -| zapContainer.securityContext.capabilities.drop[0] | string | `"all"` | | -| zapContainer.securityContext.privileged | bool | `false` | | -| zapContainer.securityContext.readOnlyRootFilesystem | bool | `false` | | -| zapContainer.securityContext.runAsNonRoot | bool | `false` | | - -## Contributing - -Contributions are welcome and extremely helpful 🙌 -Please have a look at [Contributing](./CONTRIBUTING.md) - -## Community - -You are welcome, please join us on... 👋 - -- [GitHub][scb-github] -- [OWASP Slack (Channel #project-securecodebox)][scb-slack] -- [Mastodon][scb-mastodon] - -secureCodeBox is an official [OWASP][scb-owasp] project. - -## License -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) - -Code of secureCodeBox is licensed under the [Apache License 2.0][scb-license]. - -[scb-owasp]: https://www.owasp.org/index.php/OWASP_secureCodeBox -[scb-docs]: https://www.securecodebox.io/ -[scb-site]: https://www.securecodebox.io/ -[scb-github]: https://github.com/secureCodeBox/ -[scb-mastodon]: https://infosec.exchange/@secureCodeBox -[scb-slack]: https://owasp.org/slack/invite -[scb-license]: https://github.com/secureCodeBox/secureCodeBox/blob/master/LICENSE -[zap github]: https://github.com/zaproxy/zaproxy/ -[zap user guide]: https://www.zaproxy.org/docs/ diff --git a/scanners/zap-advanced/docs/README.DockerHub-Scanner.md b/scanners/zap-advanced/docs/README.DockerHub-Scanner.md deleted file mode 100644 index 1b961e879e..0000000000 --- a/scanners/zap-advanced/docs/README.DockerHub-Scanner.md +++ /dev/null @@ -1,115 +0,0 @@ - - - -

- License Apache-2.0 - GitHub release (latest SemVer) - OWASP Lab Project - Artifact HUB - GitHub Repo stars - Mastodon Follower -

- -## What is OWASP secureCodeBox? - -

- secureCodeBox Logo -

- -_[OWASP secureCodeBox][scb-github]_ is an automated and scalable open source solution that can be used to integrate various *security vulnerability scanners* with a simple and lightweight interface. The _secureCodeBox_ mission is to support *DevSecOps* Teams to make it easy to automate security vulnerability testing in different scenarios. - -With the _secureCodeBox_ we provide a toolchain for continuous scanning of applications to find the low-hanging fruit issues early in the development process and free the resources of the penetration tester to concentrate on the major security issues. - -The secureCodeBox project is running on [Kubernetes](https://kubernetes.io/). To install it you need [Helm](https://helm.sh), a package manager for Kubernetes. It is also possible to start the different integrated security vulnerability scanners based on a docker infrastructure. - -### Quickstart with secureCodeBox on Kubernetes - -You can find resources to help you get started on our [documentation website](https://www.securecodebox.io) including instruction on how to [install the secureCodeBox project](https://www.securecodebox.io/docs/getting-started/installation) and guides to help you [run your first scans](https://www.securecodebox.io/docs/getting-started/first-scans) with it. - -## Supported Tags -- `latest` (represents the latest stable release build) -- tagged releases, e.g. `3.0.0`, `2.9.0`, `2.8.0`, `2.7.0` - -## How to use this image -This `scanner` image is intended to work in combination with the corresponding `parser` image to parse the scanner `findings` to generic secureCodeBox results. For more information details please take a look at the [project page][scb-docs] or [documentation page][https://www.securecodebox.io/docs/scanners/ZAP]. - -```bash -docker pull securecodebox/scanner-zap-advanced -``` - -## What is ZAP? -:::caution Deprecation Notice -The `zap-advanced` and `zap` ScanType are being deprecated in favor of the `zap-automation-framework`, which encompasses all functionalities of the previous ScanTypes. We recommend transitioning to the "zap-automation-framework" as soon as possible. `zap-advanced` and `zap` ScanTypes will be removed in the upcoming v5 release. For guidance on migrating to "zap-automation-framework," please refer to [migration to zap-automation framework](/docs/scanners/zap-automation-framework#migration-to-zap-automation-framework). -::: - -The Zed Attack Proxy (ZAP) is one of the world’s most popular free security tools and is actively maintained by hundreds of international volunteers*. It can help you automatically find security vulnerabilities in your web applications while you are developing and testing your applications. It's also a great tool for experienced pentesters to use for manual security testing. - -To learn more about the ZAP scanner itself visit [https://www.zaproxy.org/](https://www.zaproxy.org/). - -## Scanner Configuration - -Listed below are the arguments supported by the `zap-advanced-scan` script. - -The command line interface can be used to easily run server scans: `-t www.example.com` - -```bash -usage: zap-client [-h] -z ZAP_URL [-a API_KEY] [-c CONFIG_FOLDER] -t TARGET [-o OUTPUT_FOLDER] [-r XML,XML-plus,JSON,JSON-plus,HTML,HTML-plus,MD] - -OWASP secureCodeBox ZAP Client (can be used to automate ZAP instances based on YAML configuration files.) - -optional arguments: - -h, --help show this help message and exit - -z ZAP_URL, --zap-url ZAP_URL - The ZAP API Url used to call the ZAP API. - -a API_KEY, --api-key API_KEY - The ZAP API Key used to call the ZAP API. - -c CONFIG_FOLDER, --config-folder CONFIG_FOLDER - The path to a local folder containing the additional ZAP configuration YAMLs used to configure ZAP. - -t TARGET, --target TARGET - The target to scan with ZAP. - -o OUTPUT_FOLDER, --output-folder OUTPUT_FOLDER - The path to a local folder used to store the output files, eg. the ZAP Report or logfiles. - -r XML,XML-plus,JSON,JSON-plus,HTML,HTML-plus,MD, --report-type XML,XML-plus,JSON,JSON-plus,HTML,HTML-plus,MD - The ZAP Report Type. -``` - -## Community - -You are welcome, please join us on... 👋 - -- [GitHub][scb-github] -- [OWASP Slack (Channel #project-securecodebox)][scb-slack] -- [Mastodon][scb-mastodon] - -secureCodeBox is an official [OWASP][scb-owasp] project. - -## License -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) - -As with all Docker images, these likely also contain other software which may be under other licenses (such as Bash, etc from the base distribution, along with any direct or indirect dependencies of the primary software being contained). - -As for any pre-built image usage, it is the image user's responsibility to ensure that any use of this image complies with any relevant licenses for all software contained within. - -[scb-owasp]: https://www.owasp.org/index.php/OWASP_secureCodeBox -[scb-docs]: https://www.securecodebox.io/ -[scb-site]: https://www.securecodebox.io/ -[scb-github]: https://github.com/secureCodeBox/ -[scb-mastodon]: https://infosec.exchange/@secureCodeBox -[scb-slack]: https://owasp.org/slack/invite -[scb-license]: https://github.com/secureCodeBox/secureCodeBox/blob/master/LICENSE -[zap github]: https://github.com/zaproxy/zaproxy/ -[zap user guide]: https://www.zaproxy.org/docs/ diff --git a/scanners/zap-advanced/examples/demo-bodgeit-scan-authenticated/scan.yaml b/scanners/zap-advanced/examples/demo-bodgeit-scan-authenticated/scan.yaml deleted file mode 100644 index 3e83112693..0000000000 --- a/scanners/zap-advanced/examples/demo-bodgeit-scan-authenticated/scan.yaml +++ /dev/null @@ -1,119 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: zap-advanced-scan-config -data: - 2-zap-advanced-scan.yaml: |- - - # ZAP Contexts Configuration - contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: scb-bodgeit-context - # The top level url, mandatory, everything under this will be included - url: http://bodgeit.default.svc:8080/bodgeit/ - # An optional list of regexes to include - includePaths: - - "http://bodgeit.default.svc:8080/bodgeit.*" - # An optional list of regexes to exclude - excludePaths: - - "http://bodgeit.default.svc:8080/bodgeit/logout.jsp" - - ".*\\.js" - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - # Auth Credentials for the scanner to access the application - # Can be either basicAuth or a oidc token. - # If both are set, the oidc token takes precedent - authentication: - # Currently supports "basic-auth", "form-based", "json-based", "script-based" - type: "form-based" - # basic-auth requires no further configuration - form-based: - loginUrl: "http://bodgeit.default.svc:8080/bodgeit/login.jsp" - # must be escaped already to prevent yaml parser colidations 'username={%username%}&password={%password%}'' - loginRequestData: "username%3D%7B%25username%25%7D%26password%3D%7B%25password%25%7D" - # Indicates if the current Zap User Session is based on a valid authentication (loggedIn) or not (loggedOut) - verification: - isLoggedInIndicator: '\Q\E' - isLoggedOutIndicator: '\QGuest user\E' - users: - - name: bodgeit-user-1 - username: test@thebodgeitstore.com - password: password - forced: true - session: - # Currently supports "scriptBasedSessionManagement", "cookieBasedSessionManagement", "httpAuthSessionManagement" - type: "cookieBasedSessionManagement" - - # ZAP Spiders Configuration - spiders: - - name: scb-bodgeit-spider - # String: Name of the context to spider, default: first context - context: scb-bodgeit-context - # String: Name of the user to authenticate with and used to spider - user: bodgeit-user-1 - # String: Url to start spidering from, default: first context URL - url: http://bodgeit.default.svc:8080/bodgeit/ - # Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 3 - # Int: The maximum tree depth to explore, default 5 - maxDepth: 5 - # Int: The maximum number of children to add to each node in the tree - maxChildren: 10 - # String: The user agent to use in requests, default: '' - use the default ZAP one - userAgent: "secureCodeBox / ZAP Spider" - - # ZAP ActiveScans Configuration - scanners: - - name: scb-bodgeit-scan - # String: Name of the context to attack, default: first context - context: scb-bodgeit-context - # String: Name of the user to authenticate with and used to spider - user: bodgeit-user-1 - # String: Url to start scaning from, default: first context URL - url: http://bodgeit.default.svc:8080/bodgeit/ - # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 3 - # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 10 - # Int: The max number of threads per host, default: 2 - threadPerHost: 2 - # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false ---- -apiVersion: "execution.securecodebox.io/v1" -kind: Scan -metadata: - name: "zap-authenticated-full-scan-bodgeit" -spec: - scanType: "zap-advanced-scan" - parameters: - # target URL including the protocol - - "-t" - - "http://bodgeit.default.svc:8080/bodgeit/" - volumeMounts: - - name: zap-advanced-scan-config - mountPath: /home/securecodebox/configs/2-zap-advanced-scan.yaml - subPath: 2-zap-advanced-scan.yaml - readOnly: true - volumes: - - name: zap-advanced-scan-config - configMap: - name: zap-advanced-scan-config diff --git a/scanners/zap-advanced/examples/demo-bodgeit-scan-unauthenticated/scan.yaml b/scanners/zap-advanced/examples/demo-bodgeit-scan-unauthenticated/scan.yaml deleted file mode 100644 index 6fbcd6e4db..0000000000 --- a/scanners/zap-advanced/examples/demo-bodgeit-scan-unauthenticated/scan.yaml +++ /dev/null @@ -1,68 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -apiVersion: v1 -kind: ConfigMap -metadata: - name: zap-advanced-scan-config -data: - 2-zap-advanced-scan.yaml: |- - - # ZAP Contexts Configuration - contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: scb-bodgeit-context - # The top level url, mandatory, everything under this will be included - url: http://bodgeit.default.svc:8080/bodgeit/ - # An optional list of regexes to include - includePaths: - - "http://bodgeit.default.svc:8080/bodgeit.*" - # An optional list of regexes to exclude - excludePaths: - - "http://bodgeit.default.svc:8080/bodgeit/logout.jsp" - - ".*\\.js" - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - - # ZAP Spiders Configuration - spiders: - - name: scb-bodgeit-spider - # String: Name of the context to spider, default: first context - context: scb-bodgeit-context - # String: Url to start spidering from, default: first context URL - url: http://bodgeit.default.svc:8080/bodgeit/ - # Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 3 - # Int: The maximum tree depth to explore, default 5 - maxDepth: 5 - # Int: The maximum number of children to add to each node in the tree - maxChildren: 10 - # String: The user agent to use in requests, default: '' - use the default ZAP one - userAgent: "secureCodeBox / ZAP Spider" - ---- -apiVersion: "execution.securecodebox.io/v1" -kind: Scan -metadata: - name: "zap-authenticated-baseline-scan-bodgeit" -spec: - scanType: "zap-advanced-scan" - parameters: - # target URL including the protocol - - "-t" - - "http://bodgeit.default.svc:8080/bodgeit/" - volumeMounts: - - name: zap-advanced-scan-config - mountPath: /home/securecodebox/configs/2-zap-advanced-scan.yaml - subPath: 2-zap-advanced-scan.yaml - readOnly: true - volumes: - - name: zap-advanced-scan-config - configMap: - name: zap-advanced-scan-config diff --git a/scanners/zap-advanced/examples/demo-juiceshop-scan-authenticated/scan.yaml b/scanners/zap-advanced/examples/demo-juiceshop-scan-authenticated/scan.yaml deleted file mode 100644 index bfec98bf10..0000000000 --- a/scanners/zap-advanced/examples/demo-juiceshop-scan-authenticated/scan.yaml +++ /dev/null @@ -1,133 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: zap-advanced-scan-config -data: - 2-zap-advanced-scan.yaml: |- - - # ZAP Contexts Configuration - contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: scb-juiceshop-context - # The top level url, mandatory, everything under this will be included - url: http://juice-shop.default.svc:3000/ - # An optional list of regexes to include - includePaths: - - "http://juice-shop.default.svc:3000.*" - # An optional list of regexes to exclude - excludePaths: - - ".*socket\\.io.*" - - ".*\\.png" - - ".*\\.jpeg" - - ".*\\.jpg" - - ".*\\.woff" - - ".*\\.woff2" - - ".*\\.ttf" - - ".*\\.ico" - # Auth Credentials for the scanner to access the application - # Can be either basicAuth or a oidc token. - # If both are set, the oidc token takes precedent - authentication: - # Currently supports "basic-auth", "form-based", "json-based", "script-based" - type: "json-based" - # json-based requires no further configuration - # zapConfiguration.contexts[0].authentication.json-based -- Configure `type: json-based` authentication (more: https://www.zaproxy.org/docs/api/#json-based-authentication). - json-based: - loginUrl: "http://juice-shop.default.svc:3000/rest/user/login" - # must be escaped already to prevent yaml parser colidations '{"user":{"id":1,"email":"test@test.com"}}'' - loginRequestData: '{"email":"admin@juice-sh.op","password":"admin123"}' - # Indicates if the current Zap User Session is based on a valid authentication (loggedIn) or not (loggedOut) - verification: - # isLoggedInIndicator: "\Q\E" - isLoggedOutIndicator: '\Q{"user":{}}\E' - users: - - name: juiceshop-user-1 - username: admin@juice-sh.op - password: admin123 - forced: true - session: - # Currently supports "scriptBasedSessionManagement", "cookieBasedSessionManagement", "httpAuthSessionManagement" - type: "scriptBasedSessionManagement" - # scriptBasedSessionManagement configuration details - scriptBasedSessionManagement: - name: "juiceshop-session-management.js" - # -- Enables the script if true, otherwise false - enabled: true - # Script engine values: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - engine: "Oracle Nashorn" - # Must be a full path to the script file inside the ZAP container (corresponding to the configMap FileMount) - filePath: "/home/zap/.ZAP_D/scripts/scripts/session/juiceshop-session-management.js" - # A short description for the script. - description: "This is a JuiceShop specific SessionManagement Script used to handle JWT." - - # ZAP Spiders Configuration - spiders: - - name: scb-juiceshop-spider - # String: Name of the context to spider, default: first context - context: scb-juiceshop-context - # String: Name of the user to authenticate with and used to spider - user: juiceshop-user-1 - # String: Url to start spidering from, default: first context URL - url: http://juice-shop.default.svc:3000/ - # zapConfiguration.spiders[0].ajax -- Bool: Whether to use the ZAP ajax spider, default: false - ajax: true - # Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 5 - # Int: The maximum tree depth to explore, default 5 - maxDepth: 10 - - # ZAP ActiveScans Configuration - scanners: - - name: scb-juiceshop-scan - # String: Name of the context to attack, default: first context - context: scb-juiceshop-context - # String: Name of the user to authenticate with and used to spider - user: juiceshop-user-1 - # String: Url to start scaning from, default: first context URL - url: http://juice-shop.default.svc:3000/ - # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 1 - # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 10 - # Int: The max number of threads per host, default: 2 - threadPerHost: 5 - # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false - ---- -apiVersion: "execution.securecodebox.io/v1" -kind: Scan -metadata: - name: "zap-authenticated-full-scan-juiceshop" -spec: - scanType: "zap-advanced-scan" - parameters: - # target URL including the protocol - - "-t" - - "http://juice-shop.default.svc:3000/" - volumeMounts: - - name: zap-advanced-scan-config - mountPath: /home/securecodebox/configs/2-zap-advanced-scan.yaml - subPath: 2-zap-advanced-scan.yaml - readOnly: true - volumes: - - name: zap-advanced-scan-config - configMap: - name: zap-advanced-scan-config diff --git a/scanners/zap-advanced/examples/demo-juiceshop-scan-unauthenticated/scan.yaml b/scanners/zap-advanced/examples/demo-juiceshop-scan-unauthenticated/scan.yaml deleted file mode 100644 index a139341d7c..0000000000 --- a/scanners/zap-advanced/examples/demo-juiceshop-scan-unauthenticated/scan.yaml +++ /dev/null @@ -1,93 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: zap-advanced-scan-config -data: - 2-zap-advanced-scan.yaml: |- - - # ZAP Contexts Configuration - contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: scb-juiceshop-context - # The top level url, mandatory, everything under this will be included - url: http://juice-shop.default.svc:3000/ - # An optional list of regexes to include - includePaths: - - "http://juice-shop.default.svc:3000.*" - # An optional list of regexes to exclude - excludePaths: - - ".*socket\\.io.*" - - ".*\\.png" - - ".*\\.jpeg" - - ".*\\.jpg" - - ".*\\.woff" - - ".*\\.woff2" - - ".*\\.ttf" - - ".*\\.ico" - - # ZAP Spiders Configuration - spiders: - - name: scb-juiceshop-spider - # String: Name of the context to spider, default: first context - context: scb-juiceshop-context - # String: Url to start spidering from, default: first context URL - url: http://juice-shop.default.svc:3000/ - # zapConfiguration.spiders[0].ajax -- Bool: Whether to use the ZAP ajax spider, default: false - ajax: true - # Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 5 - # Int: The maximum tree depth to explore, default 5 - maxDepth: 10 - - # ZAP ActiveScans Configuration - scanners: - - name: scb-juiceshop-scan - # String: Name of the context to attack, default: first context - context: scb-juiceshop-context - # String: Url to start scaning from, default: first context URL - url: http://juice-shop.default.svc:3000/ - # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 1 - # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 10 - # Int: The max number of threads per host, default: 2 - threadPerHost: 5 - # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false ---- -apiVersion: "execution.securecodebox.io/v1" -kind: Scan -metadata: - name: "zap-authenticated-baseline-scan-juiceshop" -spec: - scanType: "zap-advanced-scan" - parameters: - # target URL including the protocol - - "-t" - - "http://juice-shop.default.svc:3000/" - volumeMounts: - - name: zap-advanced-scan-config - mountPath: /home/securecodebox/configs/2-zap-advanced-scan.yaml - subPath: 2-zap-advanced-scan.yaml - readOnly: true - volumes: - - name: zap-advanced-scan-config - configMap: - name: zap-advanced-scan-config diff --git a/scanners/zap-advanced/examples/demo-petstoreapi-scan-authenticated-no-hardcoded-urls/scan.yaml b/scanners/zap-advanced/examples/demo-petstoreapi-scan-authenticated-no-hardcoded-urls/scan.yaml deleted file mode 100644 index a4b119dbaa..0000000000 --- a/scanners/zap-advanced/examples/demo-petstoreapi-scan-authenticated-no-hardcoded-urls/scan.yaml +++ /dev/null @@ -1,71 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: zap-advanced-scan-config -data: - 2-zap-advanced-scan.yaml: |- - - # ZAP Contexts Configuration - contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: scb-petstore-context - # An optional list of regexes to include - includePaths: - - "https?://.*\\..*.svc:.*" - - "https?://.*\\..*.svc/.*" - - "https?://.*\\..*.svc.cluster.local/.*" - - "https?://.*\\..*.svc.cluster.local:.*" - # An optional list of regexes to exclude - excludePaths: - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - - apis: - - name: scb-petstore-api - # -- The Name of the context (zapConfiguration.contexts[x].name) to spider, default: first context available. - context: scb-petstore-context - # -- format of the API ('openapi', 'grapql', 'soap') - format: openapi - # -- path to the OpenAPI spec. Always relative to the targets **hosts**, paths in the targets url will be ignored - path: /v2/swagger.json - - # ZAP ActiveScans Configuration - scanners: - - name: scb-petstore-scan - # String: Name of the context to attack, default: first context - context: scb-petstore-context - # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 1 - # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 5 - # Int: The max number of threads per host, default: 2 - threadPerHost: 5 - ---- -apiVersion: "execution.securecodebox.io/v1" -kind: Scan -metadata: - name: "zap-advanced-api-scan-petstore" -spec: - scanType: "zap-advanced-scan" - parameters: - # target URL including the protocol - - "--target" - - "http://swagger-petstore.default.svc/" - - "--context" - - "scb-petstore-context" - volumeMounts: - - name: zap-advanced-scan-config - mountPath: /home/securecodebox/configs/2-zap-advanced-scan.yaml - subPath: 2-zap-advanced-scan.yaml - readOnly: true - volumes: - - name: zap-advanced-scan-config - configMap: - name: zap-advanced-scan-config diff --git a/scanners/zap-advanced/examples/demo-petstoreapi-scan-authenticated/scan.yaml b/scanners/zap-advanced/examples/demo-petstoreapi-scan-authenticated/scan.yaml deleted file mode 100644 index 43212c5f22..0000000000 --- a/scanners/zap-advanced/examples/demo-petstoreapi-scan-authenticated/scan.yaml +++ /dev/null @@ -1,144 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: zap-advanced-scan-config -data: - 2-zap-advanced-scan.yaml: |- - - global: - # Sets the ZAP Session name - sessionName: integration-test - # Configures existings ZAP Scripts or add new ZAP Scripts. - scripts: - - name: "Alert_on_HTTP_Response_Code_Errors.js" - enabled: true - filePath: "/home/zap/.ZAP_D/scripts/scripts/httpsender/Alert_on_HTTP_Response_Code_Errors.js" - engine: "Oracle Nashorn" - type: "httpsender" - description: "A HTTP Sender Script which will raise alerts based on HTTP Response codes." - - name: "Alert_on_Unexpected_Content_Types.js" - enabled: true - filePath: "/home/zap/.ZAP_D/scripts/scripts/httpsender/Alert_on_Unexpected_Content_Types.js" - engine: "Oracle Nashorn" - type: "httpsender" - description: "A HTTP Sender Script which will raise alerts based on unexpected Content-Types." - - # ZAP Contexts Configuration - contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: scb-petstore-context - # The top level url, mandatory, everything under this will be included. IMPORTANT: must be the hostname without any subpath! - url: http://petstore.demo-targets.svc/ - # An optional list of regexes to include - includePaths: - - "http://petstore.demo-targets.svc/v2.*" - # An optional list of regexes to exclude - excludePaths: - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - - apis: - - name: scb-petstore-api - # -- The Name of the context (zapConfiguration.contexts[x].name) to spider, default: first context available. - context: scb-petstore-context - # -- format of the API ('openapi', 'grapql', 'soap') - format: openapi - # -- Url to start spidering from, default: first context URL - url: http://petstore.demo-targets.svc/v2/swagger.json - # -- Override host setting in swagger.json - hostOverride: http://petstore.demo-targets.svc - - # ZAP Spiders Configuration - spiders: - - name: scb-petstore-spider - # String: Name of the context to spider, default: first context - context: scb-petstore-context - # String: Url to start spidering from, default: first context URL - url: http://petstore.demo-targets.svc/v2/ - # Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 1 - # Int: The maximum tree depth to explore, default 5 - maxDepth: 5 - # Int: The maximum number of children to add to each node in the tree - maxChildren: 10 - # Bool: Whether the spider will accept cookies, default: true - acceptCookies: true - # Bool: Whether the spider will parse HTML comments in order to find URLs, default: true - parseComments: true - # Bool: Whether the spider will parse Git metadata in order to find URLs, default: false - parseGit: false - # Bool: Whether the spider will parse 'robots.txt' files in order to find URLs, default: true - parseRobotsTxt: false - # Bool: Whether the spider will parse 'sitemap.xml' files in order to find URLs, default: true - parseSitemapXml: false - # Bool: Whether the spider will parse SVN metadata in order to find URLs, default: false - parseSVNEntries: false - # Bool: Whether the spider will submit POST forms, default: true - postForm: true - # Bool: Whether the spider will process forms, default: true - processForm: true - # Int: The time between the requests sent to a server in milliseconds, default: 200 - requestWaitTime: 200 - # Bool: Whether the spider will send the referer header, default: true - sendRefererHeader: true - # Int: The number of spider threads, default: 2 - threadCount: 2 - # String: The user agent to use in requests, default: '' - use the default ZAP one - userAgent: "secureCodeBox / ZAP Spider" - - # ZAP ActiveScans Configuration - scanners: - - name: scb-petstore-scan - # String: Name of the context to attack, default: first context - context: scb-petstore-context - # String: Url to start scaning from, default: first context URL - url: http://petstore.demo-targets.svc/v2/ - # String: Name of the scan policy to be used, default: Default Policy - policy: "API-Minimal" - # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 1 - # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 5 - # Int: The max number of threads per host, default: 2 - threadPerHost: 5 - # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false - ---- -apiVersion: "execution.securecodebox.io/v1" -kind: Scan -metadata: - name: "zap-advanced-api-scan-petstore" -spec: - scanType: "zap-advanced-scan" - parameters: - # target URL including the protocol - - "-t" - - "http://petstore.demo-targets.svc/" - volumeMounts: - - name: zap-advanced-scan-config - mountPath: /home/securecodebox/configs/2-zap-advanced-scan.yaml - subPath: 2-zap-advanced-scan.yaml - readOnly: true - volumes: - - name: zap-advanced-scan-config - configMap: - name: zap-advanced-scan-config diff --git a/scanners/zap-advanced/examples/demo-petstoreapi-scan-unauthenticated/scan.yaml b/scanners/zap-advanced/examples/demo-petstoreapi-scan-unauthenticated/scan.yaml deleted file mode 100644 index f6973c87fb..0000000000 --- a/scanners/zap-advanced/examples/demo-petstoreapi-scan-unauthenticated/scan.yaml +++ /dev/null @@ -1,127 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: zap-advanced-scan-config -data: - 2-zap-advanced-scan.yaml: |- - - global: - # Sets the ZAP Session name - sessionName: integration-test - # Configures existings ZAP Scripts or add new ZAP Scripts. - scripts: - - name: "Alert_on_HTTP_Response_Code_Errors.js" - enabled: true - filePath: "/home/zap/.ZAP_D/scripts/scripts/httpsender/Alert_on_HTTP_Response_Code_Errors.js" - engine: "Oracle Nashorn" - type: "httpsender" - description: "A HTTP Sender Script which will raise alerts based on HTTP Response codes." - - name: "Alert_on_Unexpected_Content_Types.js" - enabled: true - filePath: "/home/zap/.ZAP_D/scripts/scripts/httpsender/Alert_on_Unexpected_Content_Types.js" - engine: "Oracle Nashorn" - type: "httpsender" - description: "A HTTP Sender Script which will raise alerts based on unexpected Content-Types." - - # ZAP Contexts Configuration - contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: scb-petstore-context - # The top level url, mandatory, everything under this will be included. IMPORTANT: must be the hostname without any subpath! - url: http://petstore.demo-targets.svc/ - # An optional list of regexes to include - includePaths: - - "https?://.*\\..*.svc:.*" - - "https?://.*\\..*.svc/.*" - - "https?://.*\\..*.svc.cluster.local/.*" - - "https?://.*\\..*.svc.cluster.local:.*" - # An optional list of regexes to exclude - excludePaths: - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - - apis: - - name: scb-petstore-api - # -- The Name of the context (zapConfiguration.contexts[x].name) to spider, default: first context available. - context: scb-petstore-context - # -- format of the API ('openapi', 'grapql', 'soap') - format: openapi - # -- Url to start spidering from, default: first context URL - url: http://petstore.demo-targets.svc/v2/swagger.json - # -- Relative path for the given targetUrl. mutually exclusive to the URL configuration. - # path: /v2/swagger.json - # -- Override host setting in swagger.json - hostOverride: http://petstore.demo-targets.svc - - # ZAP Spiders Configuration - spiders: - - name: scb-petstore-spider - # String: Name of the context to spider, default: first context - context: scb-petstore-context - # String: Url to start spidering from, default: first context URL - url: http://petstore.demo-targets.svc/v2/ - # Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 1 - # Int: The maximum tree depth to explore, default 5 - maxDepth: 5 - # Int: The maximum number of children to add to each node in the tree - maxChildren: 10 - # # Int: The max size of a response that will be parsed, default: 2621440 - 2.5 Mb - # maxParseSizeBytes: 2621440 - # Bool: Whether the spider will accept cookies, default: true - acceptCookies: true - # Bool: Whether the spider will handle OData responses, default: false - handleODataParametersVisited: false - # Bool: Whether the spider will parse HTML comments in order to find URLs, default: true - parseComments: true - # Bool: Whether the spider will parse Git metadata in order to find URLs, default: false - parseGit: false - # Bool: Whether the spider will parse 'robots.txt' files in order to find URLs, default: true - parseRobotsTxt: false - # Bool: Whether the spider will parse 'sitemap.xml' files in order to find URLs, default: true - parseSitemapXml: false - # Bool: Whether the spider will parse SVN metadata in order to find URLs, default: false - parseSVNEntries: false - # Bool: Whether the spider will submit POST forms, default: true - postForm: true - # Bool: Whether the spider will process forms, default: true - processForm: true - # Int: The time between the requests sent to a server in milliseconds, default: 200 - requestWaitTime: 200 - # Bool: Whether the spider will send the referer header, default: true - sendRefererHeader: true - # Int: The number of spider threads, default: 2 - threadCount: 2 - # String: The user agent to use in requests, default: '' - use the default ZAP one - userAgent: "secureCodeBox / ZAP Spider" - ---- -apiVersion: "execution.securecodebox.io/v1" -kind: Scan -metadata: - name: "zap-api-baseline-scan-petstore" -spec: - scanType: "zap-advanced-scan" - parameters: - # target URL including the protocol - - "-t" - - "http://petstore.demo-targets.svc/" - volumeMounts: - - name: zap-advanced-scan-config - mountPath: /home/securecodebox/configs/2-zap-advanced-scan.yaml - subPath: 2-zap-advanced-scan.yaml - readOnly: true - volumes: - - name: zap-advanced-scan-config - configMap: - name: zap-advanced-scan-config diff --git a/scanners/zap-advanced/examples/secureCodeBox.io-scan/scan.yaml b/scanners/zap-advanced/examples/secureCodeBox.io-scan/scan.yaml deleted file mode 100644 index 910b116a49..0000000000 --- a/scanners/zap-advanced/examples/secureCodeBox.io-scan/scan.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -apiVersion: "execution.securecodebox.io/v1" -kind: Scan -metadata: - name: "zap-advanced-scan-securecodebox" -spec: - scanType: "zap-advanced-scan" - parameters: - # target URL including the protocol - - "-t" - - "https://www.secureCodeBox.io" diff --git a/scanners/zap-advanced/integration-tests/scantype-configMap.yaml b/scanners/zap-advanced/integration-tests/scantype-configMap.yaml deleted file mode 100644 index 38dcc6b65b..0000000000 --- a/scanners/zap-advanced/integration-tests/scantype-configMap.yaml +++ /dev/null @@ -1,331 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -apiVersion: v1 -kind: ConfigMap -metadata: - name: zap-advanced-scantype-config -data: - 1-zap-advanced-scantype.yaml: |- - - # Global ZAP Configurations - global: - # Sets the ZAP Session name - sessionName: scb-integration-test - # -- Updates all installed ZAP AddOns on startup if true, otherwise false. - addonUpdate: true - # -- Installs additional ZAP AddOns on startup, listed by their name: - addonInstall: - - pscanrulesBeta - - ascanrulesBeta - - pscanrulesAlpha - - ascanrulesAlpha - - # ZAP Contexts Configuration - contexts: - - name: scb-bodgeit-context - # The top level url, mandatory, everything under this will be included. IMPORTANT: must be the hostname without any subpath! - url: http://bodgeit.demo-targets.svc:8080/ - # An optional list of regexes to include - includePaths: - - "http://bodgeit.demo-targets.svc:8080/bodgeit.*" - # An optional list of regexes to exclude - excludePaths: - - ".*\\.js" - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - # Auth Credentials for the scanner to access the application - # Can be either basicAuth or a oidc token. - # If both are set, the oidc token takes precedent - # More infos about "ZAP Authentication for BodgeIT": https://play.sonatype.com/watch/B1vhaLSUsme7eA5hU8WeGB? - authentication: - # Currently supports "basic-auth", "form-based", "json-based", "script-based" - type: "form-based" - # basic-auth requires no further configuration - form-based: - loginUrl: "http://bodgeit.demo-targets.svc:8080/bodgeit/login.jsp" - # must be escaped already to prevent yaml parser colidations 'username={%username%}&password={%password%}'' - loginRequestData: "username%3D%7B%25username%25%7D%26password%3D%7B%25password%25%7D" - # Indicates if the current Zap User Session is based on a valid authentication (loggedIn) or not (loggedOut) - verification: - isLoggedInIndicator: '\Q\E' - isLoggedOutIndicator: '\QGuest user\E' - users: - - name: bodgeit-user-1 - username: test@thebodgeitstore.com - password: password - forced: true - session: - # Currently supports "scriptBasedSessionManagement", "cookieBasedSessionManagement", "httpAuthSessionManagement" - type: "cookieBasedSessionManagement" - - name: scb-juiceshop-context - # The top level url, mandatory, everything under this will be included - url: http://juiceshop.demo-targets.svc:3000/ - # An optional list of regexes to include - includePaths: - - "http://juiceshop.demo-targets.svc:3000.*" - # An optional list of regexes to exclude - excludePaths: - - ".*socket\\.io.*" - - ".*\\.png" - - ".*\\.jpeg" - - ".*\\.jpg" - - ".*\\.woff" - - ".*\\.woff2" - - ".*\\.ttf" - - ".*\\.ico" - # Auth Credentials for the scanner to access the application - # Can be either basicAuth or a oidc token. - # If both are set, the oidc token takes precedent - authentication: - # Currently supports "basic-auth", "form-based", "json-based", "script-based" - type: "json-based" - # json-based requires no further configuration - # zapConfiguration.contexts[0].authentication.json-based -- Configure `type: json-based` authentication (more: https://www.zaproxy.org/docs/api/#json-based-authentication). - json-based: - loginUrl: "http://juiceshop.demo-targets.svc:3000/rest/user/login" - # must be escaped already to prevent yaml parser colidations '{"user":{"id":1,"email":"test@test.com"}}'' - loginRequestData: '{"email":"admin@juice-sh.op","password":"admin123"}' - # Indicates if the current Zap User Session is based on a valid authentication (loggedIn) or not (loggedOut) - verification: - # isLoggedInIndicator: "\Q\E" - isLoggedOutIndicator: '\Q{"user":{}}\E' - users: - - name: juiceshop-user-1 - username: admin@juice-sh.op - password: admin123 - forced: true - # session: - # # Currently supports "scriptBasedSessionManagement", "cookieBasedSessionManagement", "httpAuthSessionManagement" - # type: "scriptBasedSessionManagement" - # # scriptBasedSessionManagement configuration details - # scriptBasedSessionManagement: - # name: "juiceshop-session-management.js" - # # Script engine values: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - # engine: "Oracle Nashorn" - # type: "session" - # # Must be a full path to the script file inside the ZAP container (corresponding to the configMap FileMount) - # filePath: "/home/zap/.ZAP_D/scripts/scripts/session/juiceshop-session-management.js" - # description: "This is a JuiceShop specific SessionManagement Script used to handle JWT." - - name: scb-petstore-context - # The top level url, mandatory, everything under this will be included. IMPORTANT: must be the hostname without any subpath! - url: http://petstore.demo-targets.svc/ - # An optional list of regexes to include - includePaths: - - "http://petstore.demo-targets.svc/v2.*" - # An optional list of regexes to exclude - excludePaths: - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - - apis: - - name: scb-petstore-api - # -- The Name of the context (zapConfiguration.contexts[x].name) to spider, default: first context available. - context: scb-petstore-context - # -- format of the API ('openapi', 'grapql', 'soap') - format: openapi - # -- Url to start spidering from, default: first context URL - url: http://petstore.demo-targets.svc/v2/swagger.json - # -- Override host setting in swagger.json - hostOverride: http://petstore.demo-targets.svc - # Configures existings ZAP Scripts or add new ZAP Scripts. - scripts: - - name: "Alert_on_HTTP_Response_Code_Errors.js" - enabled: true - filePath: "/home/zap/.ZAP_D/scripts/scripts/httpsender/Alert_on_HTTP_Response_Code_Errors.js" - engine: "Oracle Nashorn" - type: "httpsender" - description: "A HTTP Sender Script which will raise alerts based on HTTP Response codes." - - name: "Alert_on_Unexpected_Content_Types.js" - enabled: true - filePath: "/home/zap/.ZAP_D/scripts/scripts/httpsender/Alert_on_Unexpected_Content_Types.js" - engine: "Oracle Nashorn" - type: "httpsender" - description: "A HTTP Sender Script which will raise alerts based on unexpected Content-Types." - - # ZAP Spiders Configuration - spiders: - - name: scb-bodgeit-spider - # String: Name of the context to spider, default: first context - context: scb-bodgeit-context - # String: Name of the user to authenticate with and used to spider - user: bodgeit-user-1 - # String: Url to start spidering from, default: first context URL - url: http://bodgeit.demo-targets.svc:8080/bodgeit/ - # Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 1 - # Int: The maximum tree depth to explore, default 5 - maxDepth: 5 - # Int: The maximum number of children to add to each node in the tree - maxChildren: 10 - # # Int: The max size of a response that will be parsed, default: 2621440 - 2.5 Mb - # maxParseSizeBytes: 2621440 - # Bool: Whether the spider will accept cookies, default: true - acceptCookies: true - # Bool: Whether the spider will handle OData responses, default: false - handleODataParametersVisited: false - # Enum [ignore_completely, ignore_value, use_all]: How query string parameters are used when checking if a URI has already been visited, default: use_all - handleParameters: use_all - # Bool: Whether the spider will parse HTML comments in order to find URLs, default: true - parseComments: true - # Bool: Whether the spider will parse Git metadata in order to find URLs, default: false - parseGit: false - # Bool: Whether the spider will parse 'robots.txt' files in order to find URLs, default: true - parseRobotsTxt: true - # Bool: Whether the spider will parse 'sitemap.xml' files in order to find URLs, default: true - parseSitemapXml: false - # Bool: Whether the spider will parse SVN metadata in order to find URLs, default: false - parseSVNEntries: false - # Bool: Whether the spider will submit POST forms, default: true - postForm: true - # Bool: Whether the spider will process forms, default: true - processForm: true - # Int: The time between the requests sent to a server in milliseconds, default: 200 - requestWaitTime: 200 - # Bool: Whether the spider will send the referer header, default: true - sendRefererHeader: true - # Int: The number of spider threads, default: 2 - threadCount: 2 - # String: The user agent to use in requests, default: '' - use the default ZAP one - userAgent: "secureCodeBox / ZAP Spider" - - name: scb-juiceshop-spider - # String: Name of the context to spider, default: first context - context: scb-juiceshop-context - # String: Name of the user to authenticate with and used to spider - user: juiceshop-user-1 - # String: Url to start spidering from, default: first context URL - url: http://juiceshop.demo-targets.svc:3000/ - # zapConfiguration.spiders[0].ajax -- Bool: Whether to use the ZAP ajax spider, default: false - ajax: true - # Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 2 - # Int: The maximum tree depth to explore, default 5 - maxDepth: 5 - - name: scb-petstore-spider - # String: Name of the context to spider, default: first context - context: scb-petstore-context - # String: Url to start spidering from, default: first context URL - url: http://petstore.demo-targets.svc/v2/ - # Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 1 - # Int: The maximum tree depth to explore, default 5 - maxDepth: 5 - # Int: The maximum number of children to add to each node in the tree - maxChildren: 10 - # # Int: The max size of a response that will be parsed, default: 2621440 - 2.5 Mb - # maxParseSizeBytes: 2621440 - # Bool: Whether the spider will accept cookies, default: true - acceptCookies: true - # Bool: Whether the spider will handle OData responses, default: false - handleODataParametersVisited: false - # Enum [ignore_completely, ignore_value, use_all]: How query string parameters are used when checking if a URI has already been visited, default: use_all - handleParameters: use_all - # Bool: Whether the spider will parse HTML comments in order to find URLs, default: true - parseComments: true - # Bool: Whether the spider will parse Git metadata in order to find URLs, default: false - parseGit: false - # Bool: Whether the spider will parse 'robots.txt' files in order to find URLs, default: true - parseRobotsTxt: false - # Bool: Whether the spider will parse 'sitemap.xml' files in order to find URLs, default: true - parseSitemapXml: false - # Bool: Whether the spider will parse SVN metadata in order to find URLs, default: false - parseSVNEntries: false - # Bool: Whether the spider will submit POST forms, default: true - postForm: true - # Bool: Whether the spider will process forms, default: true - processForm: true - # Int: The time between the requests sent to a server in milliseconds, default: 200 - requestWaitTime: 200 - # Bool: Whether the spider will send the referer header, default: true - sendRefererHeader: true - # Int: The number of spider threads, default: 2 - threadCount: 5 - # String: The user agent to use in requests, default: '' - use the default ZAP one - userAgent: "secureCodeBox / ZAP Spider" - - # ZAP ActiveScans Configuration - scanners: - - name: scb-bodgeit-scan - # String: Name of the context to attack, default: first context - context: scb-bodgeit-context - # String: Name of the user to authenticate with and used to spider - user: bodgeit-user-1 - # String: Url to start scaning from, default: first context URL - url: http://bodgeit.demo-targets.svc:8080/bodgeit/ - # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 1 - # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 5 - # Int: The max number of threads per host, default: 2 - threadPerHost: 5 - # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false - - name: scb-juiceshop-scanner - # String: Name of the context to attack, default: first context - context: scb-juiceshop-context - # String: Name of the user to authenticate with and used to spider - user: juiceshop-user-1 - # String: Url to start scaning from, default: first context URL - url: http://juiceshop.demo-targets.svc:3000/ - # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 1 - # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 5 - # Int: The max number of threads per host, default: 2 - threadPerHost: 5 - # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false - - name: scb-petstore-scan - # String: Name of the context to attack, default: first context - context: scb-petstore-context - # String: Url to start scaning from, default: first context URL - url: http://petstore.demo-targets.svc/v2/ - # String: Name of the scan policy to be used, default: Default Policy - policy: "API-Minimal" - # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 1 - # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 5 - # Int: The max number of threads per host, default: 2 - threadPerHost: 5 - # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false diff --git a/scanners/zap-advanced/integration-tests/zap-advanced.test.js b/scanners/zap-advanced/integration-tests/zap-advanced.test.js deleted file mode 100644 index 796a11d215..0000000000 --- a/scanners/zap-advanced/integration-tests/zap-advanced.test.js +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-FileCopyrightText: the secureCodeBox authors -// -// SPDX-License-Identifier: Apache-2.0 - -const { scan } = require("../../../tests/integration/helpers.js"); - -jest.retryTimes(3); - -test.concurrent.skip( - "ZAP-advanced scan without config YAML against 'bodgeit' container should only find couple findings", - async () => { - const { count } = await scan( - "zap-advanced-scan-bodgeit-demo", - "zap-advanced-scan", - ["-t", "http://bodgeit.demo-targets.svc:8080/"], - 60 * 30 - ); - - // There must be at least one finding - expect(count).toBeGreaterThanOrEqual(1); - }, - 60 * 31 * 1000 -); - -test.concurrent( - "ZAP-advanced scan without config YAML against 'juiceshop' should only find couple findings", - async () => { - const { count } = await scan( - "zap-advanced-scan-juiceshop-demo", - "zap-advanced-scan", - ["-t", "http://juiceshop.demo-targets.svc:3000/"], - 60 * 30 - ); - - // There must be at least one finding - expect(count).toBeGreaterThanOrEqual(1); - }, - 60 * 31 * 1000 -); - -test.concurrent.skip( - "ZAP-advanced scan without config YAML against 'swagger-petstore' should only find couple findings", - async () => { - const { count } = await scan( - "zap-advanced-scan-petstore-demo", - "zap-advanced-scan", - ["-t", "http://petstore.demo-targets.svc/"], - 60 * 30 - ); - - // There must be at least one finding - expect(count).toBeGreaterThanOrEqual(1); - }, - 60 * 31 * 1000 -); - -// test( -// "ZAP-advanced scan without config YAML against 'old-wordpress' should only find couple findings", -// async () => { -// const { count } = await scan( -// "zap-advanced-scan-wordpress-demo", -// "zap-advanced-scan", -// ["-t", "http://old-wordpress.demo-targets.svc/"], -// 60 * 5 -// ); - -// // There must be at least one finding -// expect(count).toBeGreaterThanOrEqual(1); -// }, -// 60 * 5 * 1000 -// ); diff --git a/scanners/zap-advanced/scanner/.dockerignore b/scanners/zap-advanced/scanner/.dockerignore deleted file mode 100644 index d38a1f7a50..0000000000 --- a/scanners/zap-advanced/scanner/.dockerignore +++ /dev/null @@ -1,14 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -**/node_modules -**/__pycache__ -**/.pytest_cache -examples/ -tests/ -*.log -*.yaml -pytest.ini -test-requirements.txt -Makefile \ No newline at end of file diff --git a/scanners/zap-advanced/scanner/Dockerfile b/scanners/zap-advanced/scanner/Dockerfile deleted file mode 100644 index c72afb2524..0000000000 --- a/scanners/zap-advanced/scanner/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -FROM python:3.10.2-alpine -COPY . /zap-client/ -RUN pip3 install -r /zap-client/requirements.txt -RUN addgroup --system --gid 1001 zap-client && adduser zap-client --system --uid 1001 --ingroup zap-client -USER 1001 -CMD ["/bin/sh"] -WORKDIR /zap-client -ENTRYPOINT ["python3", "-m", "zapclient"] diff --git a/scanners/zap-advanced/scanner/Makefile b/scanners/zap-advanced/scanner/Makefile deleted file mode 100644 index 412e5f4bdb..0000000000 --- a/scanners/zap-advanced/scanner/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# Usage: -# make # generate all -# make clean # remove ALL binaries and objects - -include ../../../prerequisites.mk - -.DEFAULT_GOAL:= generate - -.PHONY: all: -all: init - -.PHONY: init -init: - pip3 install -r requirements.txt - -.PHONY: test -test: unit-test docker-test local-test - -.PHONY: unit-test -unit-test: - @echo "Running with Unit Tests based on pytest ..." - pytest --ignore-glob='*_local.py' - -.PHONY: docker-test -docker-test: - @echo "Running local Integrations Tests based on docker-compose..." - pytest ./tests/test_integration_docker_local.py --log-cli-level "INFO" - -.PHONY: local-test -local-test: - @echo "Running local Integrations Tests based on local ZAP + docker-compose..." - pytest ./tests/test_integration_zap_local.py --log-cli-level "INFO" diff --git a/scanners/zap-advanced/scanner/README.md b/scanners/zap-advanced/scanner/README.md deleted file mode 100644 index db569899a7..0000000000 --- a/scanners/zap-advanced/scanner/README.md +++ /dev/null @@ -1,47 +0,0 @@ - - -# ZAP Scanner - -This directory contains a secureCodeBox specific python implementation of an ZAP Client. - -## Testing -If you want to test the ZAP Client localy you can use - -```bash -# test everything combined -make test -# start only unit tests -make unit-test -# start only docker base tests -make docker-test -# start only local zap based tests -make local-test -``` - -### Local testing with an already running ZAP instance (at localhost) -If you want to run the local test directly based on pytest you can do so. -Please configure `test_integration_zap_local.py` before running with your ZAP _host_ and _port_ address: - -```bash -pytest ./tests/test_integration_zap_local.py --log-cli-level "DEBUG" -``` - -### Docker based testing -If you want to run the local test directly based on pytest you can do so. - -```bash -pytest ./tests/test_integration_docker_local.py --log-cli-level "DEBUG" -``` - -## Additional reading and sources -* https://realpython.com/documenting-python-code/ -* https://docs.python.org/3/howto/logging-cookbook.html#logging-cookbook -* https://pypi.org/project/HiYaPyCo/ -* https://github.com/zaproxy/zap-api-python/blob/master/src/examples/zap_example_api_script.py -* Python Package Structure: - * https://docs.pytest.org/en/stable/goodpractices.html - * https://blog.ionelmc.ro/2014/05/25/python-packaging/#the-structure diff --git a/scanners/zap-advanced/scanner/docker-compose.demo-apps.yaml b/scanners/zap-advanced/scanner/docker-compose.demo-apps.yaml deleted file mode 100644 index cdae4af962..0000000000 --- a/scanners/zap-advanced/scanner/docker-compose.demo-apps.yaml +++ /dev/null @@ -1,61 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -version: "3" -services: - bodgeit: - image: docker.io/psiinon/bodgeit:latest - deploy: - replicas: 1 - restart_policy: - condition: on-failure - ports: - - "8080:8080" - healthcheck: - interval: 1m - retries: 3 - test: - - CMD - - curl - - -f - - http://bodgeit:8080/bodgeit/ - timeout: 10s - juiceshop: - image: docker.io/bkimminich/juice-shop:latest - deploy: - replicas: 1 - restart_policy: - condition: on-failure - ports: - - "3000:3000" - healthcheck: - interval: 1m - retries: 3 - test: - - CMD - - wget - - --spider - - http://juiceshop:3000/#/ - timeout: 10s - petstore: - image: docker.io/swaggerapi/petstore - deploy: - replicas: 1 - restart_policy: - condition: on-failure - ports: - - "8000:8080" - environment: - - SWAGGER_BASE_PATH=/v2 - - SWAGGER_HOST=http://localhost:8000 - - SWAGGER_URL=http://localhost:8000 - # healthcheck: - # interval: 1m - # retries: 3 - # test: - # - CMD - # - wget - # - --spider - # - http://petstore/ - # timeout: 10s diff --git a/scanners/zap-advanced/scanner/docker-compose.test.yaml b/scanners/zap-advanced/scanner/docker-compose.test.yaml deleted file mode 100644 index f39b6109ba..0000000000 --- a/scanners/zap-advanced/scanner/docker-compose.test.yaml +++ /dev/null @@ -1,111 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -version: "3" -services: - bodgeit: - image: docker.io/psiinon/bodgeit:latest - deploy: - replicas: 1 - restart_policy: - condition: on-failure - ports: - - "8080:8080" - healthcheck: - interval: 1m - retries: 3 - test: - - CMD - - curl - - -f - - http://bodgeit:8080/bodgeit/ - timeout: 10s - juiceshop: - image: docker.io/bkimminich/juice-shop:latest - deploy: - replicas: 1 - restart_policy: - condition: on-failure - ports: - - "3000:3000" - healthcheck: - interval: 1m - retries: 3 - test: - - CMD - - wget - - --spider - - http://juiceshop:3000/#/ - timeout: 10s - petstore: - image: docker.io/swaggerapi/petstore - deploy: - replicas: 1 - restart_policy: - condition: on-failure - ports: - - "8000:8080" - environment: - - SWAGGER_BASE_PATH=/v2 - - SWAGGER_HOST=http://localhost:8000 - - SWAGGER_URL=http://localhost:8000 - # healthcheck: - # interval: 1m - # retries: 3 - # test: - # - CMD - # - wget - # - --spider - # - http://petstore/ - # timeout: 10s - zap: - image: owasp/zap2docker-stable:latest - deploy: - replicas: 1 - restart_policy: - condition: on-failure - ports: - - "8090:8090" - links: - - "bodgeit:bodgeit" - - "juiceshop:juiceshop" - - "petstore:petstore" - depends_on: - - "bodgeit" - - "juiceshop" - - "petstore" - volumes: - - ./scripts/authentication:/home/zap/.ZAP_D/scripts/scripts/authentication - - ./scripts/session:/home/zap/.ZAP_D/scripts/scripts/session - entrypoint: - - "zap.sh" - - "-daemon" - - "-port" - - "8090" - - "-host" - - "0.0.0.0" - - "-config" - - "api.addrs.addr.name=.*" - - "-config" - - "api.addrs.addr.regex=true" - - "-config" - - "api.disablekey=true" - #- '-addonupdate' - #- '-addoninstall' - #- 'pscanrulesBeta' - #- '-addoninstall' - #- 'ascanrulesBeta' - #- '-addoninstall' - #- 'pscanrulesAlpha' - #- '-addoninstall' - #- 'ascanrulesAlpha' - healthcheck: - interval: 1m30s - retries: 3 - test: - - CMD - - curl - - -f - - http://zap:8090/UI/core/ - timeout: 10s diff --git a/scanners/zap-advanced/scanner/docker-compose.yaml b/scanners/zap-advanced/scanner/docker-compose.yaml deleted file mode 100644 index 2769d5539f..0000000000 --- a/scanners/zap-advanced/scanner/docker-compose.yaml +++ /dev/null @@ -1,154 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -version: "3" -services: - bodgeit: - image: docker.io/psiinon/bodgeit:latest - deploy: - replicas: 1 - restart_policy: - condition: on-failure - ports: - - "8080:8080" - healthcheck: - interval: 1m - retries: 3 - test: - - CMD - - curl - - -f - - http://bodgeit:8080/bodgeit/ - timeout: 10s - juiceshop: - image: docker.io/bkimminich/juice-shop:latest - deploy: - replicas: 1 - restart_policy: - condition: on-failure - ports: - - "3000:3000" - healthcheck: - interval: 1m - retries: 3 - test: - - CMD - - wget - - --spider - - http://juiceshop:3000/#/ - timeout: 10s - petstore: - image: docker.io/swaggerapi/petstore - deploy: - replicas: 1 - restart_policy: - condition: on-failure - ports: - - "8000:8080" - environment: - - SWAGGER_BASE_PATH=/v2 - - SWAGGER_HOST=http://localhost:8000 - - SWAGGER_URL=http://localhost:8000 - # healthcheck: - # interval: 1m - # retries: 3 - # test: - # - CMD - # - wget - # - --spider - # - http://petstore/ - # timeout: 10s - zap: - image: owasp/zap2docker-stable:latest - deploy: - replicas: 1 - restart_policy: - condition: on-failure - ports: - - "8090:8090" - links: - - "bodgeit:bodgeit" - - "juiceshop:juiceshop" - - "petstore:petstore" - depends_on: - - "bodgeit" - - "juiceshop" - - "petstore" - volumes: - - ./scripts/authentication:/home/zap/.ZAP_D/scripts/scripts/authentication - - ./scripts/session:/home/zap/.ZAP_D/scripts/scripts/session - entrypoint: - - "zap.sh" - - "-daemon" - - "-port" - - "8090" - - "-host" - - "0.0.0.0" - - "-config" - - "api.addrs.addr.name=.*" - - "-config" - - "api.addrs.addr.regex=true" - - "-config" - - "api.disablekey=true" - #- '-addonupdate' - #- '-addoninstall' - #- 'pscanrulesBeta' - #- '-addoninstall' - #- 'ascanrulesBeta' - #- '-addoninstall' - #- 'pscanrulesAlpha' - #- '-addoninstall' - #- 'ascanrulesAlpha' - healthcheck: - interval: 1m30s - retries: 3 - test: - - CMD - - curl - - -f - - http://zap:8090/UI/core/ - timeout: 10s - automation: - build: - context: ./ - deploy: - replicas: 1 - restart_policy: - condition: none - links: - - "zap:zap" - depends_on: - - "bodgeit" - - "juiceshop" - - "zap" - # environment: - # - SCB_ZAP_CONFIG_DIR="/zap/secureCodeBox-extensions/configs/" - volumes: - - ./tests/mocks/scan-full-petstore-docker/:/home/securecodebox/configs/ - - ./tests/results/:/home/securecodebox/results/ - entrypoint: - [ - "python3", - "-m", - "zapclient", - "--report-type", - "XML", - "--zap-url", - "zap:8090", - "--output-folder", - "/home/securecodebox/results/", - "--config-folder", - "/home/securecodebox/configs/", - "-t", - "http://petstore:8080/", - ] - # healthcheck: - # interval: 1m30s - # retries: 3 - # test: - # - CMD - # - curl - # - -f - # - http://zap:8090/UI/core/ - # timeout: 10s diff --git a/scanners/zap-advanced/scanner/pytest.ini b/scanners/zap-advanced/scanner/pytest.ini deleted file mode 100644 index bc7b0e7a0b..0000000000 --- a/scanners/zap-advanced/scanner/pytest.ini +++ /dev/null @@ -1,10 +0,0 @@ -; SPDX-FileCopyrightText: the secureCodeBox authors -; -; SPDX-License-Identifier: Apache-2.0 - -[pytest] -markers = - integrationtest: mark a test as a integration test. - unit: mark a test as a unit test. - - slow: mark test as slow. \ No newline at end of file diff --git a/scanners/zap-advanced/scanner/requirements.txt b/scanners/zap-advanced/scanner/requirements.txt deleted file mode 100644 index 4aee8e1e10..0000000000 --- a/scanners/zap-advanced/scanner/requirements.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -python-owasp-zap-v2.4==0.0.20 -HiYaPyCo==0.4.16 -MarkupSafe==2.0.1 diff --git a/scanners/zap-advanced/scanner/scripts/README.md b/scanners/zap-advanced/scanner/scripts/README.md deleted file mode 100644 index 32f9cc7e0a..0000000000 --- a/scanners/zap-advanced/scanner/scripts/README.md +++ /dev/null @@ -1,55 +0,0 @@ - - -# ZAP Scripts - -This folder contains ZAP scripts. The scripts must be in subdirectories named after the -relevant script type (such as "active", "passive", "authentication", etc.) and must have -an appropriate extension for the script language used. - -## Naming Schema - -Our custom ZAP scripts follow a naming schema: - -- always lowercase, -- only dash (`-`) no underscore (`_`), -- always start with the prefix `scb-`, -- then describe the protocol, type or such (eg. oidc, basic-auth, propretary, etc.), and -- a short descriptive part. - -## How to add them in the Desktop UI - -1. Click the plus sign in the left panel beneath the "Site" tab. -2. Click ob the popping up "Scripts". -3. Click on the gearwheel of the new "Scripts" tab. -4. Click "Add..." in the popping up "Options" dialog. -5. Navigate to this folder and select it. -6. Click "OK" in the "Options" dialog. -7. The scripts should appear in the according category. - -You can either edit the script in ZAP or in your favorite editor. - -## Setup the Authentication Scripts in the Desktop UI - -1. Double click your context for editing. -2. Go to "Authentication" - 1. Select "Script based Authentication" in the dropdown. - 2. Select "oidc-grandtype-password-auth.js" in the script dropdown" - 3. Click "Load". - 4. TODO doc the params -3. Go to Users - 1. Click "Add..." - 2. Fill the form with the basic auth user credentials from LastPass. - 3. Click "Add". -4. Go to "Session Management" - 1. Select "Script based Session Management" in the dropdown. - 2. Click "Load". -5. Click "OK" - -## Various Links - -- -- diff --git a/scanners/zap-advanced/scanner/scripts/authentication/scb-oidc-password-grand-type.js b/scanners/zap-advanced/scanner/scripts/authentication/scb-oidc-password-grand-type.js deleted file mode 100644 index e274f56100..0000000000 --- a/scanners/zap-advanced/scanner/scripts/authentication/scb-oidc-password-grand-type.js +++ /dev/null @@ -1,104 +0,0 @@ -// SPDX-FileCopyrightText: the secureCodeBox authors -// -// SPDX-License-Identifier: Apache-2.0 - -var HttpRequestHeader = Java.type("org.parosproxy.paros.network.HttpRequestHeader"), - HttpHeader = Java.type("org.parosproxy.paros.network.HttpHeader"), - URI = Java.type("org.apache.commons.httpclient.URI"); -/** - * OIDC Password Grant Type based authentication script for ZAP. - * - * This authenticate function is called whenever ZAP requires to authenticate, - * for a Context which has this script selected as the authentication method. - * - * This function should send any messages that are required to do the authentication - * and should return a message with an authenticated response. - * - * This auth is based on the grand type "password" to retrieve fresh tokens: - * https://developer.okta.com/blog/2018/06/29/what-is-the-oauth2-password-grant - * - * For Authentication select/configure in your ZAP Context: - * - * - Authentication method: ScriptBased Authentication - * - Login FORM target URL: https://$keycloak-url/auth/realms/$app/protocol/openid-connect/token - * - username parameter: your-username-to-get-tokens - * - password parameter: your-password-to-get-tokens - * - Logged out regex: ".*Credentials are required to access this resource.*" - * - * NOTE: Any message sent in the function should be obtained using the 'helper.prepareMessage()' - * method. - * - * @param {Object} helper - Helper class providing useful methods: prepareMessage(), sendAndReceive(msg). - * @param {Object} paramsValues - Values of the parameters configured in the Session Properties -> Authentication panel. - * The paramsValues is a map with parameters names as keys (like returned - * by the getRequiredParamsNames() and getOptionalParamsNames() functions below). - * @param {Object} credentials - Object containing the credentials configured in the Session Properties -> Users panel. - * The credential values can be obtained via calls to the getParam(paramName) method. - * The param names are the ones returned by the getCredentialsParamsNames() below. - */ -function authenticate(helper, paramsValues, credentials) { - print("Authentication via scb-oidc-password-grand-type.js..."); - - // Prepare the login request details - var url = paramsValues.get("URL"); - var clientId = paramsValues.get("clientId"); - print("Logging in to url: " + url + " clientId: " + clientId); - - var requestUri = new URI(url, false); - var requestMethod = HttpRequestHeader.POST; - - // Build the request body using the credentials values - // This auth is based on the grand type "password" to retrieve fresh tokens - // https://developer.okta.com/blog/2018/06/29/what-is-the-oauth2-password-grant - var requestBody = "grant_type=password&client_id=" + clientId + "&username=" + credentials.getParam("username") + "&password=" + credentials.getParam("password"); - - // Build the actual message to be sent - print("Sending " + requestMethod + " request to " + requestUri + " with body: " + requestBody); - var msg = helper.prepareMessage(); - msg.setRequestBody(requestBody); - - var requestHeader = new HttpRequestHeader(requestMethod, requestUri, HttpHeader.HTTP10); - msg.setRequestHeader(requestHeader); - print("Msg prepared") - - // Send the authentication message and return it - try { - helper.sendAndReceive(msg); - print("Received response status code for authentication request: " + msg.getResponseHeader().getStatusCode()); - return msg; - } catch (err) { - print("Got error"); - print(err); - } - - return null -} - -/** - * This function is called during the script loading to obtain a list of required configuration parameter names. - * - * These names will be shown in the Session Properties -> Authentication panel for configuration. They can be used - * to input dynamic data into the script, from the user interface (e.g. a login URL, name of POST parameters etc.). - */ -function getRequiredParamsNames() { - return ["URL", "clientId"]; -} - -/** - * This function is called during the script loading to obtain a list of optional configuration parameter names. - * - * These will be shown in the Session Properties -> Authentication panel for configuration. They can be used - * to input dynamic data into the script, from the user interface (e.g. a login URL, name of POST parameters etc.). - */ -function getOptionalParamsNames() { - return []; -} - -/** - * This function is called during the script loading to obtain a list of required credential parameter names. - * - * They are configured for each user corresponding to an authentication using this script. - */ -function getCredentialsParamsNames() { - return ["username", "password"]; -} \ No newline at end of file diff --git a/scanners/zap-advanced/scanner/scripts/session/juiceshop-session-management.js b/scanners/zap-advanced/scanner/scripts/session/juiceshop-session-management.js deleted file mode 100644 index a63763a50b..0000000000 --- a/scanners/zap-advanced/scanner/scripts/session/juiceshop-session-management.js +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-FileCopyrightText: the secureCodeBox authors -// -// SPDX-License-Identifier: Apache-2.0 - -/* - * Session Management script for OWASP Juice Shop: https://raw.githubusercontent.com/zaproxy/community-scripts/master/session/Juice%20Shop%20Session%20Management.js - * - * For Authentication select: - * Authentication method: JSON-based authentication - * Login FORM target URL: http://localhost:3000/rest/user/login - * URL to GET Login Page: http://localhost:3000/ - * Login Request POST data: {"email":"test@test.com","password":"test1"} - * Username Parameter: email - * Password Parameter: password - * Logged out regex: \Q{"user":{}}\E - * - * Obviously update with any local changes as necessary. - */ - -var COOKIE_TYPE = org.parosproxy.paros.network.HtmlParameter.Type.cookie; -var HtmlParameter = Java.type('org.parosproxy.paros.network.HtmlParameter') -var ScriptVars = Java.type('org.zaproxy.zap.extension.script.ScriptVars'); - -function extractWebSession(sessionWrapper) { - // parse the authentication response - var json = JSON.parse(sessionWrapper.getHttpMessage().getResponseBody().toString()); - var token = json.authentication.token; - // save the authentication token - sessionWrapper.getSession().setValue("token", token); - ScriptVars.setGlobalVar("juiceshop.token", token); -} - -function clearWebSessionIdentifiers(sessionWrapper) { - var headers = sessionWrapper.getHttpMessage().getRequestHeader(); - headers.setHeader("Authorization", null); - ScriptVars.setGlobalVar("juiceshop.token", null); -} - -function processMessageToMatchSession(sessionWrapper) { - var token = sessionWrapper.getSession().getValue("token"); - if (token === null) { - print('JS mgmt script: no token'); - return; - } - var cookie = new HtmlParameter(COOKIE_TYPE, "token", token); - // add the saved authentication token as an Authentication header and a cookie - var msg = sessionWrapper.getHttpMessage(); - msg.getRequestHeader().setHeader("Authorization", "Bearer " + token); - var cookies = msg.getRequestHeader().getCookieParams(); - cookies.add(cookie); - msg.getRequestHeader().setCookieParams(cookies); -} - -function getRequiredParamsNames() { - return []; -} - -function getOptionalParamsNames() { - return []; -} diff --git a/scanners/zap-advanced/scanner/scripts/session/scb-oidc-session-management.js b/scanners/zap-advanced/scanner/scripts/session/scb-oidc-session-management.js deleted file mode 100644 index f9a2c8be6c..0000000000 --- a/scanners/zap-advanced/scanner/scripts/session/scb-oidc-session-management.js +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-FileCopyrightText: the secureCodeBox authors -// -// SPDX-License-Identifier: Apache-2.0 - -/** - * Session Management script for OIDC Authentication. - * - * Adapted from OWASP Juice Shop Example: https://www.zaproxy.org/blog/2020-06-04-zap-2-9-0-highlights/ - */ - -function extractWebSession(sessionWrapper) { - print("extractWebSession") - // parse the authentication response - var json = JSON.parse(sessionWrapper.getHttpMessage().getResponseBody().toString()); - var token = json.access_token; - // save the authentication token - sessionWrapper.getSession().setValue("token", token); -} - -function clearWebSessionIdentifiers(sessionWrapper) { - print("clearWebSessionIdentifiers") - var headers = sessionWrapper.getHttpMessage().getRequestHeader(); - headers.setHeader("Authorization", null); -} - -function processMessageToMatchSession(sessionWrapper) { - print("processMessageToMatchSession") - var token = sessionWrapper.getSession().getValue("token"); - if (token === null) { - print('JS mgmt script: no token'); - return; - } - - // add the saved authentication token as an Authentication header and a cookie - var msg = sessionWrapper.getHttpMessage(); - msg.getRequestHeader().setHeader("Authorization", "Bearer " + token); -} - -/** - * This function is called during the script loading to obtain a list of required configuration parameter names. - * - * These names will be shown in the Session Properties -> Authentication panel for configuration. They can be used - * to input dynamic data into the script, from the user interface (e.g. a login URL, name of POST parameters etc.). - */ -function getRequiredParamsNames() { - return []; -} - -/** - * This function is called during the script loading to obtain a list of optional configuration parameter names. - * - * These will be shown in the Session Properties -> Authentication panel for configuration. They can be used - * to input dynamic data into the script, from the user interface (e.g. a login URL, name of POST parameters etc.). - */ -function getOptionalParamsNames() { - return []; -} diff --git a/scanners/zap-advanced/scanner/test-requirements.txt b/scanners/zap-advanced/scanner/test-requirements.txt deleted file mode 100644 index c30fe78320..0000000000 --- a/scanners/zap-advanced/scanner/test-requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -pytest-docker==0.10.1 \ No newline at end of file diff --git a/scanners/zap-advanced/scanner/tests/__init__.py b/scanners/zap-advanced/scanner/tests/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/scanners/zap-advanced/scanner/tests/mocks/cascading-scan-full-local/1_zap-advanced-scan-config.yaml b/scanners/zap-advanced/scanner/tests/mocks/cascading-scan-full-local/1_zap-advanced-scan-config.yaml deleted file mode 100644 index 8c878c09f7..0000000000 --- a/scanners/zap-advanced/scanner/tests/mocks/cascading-scan-full-local/1_zap-advanced-scan-config.yaml +++ /dev/null @@ -1,87 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -# Global ZAP Configurations -global: - # Sets the ZAP Session name - sessionName: scb-security-test - # -- Updates all installed ZAP AddOns on startup if true, otherwise false. - addonUpdate: false - # -- Installs additional ZAP AddOns on startup, listed by their name: - addonInstall: - - pscanrulesBeta - - ascanrulesBeta - # Sets the mode, which may be one of [safe, protect, standard, attack] - mode: standard - # Sets the user agent that ZAP should use when creating HTTP messages (for example, spider messages or CONNECT requests to outgoing proxy). - defaultUserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/92.0.4515.159 secureCodeBox/3.1.0" - -# ZAP Contexts Configuration -contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: scb-test-context - # The top level url, mandatory, everything under this will be included - # An optional list of regexes to exclude - excludePaths: - - ".*socket\\.io.*" - - ".*\\.png" - - ".*\\.jpeg" - - ".*\\.jpg" - - ".*\\.woff" - - ".*\\.woff2" - - ".*\\.ttf" - - ".*\\.ico" - -apis: [] - -# ZAP Spiders Configuration -spiders: - - name: scb-test-spider - # String: Name of the context to spider, default: first context - context: scb-test-context - # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 10 - # Int: The maximum tree depth to explore, default 5 - maxDepth: 5 - # Int: The maximum number of children to add to each node in the tree - maxChildren: 10 - # -- Bool: Whether to use the ZAP ajax spider, default: false - ajax: true - # -- Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # -- Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # -- Bool: Whether the spider will accept cookies, default: true - acceptCookies: true - # -- Bool: Whether the spider will handle OData responses, default: false - handleODataParametersVisited: false - # -- Enum [ignore_completely, ignore_value, use_all]: How query string parameters are used when checking if a URI has already been visited, default: use_all - handleParameters: use_all - # -- Int: The max size of a response that will be parsed, default: 2621440 - 2.5 Mb - maxParseSizeBytes: 2621440 - # -- Bool: Whether the spider will parse HTML comments in order to find URLs, default: true - parseComments: true - -# ZAP ActiveScans Configuration -scanners: - - name: scb-test-scan - # String: Name of the context to attack, default: first context - context: scb-test-context - # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 5 - # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 120 - # Int: The max number of threads per host, default: 2 - threadPerHost: 2 - # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false diff --git a/scanners/zap-advanced/scanner/tests/mocks/context-using-forced-context/1_zap-advanced-scan-config.yaml b/scanners/zap-advanced/scanner/tests/mocks/context-using-forced-context/1_zap-advanced-scan-config.yaml deleted file mode 100644 index f924a88dc6..0000000000 --- a/scanners/zap-advanced/scanner/tests/mocks/context-using-forced-context/1_zap-advanced-scan-config.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -contexts: - - name: scb-bodgeit-context - url: http://bodgeit:8080/bodgeit/ - - name: scb-test-context - url: http://test.example.com -spiders: - - name: scb-test-spider - context: scb-test-context - - name: should-not-take-this-spider - context: scb-bodgeit-context -scanners: - - name: should-not-take-this-scanner - context: scb-bodgeit-context - - name: scb-test-scanner - context: scb-test-context diff --git a/scanners/zap-advanced/scanner/tests/mocks/context-with-overlay-secrets/1_zap-advanced-scan-type-config.yaml b/scanners/zap-advanced/scanner/tests/mocks/context-with-overlay-secrets/1_zap-advanced-scan-type-config.yaml deleted file mode 100644 index db4de5c096..0000000000 --- a/scanners/zap-advanced/scanner/tests/mocks/context-with-overlay-secrets/1_zap-advanced-scan-type-config.yaml +++ /dev/null @@ -1,73 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -# List of 1 or more contexts, mandatory -contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: secureCodeBoxScan-Script-Based - # The top level url, mandatory, everything under this will be included - url: https://www.secureCodeBox.io/ - # An optional list of regexes to include - includePaths: - - "https://www.secureCodeBox.io/.*" - # An optional list of regexes to exclude - excludePaths: - - "https://www.secureCodeBox.io/authserver/v1/.*" - - ".*\\.js" - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - # Optional technology list - technologies: - included: - - Db.CouchDB - - Db.Firebird - - Db.HypersonicSQL - - Language.ASP - - OS - excluded: - - SCM - # Auth Credentials for the scanner to access the application - # Can be either basicAuth or a oidc token. - # If both are set, the oidc token takes precedent - authentication: - # Currently supports "basic-auth", "form-based", "json-based", "script-based" - type: "script-based" - # script-based - script-based: - name: "scb-oidc-password-grand-type.js" - # Script engine values: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - engine: "Oracle Nashorn" - # Must be a full path to the script file inside the ZAP container (corresponding to the configMap FileMount) - filePath: "/home/zap/.ZAP_D/scripts/scripts/authentication/scb-oidc-password-grand-type.js" - description: "This is a description for the SCB OIDC Script." - arguments: - URL: "https://www.secureCodeBox.io/authserver/" - email: "secureCodeBox@teratec.com" - # should have at least the role "reserved_view_swagger" to access the OpenAPI spec - sub: "secureCodeBox@iteratec.com" - exp: "1609459140" - # Indicates if the current Zap User Session is based on a valid authentication (loggedIn) or not (loggedOut) - verification: - isLoggedInIndicator: "(.*Credentials are required to access this resource.*)|(.*Verifying token failed*)" - isLoggedOutIndicator: ".*User is not Authenticated.*" - users: - - name: "script-based-user-1" - username: "script-based-user-1" - password: "script-based-password-1" - - name: "script-based-user-2" - username: "script-based-user-2" - password: "script-based-password-2" - session: - # Currently supports "scriptBasedSessionManagement", "cookieBasedSessionManagement", "httpAuthSessionManagement" - type: "scriptBasedSessionManagement" - # basic-auth requires no further configuration - scriptBasedSessionManagement: - name: "juiceshop-session-management.js" - # Script engine values: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - engine: "Oracle Nashorn" - # Must be a full path to the script file inside the ZAP container (corresponding to the configMap FileMount) - filePath: "/home/zap/.ZAP_D/scripts/scripts/session/juiceshop-session-management.js" - description: "This is a JuiceShop specific SessionManagement Script used to handle JWT." diff --git a/scanners/zap-advanced/scanner/tests/mocks/context-with-overlay-secrets/2_zap-advanced-scan-type-secret.yaml b/scanners/zap-advanced/scanner/tests/mocks/context-with-overlay-secrets/2_zap-advanced-scan-type-secret.yaml deleted file mode 100644 index 5c40a62c2b..0000000000 --- a/scanners/zap-advanced/scanner/tests/mocks/context-with-overlay-secrets/2_zap-advanced-scan-type-secret.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -# List of 1 or more contexts, mandatory -contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: secureCodeBoxScan-Script-Based - users: - - name: "script-based-user-1" - username: "script-based-user-1" - password: "script-based-password-1" - - name: "script-based-user-2" - username: "script-based-user-2" - password: "script-based-password-2" diff --git a/scanners/zap-advanced/scanner/tests/mocks/context-with-overlay-secrets/3_zap-advanced-scan-config.yaml b/scanners/zap-advanced/scanner/tests/mocks/context-with-overlay-secrets/3_zap-advanced-scan-config.yaml deleted file mode 100644 index f091c41ac0..0000000000 --- a/scanners/zap-advanced/scanner/tests/mocks/context-with-overlay-secrets/3_zap-advanced-scan-config.yaml +++ /dev/null @@ -1,48 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -# List of 1 or more contexts, mandatory -contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: secureCodeBoxScan-Script-Based - # Name to be used to refer to this context in other jobs, mandatory - - name: secureCodeBox-Basic-Auth - # The top level url, mandatory, everything under this will be included - url: https://www.secureCodeBox.io/ - # An optional list of regexes to include - includePaths: - - "https://www.secureCodeBox.io/.*" - # An optional list of regexes to exclude - excludePaths: - - "https://www.secureCodeBox.io/authserver/v1/.*" - - ".*\\.js" - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - # Auth Credentials for the scanner to access the application - # Can be either basicAuth or a oidc token. - # If both are set, the oidc token takes precedent - authentication: - # Currently supports "basic-auth", "form-based", "json-based", "script-based" - type: "basic-auth" - # basic-auth requires no further configuration - basic-auth: - hostname: "https://www.secureCodeBox.io" - realm: "CORP\\administrator" - port: 8080 - # Indicates if the current Zap User Session is based on a valid authentication (loggedIn) or not (loggedOut) - verification: - isLoggedInIndicator: "(.*Credentials are required to access this resource.*)|(.*Verifying token failed*)" - isLoggedOutIndicator: ".*User is not Authenticated.*" - users: - - name: "basic-auth-user-1" - username: "basic-auth-user-1" - password: "basic-auth-password-1" - - name: "basic-auth-user-2" - username: "basic-auth-user-2" - password: "basic-auth-password-2" - session: - # Currently supports "scriptBasedSessionManagement", "cookieBasedSessionManagement", "httpAuthSessionManagement" - type: "httpAuthSessionManagement" diff --git a/scanners/zap-advanced/scanner/tests/mocks/context-with-overlay-secrets/4_zap-advanced-scan-config-secret.yaml b/scanners/zap-advanced/scanner/tests/mocks/context-with-overlay-secrets/4_zap-advanced-scan-config-secret.yaml deleted file mode 100644 index fa513da13c..0000000000 --- a/scanners/zap-advanced/scanner/tests/mocks/context-with-overlay-secrets/4_zap-advanced-scan-config-secret.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -# List of 1 or more contexts, mandatory -contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: secureCodeBoxScan-Script-Based - # Name to be used to refer to this context in other jobs, mandatory - - name: secureCodeBox-Basic-Auth - users: - - name: "basic-auth-user-1" - username: "basic-auth-user-1" - password: "basic-auth-password-1" - - name: "basic-auth-user-2" - username: "basic-auth-user-2" - password: "basic-auth-password-2" diff --git a/scanners/zap-advanced/scanner/tests/mocks/context-with-overlay/1_zap-advanced-scan-type-config.yaml b/scanners/zap-advanced/scanner/tests/mocks/context-with-overlay/1_zap-advanced-scan-type-config.yaml deleted file mode 100644 index 2900598216..0000000000 --- a/scanners/zap-advanced/scanner/tests/mocks/context-with-overlay/1_zap-advanced-scan-type-config.yaml +++ /dev/null @@ -1,21 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -# List of 1 or more contexts, mandatory -contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: secureCodeBoxScanType-NoAuth - # The top level url, mandatory, everything under this will be included - url: https://www.secureCodeBox.io/ - # An optional list of regexes to include - includePaths: - - "https://www.secureCodeBox.io/.*" - # An optional list of regexes to exclude - excludePaths: - - "https://www.secureCodeBox.io/authserver/v1/.*" - - ".*\\.js" - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" diff --git a/scanners/zap-advanced/scanner/tests/mocks/context-with-overlay/2_zap-advanced-scan-config.yaml b/scanners/zap-advanced/scanner/tests/mocks/context-with-overlay/2_zap-advanced-scan-config.yaml deleted file mode 100644 index ca95bdfd91..0000000000 --- a/scanners/zap-advanced/scanner/tests/mocks/context-with-overlay/2_zap-advanced-scan-config.yaml +++ /dev/null @@ -1,190 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -# List of 1 or more contexts, mandatory -contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: secureCodeBoxScanType-NoAuth - # Name to be used to refer to this context in other jobs, mandatory - - name: secureCodeBoxScan-Script-Based - # The top level url, mandatory, everything under this will be included - url: https://www.secureCodeBox.io/ - # An optional list of regexes to include - includePaths: - - "https://www.secureCodeBox.io/.*" - # An optional list of regexes to exclude - excludePaths: - - "https://www.secureCodeBox.io/authserver/v1/.*" - - ".*\\.js" - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - # Optional technology list - technologies: - included: - - Db.CouchDB - - Db.Firebird - - Db.HypersonicSQL - - Language.ASP - - OS - excluded: - - SCM - # Auth Credentials for the scanner to access the application - # Can be either basicAuth or a oidc token. - # If both are set, the oidc token takes precedent - authentication: - # Currently supports "basic-auth", "form-based", "json-based", "script-based" - type: "script-based" - # script-based - script-based: - name: "scb-oidc-password-grand-type.js" - # Script engine values: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - engine: "Oracle Nashorn" - # Must be a full path to the script file inside the ZAP container (corresponding to the configMap FileMount) - filePath: "/home/zap/.ZAP_D/scripts/scripts/authentication/scb-oidc-password-grand-type.js" - description: "This is a description for the SCB OIDC Script." - arguments: - URL: "https://www.secureCodeBox.io/authserver/" - email: "secureCodeBox@teratec.com" - # should have at least the role "reserved_view_swagger" to access the OpenAPI spec - sub: "secureCodeBox@iteratec.com" - exp: "1609459140" - # Indicates if the current Zap User Session is based on a valid authentication (loggedIn) or not (loggedOut) - verification: - isLoggedInIndicator: "(.*Credentials are required to access this resource.*)|(.*Verifying token failed*)" - isLoggedOutIndicator: ".*User is not Authenticated.*" - users: - - name: "script-based-user-1" - username: "script-based-user-1" - password: "script-based-password-1" - - name: "script-based-user-2" - username: "script-based-user-2" - password: "script-based-password-2" - session: - # Currently supports "scriptBasedSessionManagement", "cookieBasedSessionManagement", "httpAuthSessionManagement" - type: "scriptBasedSessionManagement" - # basic-auth requires no further configuration - scriptBasedSessionManagement: - name: "juiceshop-session-management.js" - # Script engine values: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - engine: "Oracle Nashorn" - # Must be a full path to the script file inside the ZAP container (corresponding to the configMap FileMount) - filePath: "/home/zap/.ZAP_D/scripts/scripts/session/juiceshop-session-management.js" - description: "This is a JuiceShop specific SessionManagement Script used to handle JWT." - # Name to be used to refer to this context in other jobs, mandatory - - name: secureCodeBox-Basic-Auth - # The top level url, mandatory, everything under this will be included - url: https://www.secureCodeBox.io/ - # An optional list of regexes to include - includePaths: - - "https://www.secureCodeBox.io/.*" - # An optional list of regexes to exclude - excludePaths: - - "https://www.secureCodeBox.io/authserver/v1/.*" - - ".*\\.js" - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - # Auth Credentials for the scanner to access the application - # Can be either basicAuth or a oidc token. - # If both are set, the oidc token takes precedent - authentication: - # Currently supports "basic-auth", "form-based", "json-based", "script-based" - type: "basic-auth" - # basic-auth requires no further configuration - basic-auth: - hostname: "https://www.secureCodeBox.io" - realm: "CORP\\administrator" - port: 8080 - # Indicates if the current Zap User Session is based on a valid authentication (loggedIn) or not (loggedOut) - verification: - isLoggedInIndicator: "(.*Credentials are required to access this resource.*)|(.*Verifying token failed*)" - isLoggedOutIndicator: ".*User is not Authenticated.*" - users: - - name: "basic-auth-user-1" - username: "basic-auth-user-1" - password: "basic-auth-password-1" - - name: "basic-auth-user-2" - username: "basic-auth-user-2" - password: "basic-auth-password-2" - session: - # Currently supports "scriptBasedSessionManagement", "cookieBasedSessionManagement", "httpAuthSessionManagement" - type: "httpAuthSessionManagement" - # Name to be used to refer to this context in other jobs, mandatory - - name: secureCodeBox-Form-Based - # The top level url, mandatory, everything under this will be included - url: https://www.secureCodeBox.io/ - # An optional list of regexes to include - includePaths: - - "https://www.secureCodeBox.io/.*" - # An optional list of regexes to exclude - excludePaths: - - "https://www.secureCodeBox.io/authserver/v1/.*" - - ".*\\.js" - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - # Auth Credentials for the scanner to access the application - # Can be either basicAuth or a oidc token. - # If both are set, the oidc token takes precedent - authentication: - # Currently supports "basic-auth", "form-based", "json-based", "script-based" - type: "form-based" - # basic-auth requires no further configuration - form-based: - loginUrl: "http://localhost:8090/bodgeit/login.jsp" - # must be escaped already to prevent yaml parser colidations 'username={%username%}&password={%password%}'' - loginRequestData: "username%3D%7B%25username%25%7D%26password%3D%7B%25password%25%7D" - # Indicates if the current Zap User Session is based on a valid authentication (loggedIn) or not (loggedOut) - verification: - isLoggedInIndicator: "\\Q\\E" - isLoggedOutIndicator: "\\Q\\E" - users: - - name: "form-based-user-1" - username: "form-based-user-1" - password: "form-based-password-1" - - name: "form-based-user-2" - username: "form-based-user-2" - password: "form-based-password-2" - session: - # Currently supports "scriptBasedSessionManagement", "cookieBasedSessionManagement", "httpAuthSessionManagement" - type: "cookieBasedSessionManagement" - # Name to be used to refer to this context in other jobs, mandatory - - name: secureCodeBox-Json-Based - # The top level url, mandatory, everything under this will be included - url: https://www.secureCodeBox.io/ - # An optional list of regexes to include - includePaths: - - "https://www.secureCodeBox.io/.*" - # An optional list of regexes to exclude - excludePaths: - - "https://www.secureCodeBox.io/authserver/v1/.*" - - ".*\\.js" - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - # Auth Credentials for the scanner to access the application - # Can be either basicAuth or a oidc token. - # If both are set, the oidc token takes precedent - authentication: - # Currently supports "basic-auth", "form-based", "json-based", "script-based" - type: "json-based" - # basic-auth requires no further configuration - json-based: - loginUrl: "http://localhost:3000/rest/user/login" - # must be escaped already to prevent yaml parser colidations '{"user":{"id":1,"email":"test@test.com"}}'' - loginRequestData: '{"user":{"id":1,"email":"test@test.com"}}' - # Indicates if the current Zap User Session is based on a valid authentication (loggedIn) or not (loggedOut) - verification: - isLoggedInIndicator: "(.*Credentials are required to access this resource.*)|(.*Verifying token failed*)" - isLoggedOutIndicator: ".*User is not Authenticated.*" - users: - - name: "json-based-user-1" - username: "json-based-user-1" - password: "json-based-password-1" - - name: "json-based-user-2" - username: "json-based-user-2" - password: "json-based-password-2" - forced: true diff --git a/scanners/zap-advanced/scanner/tests/mocks/context-without-overlay/1_zap-advanced-scantype-config.yaml b/scanners/zap-advanced/scanner/tests/mocks/context-without-overlay/1_zap-advanced-scantype-config.yaml deleted file mode 100644 index 2900598216..0000000000 --- a/scanners/zap-advanced/scanner/tests/mocks/context-without-overlay/1_zap-advanced-scantype-config.yaml +++ /dev/null @@ -1,21 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -# List of 1 or more contexts, mandatory -contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: secureCodeBoxScanType-NoAuth - # The top level url, mandatory, everything under this will be included - url: https://www.secureCodeBox.io/ - # An optional list of regexes to include - includePaths: - - "https://www.secureCodeBox.io/.*" - # An optional list of regexes to exclude - excludePaths: - - "https://www.secureCodeBox.io/authserver/v1/.*" - - ".*\\.js" - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" diff --git a/scanners/zap-advanced/scanner/tests/mocks/context-without-overlay/2_zap-advanced-scan-config.yaml b/scanners/zap-advanced/scanner/tests/mocks/context-without-overlay/2_zap-advanced-scan-config.yaml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/scanners/zap-advanced/scanner/tests/mocks/empty-files/1_zap-advanced-scan-config.yaml b/scanners/zap-advanced/scanner/tests/mocks/empty-files/1_zap-advanced-scan-config.yaml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/scanners/zap-advanced/scanner/tests/mocks/empty/.gitkeep b/scanners/zap-advanced/scanner/tests/mocks/empty/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/scanners/zap-advanced/scanner/tests/mocks/global/1_zap-advanced-scan-config.yaml b/scanners/zap-advanced/scanner/tests/mocks/global/1_zap-advanced-scan-config.yaml deleted file mode 100644 index 3b36702284..0000000000 --- a/scanners/zap-advanced/scanner/tests/mocks/global/1_zap-advanced-scan-config.yaml +++ /dev/null @@ -1,46 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -# Global ZAP Configurations -global: - # Sets the ZAP Session name - sessionName: SCB - # Sets the connection time out, in seconds. - timeoutInSeconds: - # Sets the mode, which may be one of [safe, protect, standard, attack] - mode: attack - # Sets the user agent that ZAP should use when creating HTTP messages (for example, spider messages or CONNECT requests to outgoing proxy). - defaultUserAgent: "secureCodeBox/2.7.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0" - globalExcludePaths: - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - proxy: - # Define if an outgoing proxy server is used. - enabled: false - # MANDATORY only if useProxyChain is True, ignored otherwise. Outgoing proxy address and port - address: "my.corp.proxy" - port: 8080 - # Define the addresses to skip in case useProxyChain is True. Ignored otherwise. List can be empty. - skipProxyAddresses: - - "127.0.0.1" - - localhost - # MANDATORY only if proxy.enabled is True. Ignored otherwise. Define if proxy server needs authentication - authentication: - # Define if an outgoing proxy server is used with special authentication credentials. - enabled: false - username: "proxy-username" - password: "proxy-password" - realm: "proxy-realm" - socks: - # Define whether or not the SOCKS proxy should be used. - enabled: false - - # Determine if a proxy script must be loaded. Proxy scripts are executed for every request traversing ZAP - scripts: - - name: "Alert on HTTP Response Code Errors.js" - enabled: true - - name: "Alert on Unexpected Content Types.js" - enabled: true diff --git a/scanners/zap-advanced/scanner/tests/mocks/scan-full-bodgeit-docker/1_zap-advanced-scan-config.yaml b/scanners/zap-advanced/scanner/tests/mocks/scan-full-bodgeit-docker/1_zap-advanced-scan-config.yaml deleted file mode 100644 index d7a00be2b2..0000000000 --- a/scanners/zap-advanced/scanner/tests/mocks/scan-full-bodgeit-docker/1_zap-advanced-scan-config.yaml +++ /dev/null @@ -1,131 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -# Global ZAP Configurations - NOT YET IMPLEMENTED -global: - # True to create another ZAP session (overwrite the former if the same name already exists), False to use an existing on - isNewSession: true - # Sets the ZAP Session name - sessionName: SCB - # Sets the connection time out, in seconds. - timeoutInSeconds: 120 - # Sets the mode, which may be one of [safe, protect, standard, attack] - mode: attack - # Sets the user agent that ZAP should use when creating HTTP messages (for example, spider messages or CONNECT requests to outgoing proxy). - defaultUserAgent: "secureCodeBox/2.7.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0" - -# List of 1 or more contexts, mandatory -contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: scb-bodgeit-context - # The top level url, mandatory, everything under this will be included. IMPORTANT: must be the hostname without any subpath! - url: http://bodgeit:8080/bodgeit/ - # An optional list of regexes to include - includePaths: - - "http://bodgeit:8080/bodgeit.*" - # An optional list of regexes to exclude - excludePaths: - - ".*\\.js" - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - # Auth Credentials for the scanner to access the application - # Can be either basicAuth or a oidc token. - # If both are set, the oidc token takes precedent - # More infos about "ZAP Authentication for BodgeIT": https://play.sonatype.com/watch/B1vhaLSUsme7eA5hU8WeGB? - authentication: - # Currently supports "basic-auth", "form-based", "json-based", "script-based" - type: "form-based" - # basic-auth requires no further configuration - form-based: - loginUrl: "http://bodgeit:8080/bodgeit/login.jsp" - # must be escaped already to prevent yaml parser colidations 'username={%username%}&password={%password%}'' - loginRequestData: "username%3D%7B%25username%25%7D%26password%3D%7B%25password%25%7D" - # Indicates if the current Zap User Session is based on a valid authentication (loggedIn) or not (loggedOut) - verification: - isLoggedInIndicator: '\Q\E' - isLoggedOutIndicator: '\QGuest user\E' - users: - - name: bodgeit-user-1 - username: test@thebodgeitstore.com - password: password - forced: true - session: - # Currently supports "scriptBasedSessionManagement", "cookieBasedSessionManagement", "httpAuthSessionManagement" - type: "cookieBasedSessionManagement" - -spiders: - - name: scb-bodgeit-spider - # String: Name of the context to spider, default: first context - context: scb-bodgeit-context - # String: Name of the user to authenticate with and used to spider - user: bodgeit-user-1 - # String: Url to start spidering from, default: first context URL - url: http://bodgeit:8080/bodgeit/ - # Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 1 - # Int: The maximum tree depth to explore, default 5 - maxDepth: 5 - # Int: The maximum number of children to add to each node in the tree - maxChildren: 10 - # # Int: The max size of a response that will be parsed, default: 2621440 - 2.5 Mb - # maxParseSizeBytes: 2621440 - # Bool: Whether the spider will accept cookies, default: true - acceptCookies: true - # Bool: Whether the spider will handle OData responses, default: false - handleODataParametersVisited: false - # Enum [ignore_completely, ignore_value, use_all]: How query string parameters are used when checking if a URI has already been visited, default: use_all - handleParameters: use_all - # Bool: Whether the spider will parse HTML comments in order to find URLs, default: true - parseComments: true - # Bool: Whether the spider will parse Git metadata in order to find URLs, default: false - parseGit: false - # Bool: Whether the spider will parse 'robots.txt' files in order to find URLs, default: true - parseRobotsTxt: true - # Bool: Whether the spider will parse 'sitemap.xml' files in order to find URLs, default: true - parseSitemapXml: false - # Bool: Whether the spider will parse SVN metadata in order to find URLs, default: false - parseSVNEntries: false - # Bool: Whether the spider will submit POST forms, default: true - postForm: true - # Bool: Whether the spider will process forms, default: true - processForm: true - # Int: The time between the requests sent to a server in milliseconds, default: 200 - requestWaitTime: 200 - # Bool: Whether the spider will send the referer header, default: true - sendRefererHeader: true - # Int: The number of spider threads, default: 2 - threadCount: 2 - # String: The user agent to use in requests, default: '' - use the default ZAP one - userAgent: "secureCodeBox / ZAP Spider" - -scanners: - - name: scb-bodgeit-scan - # String: Name of the context to attack, default: first context - context: scb-bodgeit-context - # String: Name of the user to authenticate with and used to spider - user: bodgeit-user-1 - # String: Url to start scaning from, default: first context URL - url: http://bodgeit:8080/bodgeit/ - # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 1 - # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 2 - # Int: The max number of threads per host, default: 2 - threadPerHost: 5 - # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false diff --git a/scanners/zap-advanced/scanner/tests/mocks/scan-full-bodgeit-local/1_zap-advanced-scan-config.yaml b/scanners/zap-advanced/scanner/tests/mocks/scan-full-bodgeit-local/1_zap-advanced-scan-config.yaml deleted file mode 100644 index b03cf34abe..0000000000 --- a/scanners/zap-advanced/scanner/tests/mocks/scan-full-bodgeit-local/1_zap-advanced-scan-config.yaml +++ /dev/null @@ -1,131 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -# Global ZAP Configurations - NOT YET IMPLEMENTED -global: - # True to create another ZAP session (overwrite the former if the same name already exists), False to use an existing on - isNewSession: true - # Sets the ZAP Session name - sessionName: SCB - # Sets the connection time out, in seconds. - timeoutInSeconds: 120 - # Sets the mode, which may be one of [safe, protect, standard, attack] - mode: attack - # Sets the user agent that ZAP should use when creating HTTP messages (for example, spider messages or CONNECT requests to outgoing proxy). - defaultUserAgent: "secureCodeBox/2.7.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0" - -# List of 1 or more contexts, mandatory -contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: scb-bodgeit-context - # The top level url, mandatory, everything under this will be included. IMPORTANT: must be the hostname without any subpath! - url: http://localhost:8080/bodgeit/ - # An optional list of regexes to include - includePaths: - - "http://localhost:8080/bodgeit.*" - # An optional list of regexes to exclude - excludePaths: - - ".*\\.js" - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - # Auth Credentials for the scanner to access the application - # Can be either basicAuth or a oidc token. - # If both are set, the oidc token takes precedent - # More infos about "ZAP Authentication for BodgeIT": https://play.sonatype.com/watch/B1vhaLSUsme7eA5hU8WeGB? - authentication: - # Currently supports "basic-auth", "form-based", "json-based", "script-based" - type: "form-based" - # basic-auth requires no further configuration - form-based: - loginUrl: "http://localhost:8080/bodgeit/login.jsp" - # must be escaped already to prevent yaml parser colidations 'username={%username%}&password={%password%}'' - loginRequestData: "username%3D%7B%25username%25%7D%26password%3D%7B%25password%25%7D" - # Indicates if the current Zap User Session is based on a valid authentication (loggedIn) or not (loggedOut) - verification: - isLoggedInIndicator: '\Q\E' - isLoggedOutIndicator: '\QGuest user\E' - users: - - name: bodgeit-user-1 - username: test@thebodgeitstore.com - password: password - forced: true - session: - # Currently supports "scriptBasedSessionManagement", "cookieBasedSessionManagement", "httpAuthSessionManagement" - type: "cookieBasedSessionManagement" - -spiders: - - name: scb-bodgeit-spider - # String: Name of the context to spider, default: first context - context: scb-bodgeit-context - # String: Name of the user to authenticate with and used to spider - user: bodgeit-user-1 - # String: Url to start spidering from, default: first context URL - url: http://localhost:8080/bodgeit/ - # Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 1 - # Int: The maximum tree depth to explore, default 5 - maxDepth: 5 - # Int: The maximum number of children to add to each node in the tree - maxChildren: 10 - # # Int: The max size of a response that will be parsed, default: 2621440 - 2.5 Mb - # maxParseSizeBytes: 2621440 - # Bool: Whether the spider will accept cookies, default: true - acceptCookies: true - # Bool: Whether the spider will handle OData responses, default: false - handleODataParametersVisited: false - # Enum [ignore_completely, ignore_value, use_all]: How query string parameters are used when checking if a URI has already been visited, default: use_all - handleParameters: use_all - # Bool: Whether the spider will parse HTML comments in order to find URLs, default: true - parseComments: true - # Bool: Whether the spider will parse Git metadata in order to find URLs, default: false - parseGit: false - # Bool: Whether the spider will parse 'robots.txt' files in order to find URLs, default: true - parseRobotsTxt: true - # Bool: Whether the spider will parse 'sitemap.xml' files in order to find URLs, default: true - parseSitemapXml: false - # Bool: Whether the spider will parse SVN metadata in order to find URLs, default: false - parseSVNEntries: false - # Bool: Whether the spider will submit POST forms, default: true - postForm: true - # Bool: Whether the spider will process forms, default: true - processForm: true - # Int: The time between the requests sent to a server in milliseconds, default: 200 - requestWaitTime: 200 - # Bool: Whether the spider will send the referer header, default: true - sendRefererHeader: true - # Int: The number of spider threads, default: 2 - threadCount: 2 - # String: The user agent to use in requests, default: '' - use the default ZAP one - userAgent: "secureCodeBox / ZAP Spider" - -scanners: - - name: scb-bodgeit-scan - # String: Name of the context to attack, default: first context - context: scb-bodgeit-context - # String: Name of the user to authenticate with and used to spider - user: bodgeit-user-1 - # String: Url to start scaning from, default: first context URL - url: http://localhost:8080/bodgeit/ - # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 1 - # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 5 - # Int: The max number of threads per host, default: 2 - threadPerHost: 5 - # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false diff --git a/scanners/zap-advanced/scanner/tests/mocks/scan-full-juiceshop-docker/1_zap-advanced-scan-config.yaml b/scanners/zap-advanced/scanner/tests/mocks/scan-full-juiceshop-docker/1_zap-advanced-scan-config.yaml deleted file mode 100644 index c44ec3d795..0000000000 --- a/scanners/zap-advanced/scanner/tests/mocks/scan-full-juiceshop-docker/1_zap-advanced-scan-config.yaml +++ /dev/null @@ -1,107 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -# Global ZAP Configurations - NOT YET IMPLEMENTED -global: - # True to create another ZAP session (overwrite the former if the same name already exists), False to use an existing on - isNewSession: true - # ZAP Session name - sessionName: secureCodeBox - -# List of 1 or more contexts, mandatory -contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: scb-juiceshop-context - # The top level url, mandatory, everything under this will be included. IMPORTANT: must be the hostname without any subpath! - url: http://juiceshop:3000/ - # An optional list of regexes to include - includePaths: - - "http://juiceshop:3000.*" - # An optional list of regexes to exclude - excludePaths: - - ".*socket\\.io.*" - - ".*\\.png" - - ".*\\.jpeg" - - ".*\\.jpg" - - ".*\\.woff" - - ".*\\.woff2" - - ".*\\.ttf" - - ".*\\.ico" - # Auth Credentials for the scanner to access the application - authentication: - # Currently supports "basic-auth", "form-based", "json-based", "script-based" - type: "json-based" - # json-based requires no further configuration - # zapConfiguration.contexts[0].authentication.json-based -- Configure `type: json-based` authentication (more: https://www.zaproxy.org/docs/api/#json-based-authentication). - json-based: - loginUrl: "http://juiceshop:3000/rest/user/login" - # must be escaped already to prevent yaml parser colidations '{"user":{"id":1,"email":"test@test.com"}}'' - # loginRequestData: '{"email":"{%username%}","password":"{%password%}"}' - loginRequestData: '{"email":"admin@juice-sh.op","password":"admin123"}' - # Username Parameter: email - # Password Parameter: password - # Indicates if the current Zap User Session is based on a valid authentication (loggedIn) or not (loggedOut) - verification: - isLoggedOutIndicator: '\Q{"user":{}}\E' - users: - - name: juiceshop-user-1 - username: admin@juice-sh.op - password: admin123 - forced: true - session: - # Currently supports "scriptBasedSessionManagement", "cookieBasedSessionManagement", "httpAuthSessionManagement" - type: "scriptBasedSessionManagement" - # scriptBasedSessionManagement configuration details - scriptBasedSessionManagement: - name: juiceshop-session-management.js - # Script engine values: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - engine: "Oracle Nashorn" - # Must be a full path to the script file inside the ZAP container (corresponding to the configMap FileMount) - filePath: "/home/zap/.ZAP_D/scripts/scripts/session/juiceshop-session-management.js" - description: "This is a JuiceShop specific SessionManagement Script used to handle JWT." - -spiders: - - name: scb-juiceshop-spider - # String: Name of the context to spider, default: first context - context: scb-juiceshop-context - # String: Name of the user to authenticate with and used to spider - user: juiceshop-user-1 - # String: Url to start spidering from, default: first context URL - url: http://juiceshop:3000/ - # zapConfiguration.spiders[0].ajax -- Bool: Whether to use the ZAP ajax spider, default: false - ajax: true - # Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 2 - # Int: The maximum tree depth to explore, default 5 - maxDepth: 10 - -scanners: - - name: scb-juiceshop-scan - # String: Name of the context to attack, default: first context - context: scb-juiceshop-context - # String: Name of the user to authenticate with and used to spider - user: juiceshop-user-1 - # String: Url to start scaning from, default: first context URL - url: http://juiceshop:3000/ - # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 1 - # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 5 - # Int: The max number of threads per host, default: 2 - threadPerHost: 5 - # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false diff --git a/scanners/zap-advanced/scanner/tests/mocks/scan-full-juiceshop-local/1_zap-advanced-scan-config.yaml b/scanners/zap-advanced/scanner/tests/mocks/scan-full-juiceshop-local/1_zap-advanced-scan-config.yaml deleted file mode 100644 index 9b41872f63..0000000000 --- a/scanners/zap-advanced/scanner/tests/mocks/scan-full-juiceshop-local/1_zap-advanced-scan-config.yaml +++ /dev/null @@ -1,112 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -# Global ZAP Configurations - NOT YET IMPLEMENTED -global: - # True to create another ZAP session (overwrite the former if the same name already exists), False to use an existing on - isNewSession: true - # ZAP Session name - sessionName: secureCodeBox - -# List of 1 or more contexts, mandatory -contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: scb-juiceshop-context - # The top level url, mandatory, everything under this will be included. IMPORTANT: must be the hostname without any subpath! - url: http://localhost:3000/ - # An optional list of regexes to include - includePaths: - - "http://localhost:3000.*" - # An optional list of regexes to exclude - excludePaths: - - ".*socket\\.io.*" - - ".*\\.png" - - ".*\\.jpeg" - - ".*\\.jpg" - - ".*\\.woff" - - ".*\\.woff2" - - ".*\\.ttf" - - ".*\\.ico" - # Auth Credentials for the scanner to access the application - authentication: - # Currently supports "basic-auth", "form-based", "json-based", "script-based" - type: "json-based" - # json-based requires no further configuration - # zapConfiguration.contexts[0].authentication.json-based -- Configure `type: json-based` authentication (more: https://www.zaproxy.org/docs/api/#json-based-authentication). - json-based: - loginUrl: "http://localhost:3000/rest/user/login" - # must be escaped already to prevent yaml parser colidations '{"user":{"id":1,"email":"test@test.com"}}'' - # loginRequestData: '{"email":"{%username%}","password":"{%password%}"}' - loginRequestData: '{"email":"admin@juice-sh.op","password":"admin123"}' - # Username Parameter: email - # Password Parameter: password - # Indicates if the current Zap User Session is based on a valid authentication (loggedIn) or not (loggedOut) - verification: - isLoggedOutIndicator: '\Q{"user":{}}\E' - users: - - name: juiceshop-user-1 - username: admin@juice-sh.op - password: admin123 - forced: true - session: - # Currently supports "scriptBasedSessionManagement", "cookieBasedSessionManagement", "httpAuthSessionManagement" - type: "scriptBasedSessionManagement" - # scriptBasedSessionManagement configuration details - scriptBasedSessionManagement: - name: juiceshop-session-management.js - enabled: true - # ---- Hint: ---- - # Fue to the fact this config is executed with your local ZAP Instance the script path may vary on your maschine. - # To make this configuration more stable you have to ensure to install the neede script beforehand in your local ZAP Instance and ensure the correct script name "juiceshop-session-management.js". - # --- - # # Script engine values: 'Graal.js', 'Oracle Nashorn' for Javascript and 'Mozilla Zest' for Zest Scripts - # engine: "Oracle Nashorn" - # # Must be a full path to the script file inside the ZAP container (corresponding to the configMap FileMount) - # filePath: "/home/zap/.ZAP_D/scripts/scripts/session/juiceshop-session-management.js" - # description: "This is a JuiceShop specific SessionManagement Script used to handle JWT." - -spiders: - - name: scb-juiceshop-spider - # String: Name of the context to spider, default: first context - context: scb-juiceshop-context - # String: Name of the user to authenticate with and used to spider - user: juiceshop-user-1 - # String: Url to start spidering from, default: first context URL - url: http://localhost:3000/ - # zapConfiguration.spiders[0].ajax -- Bool: Whether to use the ZAP ajax spider, default: false - ajax: true - # Int: Fail if spider finds less than the specified number of URLs, default: 0 (TODO: not yet implemented) - failIfFoundUrlsLessThan: 0 - # Int: Warn if spider finds less than the specified number of URLs, default: 0 (TODO: not yet implemented) - warnIfFoundUrlsLessThan: 0 - # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 2 - # Int: The maximum tree depth to explore, default 5 - maxDepth: 5 - -scanners: - - name: scb-juiceshop-scan - # String: Name of the context to attack, default: first context - context: scb-juiceshop-context - # String: Name of the user to authenticate with and used to spider - user: juiceshop-user-1 - # String: Url to start scaning from, default: first context URL - url: http://localhost:3000/ - # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 1 - # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 10 - # Int: The max number of threads per host, default: 2 - threadPerHost: 5 - # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false diff --git a/scanners/zap-advanced/scanner/tests/mocks/scan-full-petstore-alert-filter-docker/1_zap-advanced-scan-config.yaml b/scanners/zap-advanced/scanner/tests/mocks/scan-full-petstore-alert-filter-docker/1_zap-advanced-scan-config.yaml deleted file mode 100644 index e7fc74dbac..0000000000 --- a/scanners/zap-advanced/scanner/tests/mocks/scan-full-petstore-alert-filter-docker/1_zap-advanced-scan-config.yaml +++ /dev/null @@ -1,138 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -# Global ZAP Configurations -global: - # True to create another ZAP session (overwrite the former if the same name already exists), False to use an existing on - isNewSession: true - # Sets the ZAP Session name - sessionName: SCB - -# List of 1 or more contexts, mandatory -contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: scb-petstore-context - # The top level url, mandatory, everything under this will be included. IMPORTANT: must be the hostname without any subpath! - url: http://petstore:8080/ - # An optional list of regexes to include - includePaths: - - "http://petstore:8080/v2.*" - # An optional list of regexes to exclude - excludePaths: - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - alertFilters: - # ignore a bunch of rules to reduce number of findings in tests - - ruleId: 10020 - newLevel: "False Positive" - - ruleId: 10021 - newLevel: "False Positive" - - ruleId: 10024 - newLevel: "False Positive" - - ruleId: 10036 - newLevel: "False Positive" - - ruleId: 10038 - newLevel: "False Positive" - - ruleId: 10049 - newLevel: "False Positive" - - ruleId: 10063 - newLevel: "False Positive" - - ruleId: 10098 - newLevel: "False Positive" - - ruleId: 10109 - newLevel: "False Positive" - - ruleId: 40033 - newLevel: "False Positive" - - ruleId: 40039 - newLevel: "False Positive" - - ruleId: 40040 - newLevel: "False Positive" - - ruleId: 90003 - newLevel: "False Positive" - -apis: - # -- The name of the spider configuration - - name: scb-petstore-api - # -- The Name of the context (zapConfiguration.contexts[x].name) to spider, default: first context available. - context: scb-petstore-context - # -- format of the API ('openapi', 'grapql', 'soap') - format: openapi - # -- Url to start spidering from, default: first context URL - url: http://petstore:8080/v2/swagger.json - # -- Override host setting in swagger.json - hostOverride: http://petstore:8080 - -spiders: - - name: scb-petstore-spider - # String: Name of the context to spider, default: first context - context: scb-petstore-context - # String: Url to start spidering from, default: first context URL - url: http://petstore:8080/v2/ - # Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 1 - # Int: The maximum tree depth to explore, default 5 - maxDepth: 5 - # Int: The maximum number of children to add to each node in the tree - maxChildren: 10 - # # Int: The max size of a response that will be parsed, default: 2621440 - 2.5 Mb - # maxParseSizeBytes: 2621440 - # Bool: Whether the spider will accept cookies, default: true - acceptCookies: true - # Bool: Whether the spider will handle OData responses, default: false - handleODataParametersVisited: false - # Enum [ignore_completely, ignore_value, use_all]: How query string parameters are used when checking if a URI has already been visited, default: use_all - handleParameters: use_all - # Bool: Whether the spider will parse HTML comments in order to find URLs, default: true - parseComments: true - # Bool: Whether the spider will parse Git metadata in order to find URLs, default: false - parseGit: false - # Bool: Whether the spider will parse 'robots.txt' files in order to find URLs, default: true - parseRobotsTxt: false - # Bool: Whether the spider will parse 'sitemap.xml' files in order to find URLs, default: true - parseSitemapXml: false - # Bool: Whether the spider will parse SVN metadata in order to find URLs, default: false - parseSVNEntries: false - # Bool: Whether the spider will submit POST forms, default: true - postForm: true - # Bool: Whether the spider will process forms, default: true - processForm: true - # Int: The time between the requests sent to a server in milliseconds, default: 200 - requestWaitTime: 200 - # Bool: Whether the spider will send the referer header, default: true - sendRefererHeader: true - # Int: The number of spider threads, default: 2 - threadCount: 5 - # String: The user agent to use in requests, default: '' - use the default ZAP one - userAgent: "secureCodeBox / ZAP Spider" - -scanners: - - name: scb-petstore-scan - # String: Name of the context to attack, default: first context - context: scb-petstore-context - # String: Url to start scaning from, default: first context URL - url: http://petstore:8080/v2/ - # String: Name of the scan policy to be used, default: Default Policy - policy: "API-Minimal" - # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 1 - # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 5 - # Int: The max number of threads per host, default: 2 - threadPerHost: 5 - # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false diff --git a/scanners/zap-advanced/scanner/tests/mocks/scan-full-petstore-docker/1_zap-advanced-scan-config.yaml b/scanners/zap-advanced/scanner/tests/mocks/scan-full-petstore-docker/1_zap-advanced-scan-config.yaml deleted file mode 100644 index 3ba16f5c8e..0000000000 --- a/scanners/zap-advanced/scanner/tests/mocks/scan-full-petstore-docker/1_zap-advanced-scan-config.yaml +++ /dev/null @@ -1,136 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -# Global ZAP Configurations -global: - # True to create another ZAP session (overwrite the former if the same name already exists), False to use an existing on - isNewSession: true - # Sets the ZAP Session name - sessionName: SCB - # Determine if a proxy script must be loaded. Proxy scripts are executed for every request traversing ZAP - scripts: - - name: "Alert_on_HTTP_Response_Code_Errors.js" - enabled: false - filePath: "/home/zap/.ZAP_D/scripts/scripts/httpsender/Alert_on_HTTP_Response_Code_Errors.js" - engine: "Oracle Nashorn" - type: "httpsender" - description: "A HTTP Sender Script which will raise alerts based on HTTP Response codes." - - name: "Alert_on_Unexpected_Content_Types.js" - enabled: false - filePath: "/home/zap/.ZAP_D/scripts/scripts/httpsender/Alert_on_Unexpected_Content_Types.js" - engine: "Oracle Nashorn" - type: "httpsender" - description: "A HTTP Sender Script which will raise alerts based on unexpected Content-Types." - -# List of 1 or more contexts, mandatory -contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: scb-petstore-context - # The top level url, mandatory, everything under this will be included. IMPORTANT: must be the hostname without any subpath! - url: http://petstore:8080/ - # An optional list of regexes to include - includePaths: - - "http://petstore:8080/v2.*" - # An optional list of regexes to exclude - excludePaths: - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - -apis: - # -- The name of the spider configuration - - name: scb-petstore-api - # -- The Name of the context (zapConfiguration.contexts[x].name) to spider, default: first context available. - context: scb-petstore-context - # -- format of the API ('openapi', 'grapql', 'soap') - format: openapi - # -- Url to start spidering from, default: first context URL - url: http://petstore:8080/v2/swagger.json - # -- Override host setting in swagger.json - hostOverride: http://petstore:8080 - # -- Assumes that the OpenAPI Spec has been saved to a configmap in the namespace of the scan / this release. Should be null if not used. - #configMap: null - # Object with two keys: "name" name of the config map, and "key" which is the key / property in the configmap which holds the openapi spec file. - # name: my-configmap-with-openapi-spec - # key: openapi.yaml - # -- Allows to embed the entire yaml / json OpenAPI spec in the values. Should be null if not used. - #spec: null - scripts: - - name: "Alert_on_HTTP_Response_Code_Errors.js" - enabled: true - - name: "Alert_on_Unexpected_Content_Types.js" - enabled: true - -spiders: - - name: scb-petstore-spider - # String: Name of the context to spider, default: first context - context: scb-petstore-context - # String: Url to start spidering from, default: first context URL - url: http://petstore:8080/v2/ - # Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 1 - # Int: The maximum tree depth to explore, default 5 - maxDepth: 5 - # Int: The maximum number of children to add to each node in the tree - maxChildren: 10 - # # Int: The max size of a response that will be parsed, default: 2621440 - 2.5 Mb - # maxParseSizeBytes: 2621440 - # Bool: Whether the spider will accept cookies, default: true - acceptCookies: true - # Bool: Whether the spider will handle OData responses, default: false - handleODataParametersVisited: false - # Enum [ignore_completely, ignore_value, use_all]: How query string parameters are used when checking if a URI has already been visited, default: use_all - handleParameters: use_all - # Bool: Whether the spider will parse HTML comments in order to find URLs, default: true - parseComments: true - # Bool: Whether the spider will parse Git metadata in order to find URLs, default: false - parseGit: false - # Bool: Whether the spider will parse 'robots.txt' files in order to find URLs, default: true - parseRobotsTxt: false - # Bool: Whether the spider will parse 'sitemap.xml' files in order to find URLs, default: true - parseSitemapXml: false - # Bool: Whether the spider will parse SVN metadata in order to find URLs, default: false - parseSVNEntries: false - # Bool: Whether the spider will submit POST forms, default: true - postForm: true - # Bool: Whether the spider will process forms, default: true - processForm: true - # Int: The time between the requests sent to a server in milliseconds, default: 200 - requestWaitTime: 200 - # Bool: Whether the spider will send the referer header, default: true - sendRefererHeader: true - # Int: The number of spider threads, default: 2 - threadCount: 5 - # String: The user agent to use in requests, default: '' - use the default ZAP one - userAgent: "secureCodeBox / ZAP Spider" - -scanners: - - name: scb-petstore-scan - # String: Name of the context to attack, default: first context - context: scb-petstore-context - # String: Url to start scaning from, default: first context URL - url: http://petstore:8080/v2/ - # String: Name of the scan policy to be used, default: Default Policy - policy: "API-Minimal" - # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 1 - # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 5 - # Int: The max number of threads per host, default: 2 - threadPerHost: 5 - # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false diff --git a/scanners/zap-advanced/scanner/tests/mocks/scan-full-petstore-local/1_zap-advanced-scan-config.yaml b/scanners/zap-advanced/scanner/tests/mocks/scan-full-petstore-local/1_zap-advanced-scan-config.yaml deleted file mode 100644 index eddfbd46fc..0000000000 --- a/scanners/zap-advanced/scanner/tests/mocks/scan-full-petstore-local/1_zap-advanced-scan-config.yaml +++ /dev/null @@ -1,123 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -# Global ZAP Configurations -global: - # True to create another ZAP session (overwrite the former if the same name already exists), False to use an existing on - isNewSession: true - # Sets the ZAP Session name - sessionName: SCB - # Determine if a proxy script must be loaded. Proxy scripts are executed for every request traversing ZAP - scripts: - - name: "Alert on HTTP Response Code Errors.js" - enabled: true - - name: "Alert on Unexpected Content Types.js" - enabled: true - -# List of 1 or more contexts, mandatory -contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: scb-petstore-context - # The top level url, mandatory, everything under this will be included. IMPORTANT: must be the hostname without any subpath! - url: http://localhost:8000/ - # An optional list of regexes to include - includePaths: - - "http://localhost:8000/v2.*" - # An optional list of regexes to exclude - excludePaths: - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - -apis: - # -- The name of the spider configuration - - name: scb-petstore-api - # -- The Name of the context (zapConfiguration.contexts[x].name) to spider, default: first context available. - context: scb-petstore-context - # -- format of the API ('openapi', 'grapql', 'soap') - format: openapi - # -- Url to start spidering from, default: first context URL - url: http://localhost:8000/v2/swagger.json - # -- Override host setting in swagger.json - hostOverride: http://localhost:8000 - # -- Assumes that the OpenAPI Spec has been saved to a configmap in the namespace of the scan / this release. Should be null if not used. - #configMap: null - # Object with two keys: "name" name of the config map, and "key" which is the key / property in the configmap which holds the openapi spec file. - # name: my-configmap-with-openapi-spec - # key: openapi.yaml - # -- Allows to embed the entire yaml / json OpenAPI spec in the values. Should be null if not used. - #spec: null - -spiders: - - name: scb-petstore-spider - # String: Name of the context to spider, default: first context - context: scb-petstore-context - # String: Url to start spidering from, default: first context URL - url: http://localhost:8000/v2 - # Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 1 - # Int: The maximum tree depth to explore, default 5 - maxDepth: 5 - # Int: The maximum number of children to add to each node in the tree - maxChildren: 10 - # # Int: The max size of a response that will be parsed, default: 2621440 - 2.5 Mb - # maxParseSizeBytes: 2621440 - # Bool: Whether the spider will accept cookies, default: true - acceptCookies: true - # Bool: Whether the spider will handle OData responses, default: false - handleODataParametersVisited: false - # Enum [ignore_completely, ignore_value, use_all]: How query string parameters are used when checking if a URI has already been visited, default: use_all - handleParameters: use_all - # Bool: Whether the spider will parse HTML comments in order to find URLs, default: true - parseComments: true - # Bool: Whether the spider will parse Git metadata in order to find URLs, default: false - parseGit: false - # Bool: Whether the spider will parse 'robots.txt' files in order to find URLs, default: true - parseRobotsTxt: false - # Bool: Whether the spider will parse 'sitemap.xml' files in order to find URLs, default: true - parseSitemapXml: false - # Bool: Whether the spider will parse SVN metadata in order to find URLs, default: false - parseSVNEntries: false - # Bool: Whether the spider will submit POST forms, default: true - postForm: true - # Bool: Whether the spider will process forms, default: true - processForm: true - # Int: The time between the requests sent to a server in milliseconds, default: 200 - requestWaitTime: 200 - # Bool: Whether the spider will send the referer header, default: true - sendRefererHeader: true - # Int: The number of spider threads, default: 2 - threadCount: 5 - # String: The user agent to use in requests, default: '' - use the default ZAP one - userAgent: "secureCodeBox / ZAP Spider" - -scanners: - - name: scb-petstore-scan - # String: Name of the context to attack, default: first context - context: scb-petstore-context - # String: Url to start scaning from, default: first context URL - url: http://localhost:8000/v2 - # String: Name of the scan policy to be used, default: Default Policy - policy: "Default Policy" - # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 1 - # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 5 - # Int: The max number of threads per host, default: 2 - threadPerHost: 5 - # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false diff --git a/scanners/zap-advanced/scanner/tests/mocks/scan-full-petstore-relative/1_zap-advanced-scan-config.yaml b/scanners/zap-advanced/scanner/tests/mocks/scan-full-petstore-relative/1_zap-advanced-scan-config.yaml deleted file mode 100644 index b897e08cb3..0000000000 --- a/scanners/zap-advanced/scanner/tests/mocks/scan-full-petstore-relative/1_zap-advanced-scan-config.yaml +++ /dev/null @@ -1,111 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -# Global ZAP Configurations -global: - # True to create another ZAP session (overwrite the former if the same name already exists), False to use an existing on - isNewSession: true - # Sets the ZAP Session name - sessionName: SCB - # Determine if a proxy script must be loaded. Proxy scripts are executed for every request traversing ZAP - scripts: - - name: "Alert on HTTP Response Code Errors.js" - enabled: true - - name: "Alert on Unexpected Content Types.js" - enabled: true - -# List of 1 or more contexts, mandatory -contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: scb-petstore-context - # An optional list of regexes to include - includePaths: - - "https?://localhost:.*" - - "https?://.*\\..*.svc:.*" - - "https?://.*\\..*.svc/.*" - - "https?://.*\\..*.svc.cluster.local/.*" - - "https?://.*\\..*.svc.cluster.local:.*" - # An optional list of regexes to exclude - excludePaths: - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - -apis: - - name: scb-petstore-api - # -- The Name of the context (zapConfiguration.contexts[x].name) to spider, default: first context available. - context: scb-petstore-context - # -- format of the API ('openapi', 'grapql', 'soap') - format: openapi - # -- path to the OpenAPI spec. Always relative to the targets **hosts**, paths in the targets url will be ignored - path: /v2/swagger.json - -spiders: - - name: scb-petstore-spider - # String: Name of the context to attack, default: first context - context: scb-petstore-context - # Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 1 - # Int: The maximum tree depth to explore, default 5 - maxDepth: 5 - # Int: The maximum number of children to add to each node in the tree - maxChildren: 10 - # # Int: The max size of a response that will be parsed, default: 2621440 - 2.5 Mb - # maxParseSizeBytes: 2621440 - # Bool: Whether the spider will accept cookies, default: true - acceptCookies: true - # Bool: Whether the spider will handle OData responses, default: false - handleODataParametersVisited: false - # Enum [ignore_completely, ignore_value, use_all]: How query string parameters are used when checking if a URI has already been visited, default: use_all - handleParameters: use_all - # Bool: Whether the spider will parse HTML comments in order to find URLs, default: true - parseComments: true - # Bool: Whether the spider will parse Git metadata in order to find URLs, default: false - parseGit: false - # Bool: Whether the spider will parse 'robots.txt' files in order to find URLs, default: true - parseRobotsTxt: false - # Bool: Whether the spider will parse 'sitemap.xml' files in order to find URLs, default: true - parseSitemapXml: false - # Bool: Whether the spider will parse SVN metadata in order to find URLs, default: false - parseSVNEntries: false - # Bool: Whether the spider will submit POST forms, default: true - postForm: true - # Bool: Whether the spider will process forms, default: true - processForm: true - # Int: The time between the requests sent to a server in milliseconds, default: 200 - requestWaitTime: 200 - # Bool: Whether the spider will send the referer header, default: true - sendRefererHeader: true - # Int: The number of spider threads, default: 2 - threadCount: 5 - # String: The user agent to use in requests, default: '' - use the default ZAP one - userAgent: "secureCodeBox / ZAP Spider" - -scanners: - - name: scb-petstore-scan - # String: Name of the context to attack, default: first context - context: scb-petstore-context - # String: Name of the scan policy to be used, default: Default Policy - policy: "Default Policy" - # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 1 - # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 5 - # Int: The max number of threads per host, default: 2 - threadPerHost: 5 - # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false diff --git a/scanners/zap-advanced/scanner/tests/mocks/scan-full-secureCodeBox.io/1_zap-advanced-scan-config.yaml b/scanners/zap-advanced/scanner/tests/mocks/scan-full-secureCodeBox.io/1_zap-advanced-scan-config.yaml deleted file mode 100644 index 287175cc05..0000000000 --- a/scanners/zap-advanced/scanner/tests/mocks/scan-full-secureCodeBox.io/1_zap-advanced-scan-config.yaml +++ /dev/null @@ -1,95 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -# List of 1 or more contexts, mandatory -contexts: - # Name to be used to refer to this context in other jobs, mandatory - - name: secureCodeBoxScanType-NoAuth - # The top level url, mandatory, everything under this will be included - url: https://www.securecodebox.io/ - # An optional list of regexes to include - includePaths: - - "https://www.securecodebox.io.*" - # An optional list of regexes to exclude - excludePaths: - - "https://www.securecodebox.io/authserver/v1/.*" - - ".*\\.js" - - ".*\\.css" - - ".*\\.png" - - ".*\\.jpeg" - -spiders: - - name: scb-spider - # String: Name of the context to spider, default: first context - context: secureCodeBoxScanType-NoAuth - # String: Url to start spidering from, default: first context URL - url: https://www.securecodebox.io/ - # Int: Fail if spider finds less than the specified number of URLs, default: 0 - failIfFoundUrlsLessThan: 0 - # Int: Warn if spider finds less than the specified number of URLs, default: 0 - warnIfFoundUrlsLessThan: 0 - # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - maxDuration: 0 - # Int: The maximum tree depth to explore, default 5 - maxDepth: 5 - # Int: The maximum number of children to add to each node in the tree - maxChildren: 10 - # Bool: Whether the spider will accept cookies, default: true - acceptCookies: true - # Bool: Whether the spider will handle OData responses, default: false - handleODataParametersVisited: false - # Enum [ignore_completely, ignore_value, use_all]: How query string parameters are used when checking if a URI has already been visited, default: use_all - handleParameters: use_all - # Int: The max size of a response that will be parsed, default: 2621440 - 2.5 Mb - maxParseSizeBytes: 2621440 - # Bool: Whether the spider will parse HTML comments in order to find URLs, default: true - parseComments: true - # Bool: Whether the spider will parse Git metadata in order to find URLs, default: false - parseGit: false - # Bool: Whether the spider will parse 'robots.txt' files in order to find URLs, default: true - parseRobotsTxt: false - # Bool: Whether the spider will parse 'sitemap.xml' files in order to find URLs, default: true - parseSitemapXml: false - # Bool: Whether the spider will parse SVN metadata in order to find URLs, default: false - parseSVNEntries: false - # Bool: Whether the spider will submit POST forms, default: true - postForm: true - # Bool: Whether the spider will process forms, default: true - processForm: true - # Int: The time between the requests sent to a server in milliseconds, default: 200 - requestWaitTime: 200 - # Bool: Whether the spider will send the referer header, default: true - sendRefererHeader: true - # Int: The number of spider threads, default: 2 - threadCount: 2 - # String: The user agent to use in requests, default: '' - use the default ZAP one - userAgent: "secureCodeBox / ZAP Spider" - -scanners: - - name: scb-scan - # String: Name of the context to attack, default: first context - context: secureCodeBoxScanType-NoAuth - # String: Url to start scaning from, default: first context URL - url: https://www.securecodebox.io/ - # String: Name of the scan policy to be used, default: Default Policy - policy: "Default Policy" - # Int: The max time in minutes any individual rule will be allowed to run for, default: 0 unlimited - maxRuleDurationInMins: 0 - # Int: The max time in minutes the active scanner will be allowed to run for, default: 0 unlimited - maxScanDurationInMins: 0 - # Bool: If set will add an extra query parameter to requests that do not have one, default: false - addQueryParam: false - # String: The name of the default scan policy to use, default: Default Policy - defaultPolicy: "Default Policy" - # Int: The delay in milliseconds between each request, use to reduce the strain on the target, default 0 - delayInMs: 0 - # Bool: If set then automatically handle anti CSRF tokens, default: false - handleAntiCSRFTokens: false - # Bool: If set then the relevant rule Id will be injected into the X-ZAP-Scan-ID header of each request, default: false - injectPluginIdInHeader: false - # Bool: If set then the headers of requests that do not include any parameters will be scanned, default: false - scanHeadersAllRequests: false - # Int: The max number of threads per host, default: 2 - threadPerHost: 2 diff --git a/scanners/zap-advanced/scanner/tests/test_integration_docker_local.py b/scanners/zap-advanced/scanner/tests/test_integration_docker_local.py deleted file mode 100644 index 1e771699d3..0000000000 --- a/scanners/zap-advanced/scanner/tests/test_integration_docker_local.py +++ /dev/null @@ -1,249 +0,0 @@ -#!/usr/bin/env python - -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# -*- coding: utf-8 -*- - -import os -import pytest -import requests -import logging -import pytest - -from zapv2 import ZAPv2 -from requests.exceptions import ConnectionError - -from zapclient.zap_automation import ZapAutomation - - -def is_responsive(url): - try: - response = requests.get(url) - if response.status_code == 200: - return True - except ConnectionError: - return False - - -@pytest.fixture(scope="session") -def docker_compose_file(pytestconfig): - return os.path.join(str(pytestconfig.rootdir), "", "docker-compose.test.yaml") - - -@pytest.fixture(scope="session") -def get_bodgeit_url(docker_ip, docker_services): - """Ensure that HTTP service is up and responsive.""" - - # `port_for` takes a container port and returns the corresponding host port - port = docker_services.port_for("bodgeit", 8080) - url = "http://{}:{}".format(docker_ip, port) - docker_services.wait_until_responsive( - timeout=30.0, pause=0.1, check=lambda: is_responsive(url) - ) - return url - - -@pytest.fixture(scope="session") -def get_juiceshop_url(docker_ip, docker_services): - """Ensure that HTTP service is up and responsive.""" - - # `port_for` takes a container port and returns the corresponding host port - port = docker_services.port_for("juiceshop", 3000) - url = "http://{}:{}".format(docker_ip, port) - docker_services.wait_until_responsive( - timeout=30.0, pause=0.1, check=lambda: is_responsive(url) - ) - return url - - -@pytest.fixture(scope="session") -def get_petstore_url(docker_ip, docker_services): - """Ensure that HTTP service is up and responsive.""" - - # `port_for` takes a container port and returns the corresponding host port - port = docker_services.port_for("petstore", 8080) - url = "http://{}:{}".format(docker_ip, port) - docker_services.wait_until_responsive( - timeout=30.0, pause=0.1, check=lambda: is_responsive(url) - ) - return url - - -@pytest.fixture(scope="session") -def get_zap_url(docker_ip, docker_services): - """Ensure that HTTP service is up and responsive.""" - - # `port_for` takes a container port and returns the corresponding host port - port = docker_services.port_for("zap", 8090) - url = "http://{}:{}".format(docker_ip, port) - docker_services.wait_until_responsive( - timeout=30.0, pause=0.1, check=lambda: is_responsive(url) - ) - return url - - -@pytest.fixture(scope="session") -def get_zap_instance(get_zap_url) -> ZAPv2: - - # MANDATORY. Define the API key generated by ZAP and used to verify actions. - apiKey = "eor898q1luuq8054e0e5r9s3jh" - - # MANDATORY. Define the listening address of ZAP instance - localProxy = {"http": get_zap_url, "https": get_zap_url.replace("http", "https")} - - logging.info("Configuring ZAP Instance with %s", localProxy) - # Connect ZAP API client to the listening address of ZAP instance - zap = ZAPv2(proxies=localProxy, apikey=apiKey) - - return zap - - -@pytest.mark.integrationtest -def test_all_services_available( - get_bodgeit_url, get_juiceshop_url, get_zap_url, get_petstore_url -): - response = requests.get(get_bodgeit_url + "/bodgeit/") - assert response.status_code == 200 - - response = requests.get(get_juiceshop_url + "/#/") - assert response.status_code == 200 - - response = requests.get(get_petstore_url + "/v2/swagger.json") - assert response.status_code == 200 - - response = requests.get(get_zap_url + "/UI/core/") - assert response.status_code == 200 - - -# @pytest.mark.integrationtest -# def test_bodgeit_scan_without_config(get_bodgeit_url, get_zap_instance: ZAPv2): - -# zap = get_zap_instance -# test_target = "http://bodgeit:8080/bodgeit/" - -# logging.warning("get_bodgeit_url: %s", get_bodgeit_url) - -# zap_automation = ZapAutomation(zap=zap, config_dir="", target=test_target) -# zap_automation.scan_target(target=test_target) - -# alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], []) - -# logging.info('Found ZAP Alerts: %d', len(alerts)) - -# assert int(len(alerts)) >= 4 - - -@pytest.mark.integrationtest -def test_bodgeit_scan_with_config(get_bodgeit_url, get_zap_instance: ZAPv2): - - zap = get_zap_instance - test_config_yaml = "./tests/mocks/scan-full-bodgeit-docker/" - test_target = "http://bodgeit:8080/bodgeit/" - - logging.warning("get_bodgeit_url: %s", get_bodgeit_url) - - zap_automation = ZapAutomation( - zap=zap, config_dir=test_config_yaml, target=test_target - ) - zap_automation.scan_target(target=test_target) - - alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], []) - - logging.info("Found ZAP Alerts: %d", len(alerts)) - - assert int(len(alerts)) >= 4 - - -# @pytest.mark.integrationtest -# def test_juiceshop_scan_without_config(get_juiceshop_url, get_zap_instance: ZAPv2): - -# zap = get_zap_instance -# test_target = "http://juiceshop:3000/" - -# zap_automation = ZapAutomation(zap=zap, config_dir="", target=test_target) -# zap_automation.scan_target(target=test_target) - -# alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], []) - -# logging.info('Found ZAP Alerts: %d', len(alerts)) - -# assert int(len(alerts)) >= 2 - - -@pytest.mark.integrationtest -def test_juiceshop_scan_with_config(get_juiceshop_url, get_zap_instance: ZAPv2): - - zap = get_zap_instance - test_config_yaml = "./tests/mocks/scan-full-juiceshop-docker/" - test_target = "http://juiceshop:3000/" - - zap_automation = ZapAutomation( - zap=zap, config_dir=test_config_yaml, target=test_target - ) - zap_automation.scan_target(target=test_target) - - alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], []) - - logging.info("Found ZAP Alerts: %d", len(alerts)) - - assert int(len(alerts)) >= 2 - - -@pytest.mark.integrationtest -def test_petstore_scan_with_config(get_petstore_url, get_zap_instance: ZAPv2): - - zap = get_zap_instance - test_config_yaml = "./tests/mocks/scan-full-petstore-docker/" - test_target = "http://petstore:8080/" - - zap_automation = ZapAutomation( - zap=zap, config_dir=test_config_yaml, target=test_target - ) - zap_automation.scan_target(target=test_target) - - alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], []) - - logging.info("Found ZAP Alerts: %d", len(alerts)) - - assert int(len(alerts)) >= 1 - - -@pytest.mark.integrationtest -def test_petstore_scan_with_relative_config(get_petstore_url, get_zap_instance: ZAPv2): - - zap = get_zap_instance - test_config_yaml = "./tests/mocks/scan-full-petstore-relative/" - test_target = "http://petstore:8080/" - - zap_automation = ZapAutomation( - zap=zap, config_dir=test_config_yaml, target=test_target - ) - zap_automation.scan_target(target=test_target) - - alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], []) - - logging.info("Found ZAP Alerts: %d", len(alerts)) - - assert int(len(alerts)) >= 1 - - -@pytest.mark.integrationtest -def test_petstore_scan_with_alert_filters(get_petstore_url, get_zap_instance: ZAPv2): - - zap = get_zap_instance - test_config_yaml = "./tests/mocks/scan-full-petstore-alert-filter-docker/" - test_target = "http://petstore:8080/" - - zap_automation = ZapAutomation( - zap=zap, config_dir=test_config_yaml, target=test_target - ) - zap_automation.scan_target(target=test_target) - - alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], []) - - logging.info("Found ZAP Alerts: %d", len(alerts)) - - # should normally be 13 alerts but most of them are ignored using alertFilters in the scan config - assert int(len(alerts)) > 1 and int(len(alerts)) < 10 diff --git a/scanners/zap-advanced/scanner/tests/test_integration_zap_local.py b/scanners/zap-advanced/scanner/tests/test_integration_zap_local.py deleted file mode 100644 index b170a3f0c3..0000000000 --- a/scanners/zap-advanced/scanner/tests/test_integration_zap_local.py +++ /dev/null @@ -1,282 +0,0 @@ -#!/usr/bin/env python - -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# -*- coding: utf-8 -*- - -import os -import pytest -import requests -import logging -import pytest - -from zapv2 import ZAPv2 -from requests.exceptions import ConnectionError - -from zapclient.zap_automation import ZapAutomation - - -def is_responsive(url): - try: - response = requests.get(url) - if response.status_code == 200: - return True - except ConnectionError: - return False - - -@pytest.fixture(scope="session") -def docker_compose_file(pytestconfig): - return os.path.join(str(pytestconfig.rootdir), "", "docker-compose.test.yaml") - - -@pytest.fixture(scope="session") -def get_bodgeit_url(docker_ip, docker_services): - """Ensure that HTTP service is up and responsive.""" - - # `port_for` takes a container port and returns the corresponding host port - port = docker_services.port_for("bodgeit", 8080) - url = "http://{}:{}".format(docker_ip, port) - docker_services.wait_until_responsive( - timeout=30.0, pause=0.1, check=lambda: is_responsive(url) - ) - return url - - -@pytest.fixture(scope="session") -def get_juiceshop_url(docker_ip, docker_services): - """Ensure that HTTP service is up and responsive.""" - - # `port_for` takes a container port and returns the corresponding host port - port = docker_services.port_for("juiceshop", 3000) - url = "http://{}:{}".format(docker_ip, port) - docker_services.wait_until_responsive( - timeout=30.0, pause=0.1, check=lambda: is_responsive(url) - ) - return url - - -@pytest.fixture(scope="session") -def get_petstore_url(docker_ip, docker_services): - """Ensure that HTTP service is up and responsive.""" - - # `port_for` takes a container port and returns the corresponding host port - port = docker_services.port_for("petstore", 8080) - url = "http://{}:{}".format(docker_ip, port) - docker_services.wait_until_responsive( - timeout=30.0, pause=0.1, check=lambda: is_responsive(url) - ) - return url - - -@pytest.fixture(scope="session") -def get_zap_url(docker_ip, docker_services): - """Ensure that HTTP service is up and responsive.""" - - # `port_for` takes a container port and returns the corresponding host port - port = docker_services.port_for("zap", 8090) - url = "http://{}:{}".format(docker_ip, port) - docker_services.wait_until_responsive( - timeout=30.0, pause=0.1, check=lambda: is_responsive(url) - ) - return url - - -@pytest.fixture(scope="session") -def get_zap_instance(docker_ip, docker_services, get_zap_url) -> ZAPv2: - - # MANDATORY. Define the API key generated by ZAP and used to verify actions. - apiKey = "eor898q1luuq8054e0e5r9s3jh" - - # MANDATORY. Define the listening address of ZAP instance - localProxy = {"http": "http://127.0.0.1:8010", "https": "http://127.0.0.1:8010"} - - logging.info("Configuring ZAP Instance with %s", localProxy) - # Connect ZAP API client to the listening address of ZAP instance - zap = ZAPv2(proxies=localProxy, apikey=apiKey) - - return zap - - -@pytest.mark.integrationtest -def test_all_services_available( - get_bodgeit_url, get_juiceshop_url, get_petstore_url, get_zap_url -): - response = requests.get(get_bodgeit_url + "/bodgeit/") - assert response.status_code == 200 - - response = requests.get(get_juiceshop_url + "/#/") - assert response.status_code == 200 - - response = requests.get(get_petstore_url + "/v2/swagger.json") - assert response.status_code == 200 - - response = requests.get(get_zap_url + "/UI/core/") - assert response.status_code == 200 - - -@pytest.mark.integrationtest -def test_global_config(get_zap_instance: ZAPv2): - - zap = get_zap_instance - test_target = "http://www.secureCodeBox.io/" - test_config_yaml = "./tests/mocks/global/" - - zap_automation = ZapAutomation( - zap=zap, config_dir=test_config_yaml, target=test_target - ) - zap_automation.scan_target(target=test_target) - - alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], []) - - logging.info("Found ZAP Alerts: %d", len(alerts)) - - assert int(len(alerts)) >= 1 - - -@pytest.mark.integrationtest -def test_scan_target_without_config(get_zap_instance: ZAPv2): - - zap = get_zap_instance - test_target = "http://www.secureCodeBox.io/" - - zap_automation = ZapAutomation(zap=zap, config_dir="", target=test_target) - zap_automation.scan_target(target=test_target) - - -# @pytest.mark.integrationtest -# def test_bodgeit_scan_without_config(get_bodgeit_url, get_zap_instance: ZAPv2): - -# zap = get_zap_instance -# test_target = "http://localhost:8080/bodgeit/" - -# zap_automation = ZapAutomation(zap=zap, config_dir="", target=test_target) -# zap_automation.scan_target(target=test_target) - -# alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], []) - -# logging.info('Found ZAP Alerts: %s', str(len(alerts))) - -# assert int(len(alerts)) >= 4 - - -@pytest.mark.integrationtest -def test_bodgeit_scan_with_config(get_bodgeit_url, get_zap_instance: ZAPv2): - - zap = get_zap_instance - test_config_yaml = "./tests/mocks/scan-full-bodgeit-local/" - test_target = "http://localhost:8080/bodgeit/" - - zap_automation = ZapAutomation( - zap=zap, config_dir=test_config_yaml, target=test_target - ) - zap_automation.scan_target(target=test_target) - - alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], []) - - logging.info("Found ZAP Alerts: %s", str(len(alerts))) - - assert int(len(alerts)) >= 4 - - -# @pytest.mark.integrationtest -# def test_juiceshop_scan_without_config(get_juiceshop_url, get_zap_instance: ZAPv2): - -# zap = get_zap_instance -# test_config_yaml = "./tests/mocks/scan-full-juiceshop-local/" -# test_target = "http://localhost:3000/" - -# zap_automation = ZapAutomation(zap=zap, config_dir="", target=test_target) -# zap_automation.scan_target(target=test_target) - -# alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], []) - -# logging.info('Found ZAP Alerts: %s', str(len(alerts))) - -# assert int(len(alerts)) >= 2 - - -@pytest.mark.integrationtest -def test_juiceshop_scan_with_config(get_juiceshop_url, get_zap_instance: ZAPv2): - - zap = get_zap_instance - test_config_yaml = "./tests/mocks/scan-full-juiceshop-local/" - test_target = "http://localhost:3000/" - - zap_automation = ZapAutomation( - zap=zap, config_dir=test_config_yaml, target=test_target - ) - zap_automation.scan_target(target=test_target) - - alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], []) - - logging.info("Found ZAP Alerts: %s", str(len(alerts))) - - assert int(len(alerts)) >= 2 - - -@pytest.mark.integrationtest -def test_petstore_scan_with_config(get_petstore_url, get_zap_instance: ZAPv2): - - zap = get_zap_instance - test_config_yaml = "./tests/mocks/scan-full-petstore-local/" - test_target = "http://localhost:8000/" - - zap_automation = ZapAutomation( - zap=zap, config_dir=test_config_yaml, target=test_target - ) - zap_automation.scan_target(target=test_target) - - alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], []) - - logging.info("Found ZAP Alerts: %s", str(len(alerts))) - - assert int(len(alerts)) >= 1 - - -@pytest.mark.integrationtest -def test_petstore_scan_with_relative_config(get_petstore_url, get_zap_instance: ZAPv2): - - zap = get_zap_instance - test_config_yaml = "./tests/mocks/scan-full-petstore-relative/" - test_target = "http://localhost:8000/" - test_context = "scb-petstore-context" - - zap_automation = ZapAutomation( - zap=zap, - config_dir=test_config_yaml, - target=test_target, - forced_context=test_context, - ) - zap_automation.scan_target(target=test_target) - - alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], []) - - logging.info("Found ZAP Alerts: %s", str(len(alerts))) - - assert int(len(alerts)) >= 1 - - -@pytest.mark.integrationtest -def test_cascading_scan_config(get_zap_instance: ZAPv2): - - zap = get_zap_instance - test_target = "http://localhost:8080/bodgeit/" - test_config_yaml = "./tests/mocks/cascading-scan-full-local/" - test_context = "scb-test-context" - - zap_automation = ZapAutomation( - zap=zap, - config_dir=test_config_yaml, - target=test_target, - forced_context=test_context, - ) - zap_automation.scan_target(target=test_target) - - alerts = zap_automation.get_zap_scanner.get_alerts(test_target, [], []) - - logging.info("Found ZAP Alerts: %d", len(alerts)) - - assert int(len(alerts)) >= 1 diff --git a/scanners/zap-advanced/scanner/tests/test_zap_configuration.py b/scanners/zap-advanced/scanner/tests/test_zap_configuration.py deleted file mode 100644 index 110d8c806d..0000000000 --- a/scanners/zap-advanced/scanner/tests/test_zap_configuration.py +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/env python - -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# -*- coding: utf-8 -*- - -import pytest - -from unittest.mock import MagicMock, Mock -from unittest import TestCase - -from zapclient.configuration.zap_configuration import ZapConfiguration - - -class ZapConfigurationTests(TestCase): - @pytest.mark.unit - def test_always_passes(self): - self.assertTrue(True) - - @pytest.mark.unit - def test_empty_config_path(self): - config = ZapConfiguration("", "https://example.com") - self.assertIsNone(config.get_active_context_config) - - @pytest.mark.unit - def test_corrupt_config_path(self): - config = ZapConfiguration("not/existing/path", "https://example.com") - self.assertIsNone(config.get_active_context_config) - - @pytest.mark.unit - def test_existing_config_path(self): - config = ZapConfiguration( - "./tests/mocks/context-with-overlay/", "https://www.secureCodeBox.io/" - ) - self.assertIsNotNone(config.get_active_context_config) - - @pytest.mark.unit - def test_empty_config_folder(self): - config = ZapConfiguration( - "./tests/mocks/empty/", "https://www.secureCodeBox.io/" - ) - self.assertIsNone(config.get_active_context_config) - - @pytest.mark.unit - def test_empty_config_file(self): - config = ZapConfiguration( - "./tests/mocks/empty-files/", "https://www.secureCodeBox.io/" - ) - self.assertIsNone(config.get_active_context_config) - - @pytest.mark.unit - def test_config_context_without_overlay(self): - config = ZapConfiguration( - "./tests/mocks/context-without-overlay/", "https://www.secureCodeBox.io/" - ) - self.assertIsNotNone(config.get_active_context_config) - - @pytest.mark.unit - def test_config_context_with_overlay(self): - config = ZapConfiguration( - "./tests/mocks/context-with-overlay/", "https://www.secureCodeBox.io/" - ) - self.assertIsNotNone(config.get_active_context_config) - - @pytest.mark.unit - def test_returns_the_current_context_correctly(self): - config = ZapConfiguration( - "./tests/mocks/context-with-overlay/", "https://www.secureCodeBox.io/" - ) - context = config.get_active_context_config - self.assertIsNotNone(context) - self.assertEqual(context["name"], "secureCodeBoxScanType-NoAuth") - - @pytest.mark.unit - def test_has_spider_configurations(self): - config = ZapConfiguration( - "./tests/mocks/context-with-overlay/", "https://www.secureCodeBox.io/" - ) - self.assertIsNotNone(config.get_active_context_config) - self.assertIsNone(config.get_active_spider_config) - - config = ZapConfiguration( - "./tests/mocks/scan-full-bodgeit-docker/", "http://bodgeit:8080/bodgeit/" - ) - self.assertIsNotNone(config.get_active_context_config) - self.assertIsNotNone(config.get_active_spider_config) - - @pytest.mark.unit - def test_has_scan_configurations(self): - config = ZapConfiguration( - "./tests/mocks/context-with-overlay/", "https://www.secureCodeBox.io/" - ) - self.assertIsNotNone(config.get_active_context_config) - self.assertIsNone(config.get_active_spider_config) - - config = ZapConfiguration( - "./tests/mocks/scan-full-bodgeit-docker/", "http://bodgeit:8080/bodgeit/" - ) - self.assertIsNotNone(config.get_active_context_config) - self.assertIsNotNone(config.get_active_spider_config) - - @pytest.mark.unit - def test_has_scan_configurations(self): - config = ZapConfiguration( - "./tests/mocks/context-using-forced-context/", - "http://test.example.com", - forced_context="scb-test-context", - ) - self.assertIsNotNone(config.get_active_context_config) - self.assertEqual("scb-test-context", config.get_active_context_config["name"]) - - self.assertIsNotNone(config.get_active_spider_config) - self.assertEqual("scb-test-spider", config.get_active_spider_config["name"]) - - self.assertIsNotNone(config.get_active_scanner_config) - self.assertEqual("scb-test-scanner", config.get_active_scanner_config["name"]) diff --git a/scanners/zap-advanced/scanner/tests/test_zap_context.py b/scanners/zap-advanced/scanner/tests/test_zap_context.py deleted file mode 100644 index 1e0162239d..0000000000 --- a/scanners/zap-advanced/scanner/tests/test_zap_context.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python - -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# -*- coding: utf-8 -*- - -import pytest - -from unittest.mock import MagicMock, Mock, patch -from unittest import TestCase - -from zapv2 import ZAPv2 - -from zapclient.configuration import ZapConfiguration -from zapclient.context.zap_context import ZapConfigureContext - - -class ZapScannerTests(TestCase): - @pytest.mark.unit - def test_context_empty(self): - pass - - # # build our dependencies - # mock_zap = mock.create_autospec(ZAPv2.context.context_list) - # mock_config = mock.create_autospec(ZapConfiguration) - - # testobject = ZapConfigureContext(mock_zap, mock_config) - # testobject.configure_contexts() diff --git a/scanners/zap-advanced/scanner/tests/test_zap_scanner_active.py b/scanners/zap-advanced/scanner/tests/test_zap_scanner_active.py deleted file mode 100644 index 1a73b5ac0d..0000000000 --- a/scanners/zap-advanced/scanner/tests/test_zap_scanner_active.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python - -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# -*- coding: utf-8 -*- - -import pytest - -from unittest.mock import MagicMock, Mock -from unittest import TestCase - -from zapclient.configuration import ZapConfiguration -from zapclient.scanner.zap_scanner_active import ZapConfigureActiveScanner - - -class ZapConfigurationTests(TestCase): - @pytest.mark.unit - def test_has_scan_configurations(self): - config = ZapConfiguration( - "./tests/mocks/context-with-overlay/", "https://www.secureCodeBox.io/" - ) - self.assertIsNone(config.get_active_scanner_config) - - config = ZapConfiguration( - "./tests/mocks/scan-full-bodgeit-docker/", "http://bodgeit:8080/" - ) - self.assertIsNotNone(config.get_active_scanner_config) diff --git a/scanners/zap-advanced/scanner/tests/test_zap_spider_ajax.py b/scanners/zap-advanced/scanner/tests/test_zap_spider_ajax.py deleted file mode 100644 index 96d18434b1..0000000000 --- a/scanners/zap-advanced/scanner/tests/test_zap_spider_ajax.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python - -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# -*- coding: utf-8 -*- - -import pytest - -from unittest.mock import MagicMock, Mock -from unittest import TestCase - -from zapclient.configuration import ZapConfiguration -from zapclient.spider.zap_spider_ajax import ZapConfigureSpiderAjax - - -class ZapSpiderAjaxTests(TestCase): - @pytest.mark.unit - def test_has_spider_configurations(self): - config = ZapConfiguration( - "./tests/mocks/context-with-overlay/", "https://www.secureCodeBox.io/" - ) - self.assertIsNone(config.get_active_spider_config) - - config = ZapConfiguration( - "./tests/mocks/scan-full-juiceshop-docker/", "http://juiceshop:3000/" - ) - self.assertIsNotNone(config.get_active_spider_config) diff --git a/scanners/zap-advanced/scanner/tests/test_zap_spider_http.py b/scanners/zap-advanced/scanner/tests/test_zap_spider_http.py deleted file mode 100644 index e9bdb513c7..0000000000 --- a/scanners/zap-advanced/scanner/tests/test_zap_spider_http.py +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env python - -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# -*- coding: utf-8 -*- - -import pytest - -from unittest.mock import MagicMock, Mock -from unittest import TestCase - -from zapclient.configuration import ZapConfiguration - - -class ZapSpiderHttpTests(TestCase): - @pytest.mark.unit - def test_has_spider_configurations(self): - config = ZapConfiguration( - "./tests/mocks/context-with-overlay/", "https://www.secureCodeBox.io/" - ) - self.assertIsNone(config.get_active_spider_config) - - config = ZapConfiguration( - "./tests/mocks/scan-full-bodgeit-docker/", "http://bodgeit:8080/" - ) - self.assertIsNotNone(config.get_active_spider_config) diff --git a/scanners/zap-advanced/scanner/zapclient/__init__.py b/scanners/zap-advanced/scanner/zapclient/__init__.py deleted file mode 100644 index 2295d64dd1..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -""" -zapclient -A Python package containing secureCodeBox specific ZAPv2 Client extensions to automate ZAP. -""" - -__all__ = ["zap_abstract_client"] - -from .zap_abstract_client import ZapClient diff --git a/scanners/zap-advanced/scanner/zapclient/__main__.py b/scanners/zap-advanced/scanner/zapclient/__main__.py deleted file mode 100644 index df03854284..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/__main__.py +++ /dev/null @@ -1,148 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -import argparse -import logging -import sys - -from zapv2 import ZAPv2 - -from .zap_automation import ZapAutomation - -# set up logging to file - see previous section for more details -logging.basicConfig( - level=logging.INFO, - format="%(asctime)s %(name)-12s %(levelname)-8s: %(message)s", - datefmt="%Y-%m-%d %H:%M", -) - -logging = logging.getLogger("zapclient") - - -def main(): - args = get_parser_args() - - if args.target is None or len(args.target) <= 0: - logging.info("Argument error: No target specified!") - sys.exit(1) - - process(args) - - # logging.info('Write findings to file...') - # write_findings_to_file(args.output_folder, findings) - logging.info("Finished :-) !") - - -def process(args): - - api_key = None - if args.api_key is not None and len(args.api_key) > 0: - api_key = args.api_key - - # MANDATORY. Define the listening address of ZAP instance - zap_proxy = {"http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080"} - if args.zap_url is not None and len(args.zap_url) > 0: - zap_proxy = { - "http": "http://" + args.zap_url, - "https": "http://" + args.zap_url, - } - - logging.info(":: Configuring ZAP Instance with %s", zap_proxy) - # Connect ZAP API client to the listening address of ZAP instance - zap = ZAPv2(proxies=zap_proxy, apikey=api_key) - - logging.info( - ":: Starting SCB ZAP Automation Framework with config %s", args.config_folder - ) - zap_automation = ZapAutomation( - zap=zap, - config_dir=args.config_folder, - target=args.target, - forced_context=args.context, - ) - - try: - logging.info(":: Starting SCB ZAP Scan with target %s", args.target) - zap_automation.scan_target(target=args.target) - - alerts = zap_automation.get_zap_scanner.get_alerts(args.target, [], []) - logging.info(":: Found ZAP Alerts: %s", str(len(alerts))) - - summary = zap.alert.alerts_summary(baseurl=args.target) - logging.info(":: ZAP Alerts Summary: %s", str(summary)) - - zap_automation.generate_report_file( - file_path=args.output_folder, report_type=args.report_type - ) - - zap_automation.zap_shutdown() - logging.info(":: Finished !") - - except argparse.ArgumentError as e: - logging.exception(f"Argument error: {e}") - sys.exit(1) - except Exception as e: - logging.exception(f"Unexpected error: {e}") - zap_automation.zap_shutdown() - sys.exit(3) - - -def get_parser_args(args=None): - parser = argparse.ArgumentParser( - prog="zap-client", - description="OWASP secureCodeBox ZAP Client (can be used to automate ZAP instances based on YAML configuration files.)", - ) - parser.add_argument( - "-z", - "--zap-url", - help="The ZAP API Url used to call the ZAP API.", - default=None, - required=True, - ), - parser.add_argument( - "-a", - "--api-key", - help="The ZAP API Key used to call the ZAP API.", - default=None, - required=False, - ), - parser.add_argument( - "-c", - "--config-folder", - help="The path to a local folder containing the additional ZAP configuration YAMLs used to configure ZAP.", - default="/home/securecodebox/configs/", - required=False, - ) - parser.add_argument( - "-t", - "--target", - help="The target to scan with ZAP.", - default=None, - required=True, - ), - parser.add_argument( - "--context", - help="The name of the context to use. Has to be included in the config file(s).", - default=None, - ), - parser.add_argument( - "-o", - "--output-folder", - help="The path to a local folder used to store the output files, eg. the ZAP Report or logfiles.", - default="./", - required=False, - ) - parser.add_argument( - "-r", - "--report-type", - help="The ZAP Report Type.", - choices=["XML", "XML-plus", "JSON", "JSON-plus", "HTML", "HTML-plus", "MD"], - default=None, - required=False, - ) - return parser.parse_args(args) - - -if __name__ == "__main__": - main() diff --git a/scanners/zap-advanced/scanner/zapclient/api/__init__.py b/scanners/zap-advanced/scanner/zapclient/api/__init__.py deleted file mode 100644 index d67f40c134..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/api/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -""" -api -A Python package containing secureCodeBox specific ZAPv2 Client extensions to automate ZAP API scans. -""" - -__all__ = ["zap_api"] - -from .zap_api import ZapConfigureApi diff --git a/scanners/zap-advanced/scanner/zapclient/api/zap_api.py b/scanners/zap-advanced/scanner/zapclient/api/zap_api.py deleted file mode 100644 index c7f5d829a9..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/api/zap_api.py +++ /dev/null @@ -1,142 +0,0 @@ -#!/usr/bin/env python - -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# -*- coding: utf-8 -*- - -import json -import urllib - -import requests -import collections -import logging - -from urllib.parse import urlparse -from zapv2 import ZAPv2 - -from .. import ZapClient -from ..configuration import ZapConfiguration - -# set up logging to file - see previous section for more details -logging.basicConfig( - level=logging.INFO, - format="%(asctime)s %(name)-12s %(levelname)-8s: %(message)s", - datefmt="%Y-%m-%d %H:%M", -) - -logging = logging.getLogger("ZapConfigureApi") - - -class ZapConfigureApi(ZapClient): - """This class configures a Api scan in a running ZAP instance, based on a ZAP Configuration. - - Based on this opensource ZAP Python example: - - https://github.com/zaproxy/zap-api-python/blob/9bab9bf1862df389a32aab15ea4a910551ba5bfc/src/examples/zap_example_api_script.py - """ - - def __init__(self, zap: ZAPv2, config: ZapConfiguration): - """Initial constructor used for this class. - - Parameters - ---------- - zap : ZAPv2 - The running ZAP instance to configure. - config : ZapConfiguration - The configuration object containing all ZAP configs (based on the class ZapConfiguration). - """ - - super().__init__(zap, config) - - self.__api_config = None - - # if at least one ZAP Context is defined start to configure the running ZAP instance (`zap`) accordingly - if ( - self.get_config.has_configurations - and self.get_config.get_active_api_config is not None - ): - logging.debug( - "Configure API Import with: %s", self.get_config.get_active_api_config - ) - else: - logging.warning( - "No valid ZAP configuration object found: %s! It seems there is something important missing.", - config, - ) - - @property - def get_api_config(self) -> collections.OrderedDict: - """Returns the spider config of the currently running ZAP instance.""" - return self.__api_config - - def start_api_import( - self, - url: str, - context: collections.OrderedDict, - api_config: collections.OrderedDict, - ): - """Starts a ZAP Api scan for the given target, based on the given configuration and ZAP instance. - - Parameters - ---------- - url: str - The target to Api. - context: - The active context for the current scan / api import - api_config: - Active api_config that should be used for the api import - """ - - logging.debug("Trying to configure the API Scan") - self.configure_scripts(config=api_config) - - logging.info("Trying to start API Import with target url: '%s'", url) - - if ( - (api_config is None) - or "format" not in api_config - or api_config["format"] != "openapi" - ): - logging.info( - "No complete API definition configured (format: openapi): %s!", - api_config, - ) - return - - if "url" not in api_config and "path" not in api_config: - logging.warning( - "API Config section '%s' has neither a 'url' or a 'path' configured. It will be skipped", - api_config["name"], - ) - return - - api_spec_url = None - - if "url" in api_config: - api_spec_url = api_config["url"] - elif "path" in api_config: - logging.info( - "Building OpenAPI Spec from path (%s) and the target url (%s)", - api_config["path"], - url, - ) - api_spec_url = ( - urllib.parse.urlparse(url)._replace(path=api_config["path"]).geturl() - ) - - logging.info("Import OpenAPI Spec from (%s)", api_spec_url) - if "hostOverride" in api_config: - result = self.get_zap.openapi.import_url( - api_spec_url, api_config["hostOverride"] - ) - else: - logging.warning( - "No 'hostOverride' configured for target %s. Defaulting for target as override.", - url, - ) - result = self.get_zap.openapi.import_url(api_spec_url, url) - - urls = self.get_zap.core.urls() - logging.info("Number of Imported URLs: %d", len(urls)) - logging.debug("Import warnings: %s", str(result)) diff --git a/scanners/zap-advanced/scanner/zapclient/configuration/__init__.py b/scanners/zap-advanced/scanner/zapclient/configuration/__init__.py deleted file mode 100644 index e30976aa1c..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/configuration/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -""" -configuration -A Python package containing secureCodeBox specific ZAPv2 Client configuration parsing based on a YAML format. -""" - -__all__ = ["zap_configuration"] - -from .zap_configuration import ZapConfiguration diff --git a/scanners/zap-advanced/scanner/zapclient/configuration/helpers/__init__.py b/scanners/zap-advanced/scanner/zapclient/configuration/helpers/__init__.py deleted file mode 100644 index deb792a856..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/configuration/helpers/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -__all__ = ["zap_configuration_context_users"] - -from .zap_configuration_context_users import ZapConfigurationContextUsers diff --git a/scanners/zap-advanced/scanner/zapclient/configuration/helpers/zap_configuration_context_users.py b/scanners/zap-advanced/scanner/zapclient/configuration/helpers/zap_configuration_context_users.py deleted file mode 100644 index 4bf42a0b8e..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/configuration/helpers/zap_configuration_context_users.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python - -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# -*- coding: utf-8 -*- - -import collections - - -class ZapConfigurationContextUsers: - """Helper class to grab user related configs from a context""" - - @staticmethod - def get_context_user_by_name( - context: collections.OrderedDict, name: str - ) -> collections.OrderedDict: - """Returns the ZAP Context Users configuration object with the given name. - - Parameters - ---------- - context: collections.OrderedDict - The ZAP context configuration object to return the user for. - name: str - The name of the context to return from the list of contexts. - """ - users = context["users"] if "users" in context else [] - return next((user for user in users if user["name"] == name), None) diff --git a/scanners/zap-advanced/scanner/zapclient/configuration/zap_configuration.py b/scanners/zap-advanced/scanner/zapclient/configuration/zap_configuration.py deleted file mode 100644 index fff2fef8ad..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/configuration/zap_configuration.py +++ /dev/null @@ -1,179 +0,0 @@ -#!/usr/bin/env python - -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# -*- coding: utf-8 -*- - -import collections -import logging -import glob -import hiyapyco - -from typing import List - -# set up logging to file - see previous section for more details -logging.basicConfig( - level=logging.INFO, - format="%(asctime)s %(name)-12s %(levelname)-8s: %(message)s", - datefmt="%Y-%m-%d %H:%M", -) - -logging = logging.getLogger("ZapClient") - - -class ZapConfiguration: - """This class represent a ZAP specific configuration based on a given YAML file.""" - - def __init__(self, config_dir: str, target: str, forced_context: str = None): - """Initial constructor used for this class - - Parameters - ---------- - config_dir : str - The relative path to the config dir containing all relevant config YAML files. - """ - - self.config_dir = config_dir - self.config_dir_glob = config_dir + "*.yaml" - self.target = target - self.forced_context = forced_context - - self.__config = collections.OrderedDict() - self.__read_config_files() - - def __read_config_files(self): - """Private method to read all existing config YAML files an create a new ZAP Configuration object""" - - if self.config_dir is not None and len(self.config_dir) > 0: - logging.debug("ZAP YAML config dir: '%s'", self.config_dir) - config_files = glob.glob(self.config_dir_glob) - else: - logging.warning( - "YAML config dir not found! This is no problem but possibly not intendend here." - ) - config_files = [] - - logging.info( - "Importing YAML files for ZAP configuration at dir: '%s'", config_files - ) - if len(config_files) > 0: - config_files.sort() - self.__config = hiyapyco.load( - *config_files, - method=hiyapyco.METHOD_MERGE, - interpolate=True, - mergelists=True, - failonmissingfiles=False - ) - logging.debug("Finished importing YAML: %s", self.__config) - else: - logging.warning( - "No ZAP YAML Configuration files found :-/ This is no problem but possibly not intendend here." - ) - self.__config = collections.OrderedDict() - - @property - def has_configurations(self) -> bool: - """Returns true if any ZAP Configuration is defined, otherwise false.""" - - return (self.__config is not None) and len(self.__config) > 0 - - @property - def get_configurations(self) -> collections.OrderedDict: - """Returns the complete ZAP Configuration object""" - - return self.__config - - def has_global_configurations(self) -> bool: - """Returns true if any ZAP Global Configuration is defined, otherwise false.""" - - return self.has_configurations and "global" in self.get_configurations - - @property - def get_global(self) -> collections.OrderedDict: - """Returns the complete ZAP Configuration object""" - result = collections.OrderedDict() - - if self.has_global_configurations(): - result = self.get_configurations["global"] - - return result - - @property - def get_all_contexts(self) -> List[collections.OrderedDict]: - return self.__config["contexts"] if "contexts" in self.__config else [] - - def _get_active_config_from(self, configs: collections.OrderedDict, key: str): - """Returns the active configuration by matching url or context - - Parameters - ---------- - configs: list[collections.OrderedDict] - All configs available for this config type. E.g. all spider configs. - key: str - The key of the config object, e.g. - """ - if configs is None: - logging.warning( - "Config is not defined!", - ) - return None - if not isinstance(configs, collections.OrderedDict): - logging.warning( - "Config should be a map!", - ) - return None - if key not in configs: - logging.warning("No %s config found in the config.!", key) - return None - - if self.forced_context is not None: - # if this method is getting a context, - # search for the "name" key to match. Otherwise search for for the "context" attribute - look_for = "name" if key == "contexts" else "context" - for configuration in configs[key]: - if ( - look_for in configuration - and configuration[look_for] == self.forced_context - ): - return configuration - - logging.warning( - "No %s specific configuration found using for the configured context (%s)!", - key, - self.forced_context, - ) - else: - for configuration in configs[key]: - if "url" in configuration and configuration["url"].startswith( - self.target - ): - return configuration - - logging.warning( - "No %s specific configuration found using the given target url (%s)!", - key, - self.target, - ) - return None - - @property - def get_active_context_config(self) -> collections.OrderedDict: - return self._get_active_config_from(self.get_configurations, "contexts") - - @property - def get_active_api_config(self) -> collections.OrderedDict: - return self._get_active_config_from(self.get_configurations, "apis") - - @property - def get_active_spider_config(self) -> collections.OrderedDict: - return self._get_active_config_from(self.get_configurations, "spiders") - - @property - def get_active_scanner_config(self) -> collections.OrderedDict: - return self._get_active_config_from(self.get_configurations, "scanners") - - def __str__(self): - return " ZapConfiguration( " + str(self.get_configurations) + " )" diff --git a/scanners/zap-advanced/scanner/zapclient/context/__init__.py b/scanners/zap-advanced/scanner/zapclient/context/__init__.py deleted file mode 100644 index 2bbfc63813..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/context/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -""" -context -A Python package containing secureCodeBox specific ZAPv2 Client extensions to configure ZAP API contexts. -""" - -__all__ = ["zap_context", "zap_context_authentication"] - -from .zap_context import ZapConfigureContext -from .zap_context_authentication import ZapConfigureContextAuthentication diff --git a/scanners/zap-advanced/scanner/zapclient/context/zap_context.py b/scanners/zap-advanced/scanner/zapclient/context/zap_context.py deleted file mode 100644 index 92b3d74d5d..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/context/zap_context.py +++ /dev/null @@ -1,431 +0,0 @@ -#!/usr/bin/env python - -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# -*- coding: utf-8 -*- - -import collections -import logging - -from zapv2 import ZAPv2 -from typing import List - -from .. import ZapClient -from ..configuration import ZapConfiguration -from .zap_context_authentication import ZapConfigureContextAuthentication - -# set up logging to file - see previous section for more details -logging.basicConfig( - level=logging.INFO, - format="%(asctime)s %(name)-12s %(levelname)-8s: %(message)s", - datefmt="%Y-%m-%d %H:%M", -) - -logging = logging.getLogger("ZapConfigureContext") - - -class ZapConfigureContext(ZapClient): - """This class configures the context in running ZAP instance, based on a given ZAP Configuration. - - Based on this opensource ZAP Python example: - - https://github.com/zaproxy/zap-api-python/blob/9bab9bf1862df389a32aab15ea4a910551ba5bfc/src/examples/zap_example_api_script.py - - """ - - def __init__(self, zap: ZAPv2, config: ZapConfiguration): - """Initial constructor used for this class - - Parameters - ---------- - zap : ZAPv2 - The running ZAP instance to configure. - config : ZapConfiguration - The configuration object containing all ZAP configs (based on the class ZapConfiguration). - """ - - super().__init__(zap, config) - - def configure_contexts(self): - """Configures the ZAP instance with the given list of contexts.""" - - if self.get_config.has_configurations: - - contexts = self.get_config.get_all_contexts - - logging.debug( - "Configuring the List of #%s context(s) with: %s", - len(contexts), - contexts, - ) - - # Remove all existing ZAP contexts - logging.info( - "Existing Contexts will be removed: %s", - self.get_zap.context.context_list, - ) - for remove_context in self.get_zap.context.context_list: - self.get_zap.context.remove_context(contextname=remove_context) - - # Add all new ZAP contexts - for context in contexts: - self._configure_context(context) - - else: - logging.warning( - "No valid ZAP configuration object found: %s! It seems there is something important missing.", - self.get_config, - ) - - def _configure_context(self, context: collections.OrderedDict): - """Configures the ZAP instance with the context. - - Parameters - ---------- - context : collections.OrderedDict - The zap configuration object containing a single context configuration (based on the class ZapConfiguration). - """ - - context_name = context["name"] - logging.info("Configuring a new ZAP Context with name: " + context_name) - context_id = self.get_zap.context.new_context(context_name) - context["id"] = context_id - - if self._is_not_empty("includePaths", context): - self._configure_context_include(context) - - if self._is_not_empty("excludePaths", context): - self._configure_context_exclude(context) - - if self._is_not_empty("authentication", context) and self._is_not_empty_string( - "type", context["authentication"] - ): - configure_authenication = ZapConfigureContextAuthentication( - zap=self.get_zap, config=self.get_config - ) - configure_authenication.configure_context_authentication( - context, context_id - ) - - if self._is_not_empty("users", context) and self._is_not_empty_string( - "type", context["authentication"] - ): - self._configure_context_create_users( - users=context["users"], - auth_type=context["authentication"]["type"], - context_id=context_id, - ) - - if self._is_not_empty("session", context) and self._is_not_empty_string( - "type", context["session"] - ): - self._configure_context_session_management( - sessions_config=context["session"], context_id=context_id - ) - - if self._is_not_empty("technologies", context): - # TODO: Open a new ZAP GH Issue: Why (or) is this difference (context_id vs. context_name) here really necessary? - self._configure_context_technologies(context["technologies"], context_name) - - if self._is_not_empty("alertFilters", context): - self._configure_alert_filters(context["alertFilters"], context_id) - - def _configure_context_include(self, context: collections.OrderedDict): - """Protected method to configure the ZAP 'Context / Include Settings' based on a given ZAP config. - - Parameters - ---------- - contexts : collections.OrderedDict - The zap configuration object containing the ZAP include configuration (based on the class ZapConfiguration). - """ - - if "includePaths" in context: - for regex in context["includePaths"]: - logging.debug("Including regex '%s' from context", regex) - self.get_zap.context.include_in_context( - contextname=context["name"], regex=regex - ) - - def _configure_context_exclude(self, context: collections.OrderedDict): - """Protected method to configure the ZAP 'Context / Exclude Settings' based on a given ZAP config. - - Parameters - ---------- - contexts : collections.OrderedDict - The current zap configuration object containing the ZAP exclude configuration (based on the class ZapConfiguration). - """ - - if "excludePaths" in context: - for regex in context["excludePaths"]: - logging.debug("Excluding regex '%s' from context", regex) - self.get_zap.context.exclude_from_context( - contextname=context["name"], regex=regex - ) - - def _configure_context_create_users( - self, users: collections.OrderedDict, auth_type: str, context_id: int - ): - """Protected method to configure the ZAP 'Context / Users Settings' based on a given ZAP config. - - Parameters - ---------- - users : collections.OrderedDict - The current users (list) configuration object containing the ZAP users configuration (based on the class ZapConfiguration). - auth_type: str - The configured authentiation type (e.g.: "basic-auth", "form-based", "json-based", "script-based"). - context_id : int - The zap context id tot configure the ZAP authentication for (based on the class ZapConfiguration). - """ - - # Remove all existing ZAP Users for given context - logging.info("Existing Users will be removed before adding new ones.") - for user_id in self.get_zap.users.users_list(contextid=context_id): - self.get_zap.users.remove_user(contextid=context_id, userid=user_id) - - # Add all new ZAP Users to given context - for user in users: - self._configure_context_create_user(user, auth_type, context_id) - - def _configure_context_create_user( - self, user: collections.OrderedDict, auth_type: str, context_id: int - ): - """Protected method to adds anew User to the ZAP Context. - - Parameters - ---------- - user : collections.OrderedDict - The user configuration object to add. - auth_type: str - The configured authentiation type (e.g.: "basic-auth", "form-based", "json-based", "script-based"). - context_id : int - The zap context id tot configure the ZAP authentication for (based on the class ZapConfiguration). - """ - - logging.debug("Adding ZAP User '%s', to context(%s)", user, context_id) - user_name = user["username"] - user_password = user["password"] - - user_id = self.get_zap.users.new_user(contextid=context_id, name=user_name) - logging.debug("Created ZAP User(%s), for context(%s)", user_id, context_id) - user["id"] = user_id - - self.get_zap.users.set_user_name( - contextid=context_id, userid=user_id, name=user_name - ) - - self.get_zap.users.set_authentication_credentials( - contextid=context_id, - userid=user_id, - authcredentialsconfigparams="username=" - + user_name - + "&password=" - + user_password, - ) - self.get_zap.users.set_user_enabled( - contextid=context_id, userid=user_id, enabled=True - ) - - if "forced" in user and user["forced"]: - logging.debug( - "Configuring a forced user '%s' with id, for context(%s)'", - user_id, - context_id, - ) - self.get_zap.forcedUser.set_forced_user( - contextid=context_id, userid=user_id - ) - self.get_zap.forcedUser.set_forced_user_mode_enabled(True) - - def _configure_context_session_management( - self, sessions_config: collections.OrderedDict, context_id: int - ): - """Protected method to configure the ZAP 'Context / Session Mannagement' Settings based on a given ZAP config. - - Parameters - ---------- - sessions : collections.OrderedDict - The current sessions configuration object containing the ZAP sessions configuration (based on the class ZapConfiguration). - context_id : int - The zap context id tot configure the ZAP authentication for (based on the class ZapConfiguration). - """ - - sessions_type = sessions_config["type"] - - logging.info("Configuring the ZAP session management (type=%s)", sessions_type) - if sessions_type == "cookieBasedSessionManagement": - logging.debug("Configuring cookieBasedSessionManagement") - self.get_zap.sessionManagement.set_session_management_method( - contextid=context_id, methodname="cookieBasedSessionManagement" - ) - elif sessions_type == "httpAuthSessionManagement": - logging.debug("Configuring httpAuthSessionManagement") - self.get_zap.sessionManagement.set_session_management_method( - contextid=context_id, methodname="httpAuthSessionManagement" - ) - elif sessions_type == "scriptBasedSessionManagement": - logging.debug("Configuring scriptBasedSessionManagement()") - if "scriptBasedSessionManagement" in sessions_config: - script_config = sessions_config["scriptBasedSessionManagement"] - self._configure_context_session_management_scriptbased( - script_config=script_config, context_id=context_id - ) - else: - logging.warning( - "The 'scriptBasedSessionManagement' configuration section is missing but you have activated it (type: scriptBasedSessionManagement)! Ignoring the script configuration for session management. Please check your YAML configuration." - ) - - def _configure_context_session_management_scriptbased( - self, script_config: collections.OrderedDict, context_id: int - ): - """Protected method to configure the ZAP 'Context / Session Mannagement' Settings based on script. - - Parameters - ---------- - script_config : collections.OrderedDict - The script_config configuration object containing the ZAP Script specific configuration (based on the class ZapConfiguration). - context_id : int - The zap context id tot configure the ZAP authentication for (based on the class ZapConfiguration). - """ - - logging.debug("Script Config: %s", str(script_config)) - self._configure_load_script(script_config=script_config, script_type="session") - - if self._is_not_empty_string("name", script_config): - # Here they say that only "cookieBasedSessionManagement"; "httpAuthSessionManagement" - # is possible, but maybe this is outdated and it works anyway, hopefully: - # https://github.com/zaproxy/zap-api-python/blob/9bab9bf1862df389a32aab15ea4a910551ba5bfc/src/examples/zap_example_api_script.py#L97 - session_params = "scriptName=" + script_config["name"] - self.get_zap.sessionManagement.set_session_management_method( - contextid=context_id, - methodname="scriptBasedSessionManagement", - methodconfigparams=session_params, - ) - else: - logging.warning( - "Important script authentication configs (script name) are missing! Ignoring the authenication script configuration. Please check your YAML configuration." - ) - - def _configure_context_technologies( - self, technology: collections.OrderedDict, context_name: str - ): - """Protected method to configure the ZAP 'Context / Technology' Settings based on a given ZAP config. - - Parameters - ---------- - technology : collections.OrderedDict - The current technology configuration object containing the ZAP technology configuration (based on the class ZapConfiguration). - context_id : int - The zap context id tot configure the ZAP authentication for (based on the class ZapConfiguration). - """ - - if technology: - # Remove all existing ZAP Users for given context - # logging.warning("Existing technologies ' %s' will be removed for context: %s", zap.context.technology_list, context_name) - # zap.context.exclude_all_context_technologies(contextname=context_name) - - if "included" in technology: - technologies = ", ".join(technology["included"]) - logging.debug( - "Include technologies '%s' in context with name %s", - technologies, - context_name, - ) - self.get_zap.context.include_context_technologies( - contextname=context_name, technologynames=technologies - ) - - if "excluded" in technology: - technologies = ", ".join(technology["included"]) - logging.debug( - "Exclude technologies '%s' in context with name %s", - technologies, - context_name, - ) - self.get_zap.context.exclude_context_technologies( - contextname=context_name, technologynames=technologies - ) - - def _get_or_none(self, dict: collections.OrderedDict, key: str): - if dict == None or not isinstance(dict, collections.OrderedDict): - return None - - if key in dict: - return dict[key] - else: - return None - - def _get_or_none_stringified(self, dict: collections.OrderedDict, key: str): - value = self._get_or_none(dict, key) - - if value == None: - return None - else: - return str(value) - - def _get_level(self, level: str): - # lowercase input to catch simple typos - level = level.lower() - if level == "false positive": - return -1 - elif level == "info" or level == "informational": - return 0 - elif level == "low": - return 1 - elif level == "medium": - return 2 - elif level == "high": - return 3 - - logging.warn( - "AlertFilter configured with unknown level: '%s'. This rule will be ignored!", - level, - ) - return None - - def _configure_alert_filters( - self, alert_filters: List[collections.OrderedDict], context_id: int - ): - """Protected method to configure the ZAP 'Context / Alert Filters' Settings based on a given ZAP config. - - Parameters - ---------- - alert_filters : collections.OrderedDict - The current alert filter configuration object containing the ZAP alert filter configuration (based on the class ZapConfiguration). - context_id : int - The zap context id to configure the ZAP alert filters for (based on the class ZapConfiguration). - """ - - if alert_filters: - for alert_filter in alert_filters: - logging.debug( - "Adding AlertFilter for rule '%d' in context with id %s", - alert_filter["ruleId"], - context_id, - ) - - matches = ( - alert_filter["matches"] - if "matches" in alert_filter - else collections.OrderedDict() - ) - self.get_zap.alertFilter.add_alert_filter( - contextid=context_id, - ruleid=str(alert_filter["ruleId"]), - newlevel=str(self._get_level(alert_filter["newLevel"])), - # optional matchers - url=self._get_or_none(matches, "url"), - urlisregex=self._get_or_none_stringified(matches, "urlIsRegex"), - parameter=self._get_or_none(matches, "parameter"), - parameterisregex=self._get_or_none_stringified( - matches, "parameterIsRegex" - ), - attack=self._get_or_none(matches, "attack"), - attackisregex=self._get_or_none_stringified( - matches, "attackIsRegex" - ), - evidence=self._get_or_none(matches, "evidence"), - evidenceisregex=self._get_or_none_stringified( - matches, "evidenceIsRegex" - ), - ) diff --git a/scanners/zap-advanced/scanner/zapclient/context/zap_context_authentication.py b/scanners/zap-advanced/scanner/zapclient/context/zap_context_authentication.py deleted file mode 100644 index 88353414cc..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/context/zap_context_authentication.py +++ /dev/null @@ -1,257 +0,0 @@ -#!/usr/bin/env python - -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# -*- coding: utf-8 -*- - -import collections -import logging - -from zapv2 import ZAPv2 - -from .. import ZapClient -from ..configuration import ZapConfiguration - -# set up logging to file - see previous section for more details -logging.basicConfig( - level=logging.INFO, - format="%(asctime)s %(name)-12s %(levelname)-8s: %(message)s", - datefmt="%Y-%m-%d %H:%M", -) - -logging = logging.getLogger("ZapConfigureContextAuthentication") - - -class ZapConfigureContextAuthentication(ZapClient): - """This class configures the context in running ZAP instance, based on a given ZAP Configuration.""" - - def __init__(self, zap: ZAPv2, config: ZapConfiguration): - """Initial constructor used for this class - - Parameters - ---------- - zap : ZAPv2 - The running ZAP instance to configure. - config : ZapConfiguration - The configuration object containing all ZAP configs (based on the class ZapConfiguration). - """ - - super().__init__(zap, config) - - def configure_context_authentication( - self, context: collections.OrderedDict, context_id: int - ): - """Protected method to configure the ZAP 'Context / Authentication Settings' based on a given ZAP config. - - Parameters - ---------- - context: collections.OrderedDict - The current configuration object containing the ZAP authentication configuration (based on the class ZapConfiguration). - context_id : int - The zap context id tot configure the ZAP authentication for (based on the class ZapConfiguration). - """ - - authentication = context["authentication"] - auth_type = authentication["type"] - - if auth_type == "script-based" and "script-based" in authentication: - self._configure_context_authentication_script( - authentication["script-based"], context_id - ) - elif auth_type == "basic-auth" and "basic-auth" in authentication: - self._configure_context_authentication_basic_auth( - authentication["basic-auth"], context_id - ) - elif auth_type == "form-based" and "form-based" in authentication: - self._configure_context_authentication_form_auth( - authentication["form-based"], context_id - ) - elif auth_type == "json-based" and "json-based" in authentication: - self._configure_context_authentication_json_auth( - authentication["json-based"], context_id - ) - - if self._is_not_empty("verification", authentication): - self._configure_auth_validation(authentication["verification"], context_id) - - def _configure_context_authentication_script( - self, script_config: collections.OrderedDict, context_id: int - ): - """Protected method to configure the ZAP 'Context / Authentication Settings with Script based Authentication' based on a given ZAP config. - - Parameters - ---------- - script_config : collections.OrderedDict - The current 'script-based' authentication configuration object containing the ZAP authentication configuration (based on the class ZapConfiguration). - context_id : int - The zap context id tot configure the ZAP authentication for (based on the class ZapConfiguration). - """ - - if ( - not script_config == None - and "name" in script_config - and "filePath" in script_config - and "engine" in script_config - ): - self._configure_load_script( - script_config=script_config, script_type="authentication" - ) - - auth_params = self.__get_script_auth_params(script_config) - - # Add additional script parameters - logging.debug("Loading Authentication Script Parameters: %s", auth_params) - self.check_zap_result( - result=self.get_zap.authentication.set_authentication_method( - contextid=context_id, - authmethodname="scriptBasedAuthentication", - authmethodconfigparams=auth_params, - ), - method_name="set_authentication_method", - exception_message="Missing ZAP Authentication Script Parameters! Please check your secureCodeBox YAML configuration!", - ) - else: - logging.warning( - "Important script authentication configs (name, filePath, engine) are missing! Ignoring the authentication script configuration. Please check your YAML configuration." - ) - - def _configure_context_authentication_basic_auth( - self, basic_auth: collections.OrderedDict, context_id: int - ): - """Protected method to configure the ZAP 'Context / Authentication Settings with Basic Authentication' based on a given ZAP config. - - Parameters - ---------- - basic_auth : collections.OrderedDict - The current 'basic-auth' authentication configuration object containing the ZAP authentication configuration (based on the class ZapConfiguration). - context_id : int - The zap context id tot configure the ZAP authentication for (based on the class ZapConfiguration). - """ - - logging.debug("Enabling ZAP HTTP Basic Auth") - - if "hostname" in basic_auth: - auth_method_config_params = "hostname=" + basic_auth["hostname"] - if "realm" in basic_auth: - auth_method_config_params += "&realm=" + basic_auth["realm"] - if "port" in basic_auth: - auth_method_config_params += "&port=" + str(basic_auth["port"]) - - logging.info("HTTP BasicAuth Params: '%s'", auth_method_config_params) - - self.get_zap.authentication.set_authentication_method( - contextid=context_id, - authmethodname="httpAuthentication", - authmethodconfigparams=auth_method_config_params, - ) - - def _configure_context_authentication_form_auth( - self, form_auth: collections.OrderedDict, context_id: int - ): - """Protected method to configure the ZAP 'Context / Authentication Settings with Form Authentication' based on a given ZAP config. - - Parameters - ---------- - form_auth : collections.OrderedDict - The current 'form-auth' authentication configuration object containing the ZAP authentication configuration (based on the class ZapConfiguration). - context_id : int - The zap context id tot configure the ZAP authentication for (based on the class ZapConfiguration). - """ - - logging.debug("Enabling ZAP HTTP Form based Authentication") - - if "loginUrl" in form_auth: - auth_method_config_params = "loginUrl=" + form_auth["loginUrl"] - if "loginRequestData" in form_auth: - auth_method_config_params += ( - "&loginRequestData=" + form_auth["loginRequestData"] - ) - - logging.debug("HTTP ZAP HTTP Form Params: '%s'", auth_method_config_params) - - self.get_zap.authentication.set_authentication_method( - contextid=context_id, - authmethodname="formBasedAuthentication", - authmethodconfigparams=auth_method_config_params, - ) - - def _configure_context_authentication_json_auth( - self, json_auth: collections.OrderedDict, context_id: int - ): - """Protected method to configure the ZAP 'Context / Authentication Settings with JSON Authentication' based on a given ZAP config. - - Parameters - ---------- - json_auth : collections.OrderedDict - The current 'json-auth' authentication configuration object containing the ZAP authentication configuration (based on the class ZapConfiguration). - context_id : int - The zap context id tot configure the ZAP authentication for (based on the class ZapConfiguration). - """ - - logging.debug("Enabling ZAP HTTP JSON based Authentication") - - if "loginUrl" in json_auth: - auth_method_config_params = "loginUrl=" + json_auth["loginUrl"] - if "loginRequestData" in json_auth: - auth_method_config_params += ( - "&loginRequestData=" + json_auth["loginRequestData"] - ) - - logging.debug("HTTP ZAP HTTP JSON Params: '%s'", auth_method_config_params) - - self.get_zap.authentication.set_authentication_method( - contextid=context_id, - authmethodname="jsonBasedAuthentication", - authmethodconfigparams=auth_method_config_params, - ) - - def _configure_auth_validation( - self, validation: collections.OrderedDict, context_id: int - ): - """Protected method to configure the ZAP 'Context / Authentication Settings with Script based Authentication' based on a given ZAP config. - - Parameters - ---------- - validation : collections.OrderedDict - The current 'script-based' authentication configuration object containing the ZAP authentication configuration (based on the class ZapConfiguration). - context_id : int - The zap context id tot configure the ZAP authentication for (based on the class ZapConfiguration). - """ - - logging.debug("Configure Authentication Validation: %s", validation) - - if "isLoggedInIndicator" in validation: - self.get_zap.authentication.set_logged_in_indicator( - contextid=context_id, - loggedinindicatorregex=validation["isLoggedInIndicator"], - ) - if "isLoggedOutIndicator" in validation: - self.get_zap.authentication.set_logged_out_indicator( - contextid=context_id, - loggedoutindicatorregex=validation["isLoggedOutIndicator"], - ) - - def __get_script_auth_params(self, script_config: collections.OrderedDict) -> list: - """Protected method to configure the ZAP 'Context / Authentication Settings with JSON Authentication' based on a given ZAP config. - - Parameters - ---------- - json_auth : collections.OrderedDict - The current 'json-auth' authentication configuration object containing the ZAP authentication configuration (based on the class ZapConfiguration). - context_id : int - The zap context id tot configure the ZAP authentication for (based on the class ZapConfiguration). - """ - - # Create ZAP Script parameters based on given configuration object - auth_params = [ - "scriptName=" + script_config["name"], - ] - # Creates a list of URL-Encoded params, based on the YAML config - for key, value in script_config["arguments"].items(): - auth_params.append(key + "=" + value) - # Add a '&' to all elements except the last one - auth_params = "&".join(auth_params) - - return auth_params diff --git a/scanners/zap-advanced/scanner/zapclient/scanner/__init__.py b/scanners/zap-advanced/scanner/zapclient/scanner/__init__.py deleted file mode 100644 index f6d2837d4a..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/scanner/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -""" -zapclient -A Python package containing secureCodeBox specific ZAPv2 Client extensions to automate ZAP scans.. -""" - -__all__ = ["zap_scanner", "zap_scanner_active"] - -from .zap_abstract_scanner import ZapConfigureScanner -from .zap_scanner_active import ZapConfigureActiveScanner diff --git a/scanners/zap-advanced/scanner/zapclient/scanner/zap_abstract_scanner.py b/scanners/zap-advanced/scanner/zapclient/scanner/zap_abstract_scanner.py deleted file mode 100644 index f146fd939c..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/scanner/zap_abstract_scanner.py +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env python - -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# -*- coding: utf-8 -*- - -import collections -import logging - -from zapv2 import ZAPv2 -from abc import abstractmethod - -from .. import ZapClient -from ..configuration import ZapConfiguration - -# set up logging to file - see previous section for more details -logging.basicConfig( - level=logging.INFO, - format="%(asctime)s %(name)-12s %(levelname)-8s: %(message)s", - datefmt="%Y-%m-%d %H:%M", -) - -logging = logging.getLogger("ZapConfigureScanner") - - -class ZapConfigureScanner(ZapClient): - """This class configures a scanner in a running ZAP instance, based on a ZAP Configuration - - Based on this opensource ZAP Python example: - - https://github.com/zaproxy/zap-api-python/blob/9bab9bf1862df389a32aab15ea4a910551ba5bfc/src/examples/zap_example_api_script.py - """ - - def __init__(self, zap: ZAPv2, config: ZapConfiguration): - """Initial constructor used for this class - - Parameters - ---------- - zap : ZAPv2 - The running ZAP instance to configure. - config : ZapConfiguration - The configuration object containing all ZAP configs (based on the class ZapConfiguration). - """ - - super().__init__(zap, config) - - def start_scan_by_url(self, url: str) -> int: - """Starts a ZAP ActiveScan for the given target, based on the given configuration and ZAP instance. - - Parameters - ---------- - url: str - The url to scan with the ZAP active scanner. - """ - scannerId = -1 - - if self.get_config.get_active_scanner_config is not None: - logging.debug( - "Trying to start ActiveScan by configuration target url: '%s'", str(url) - ) - - scanner_config = self.get_config.get_active_scanner_config - scannerId = self.start_scanner(url=url, scanner_config=scanner_config) - else: - logging.warning( - "There is no scanner configuration section defined in your configuration YAML to start by url: %s.", - url, - ) - scannerId = self.start_scanner(url=url, scanner_config=None) - - return int(scannerId) - - @abstractmethod - def start_scanner(self, url: str, scanner_config: collections.OrderedDict) -> int: - """Starts a ZAP Spider with the given spiders configuration, based on the internal referenced ZAP instance. - - Parameters - ---------- - spider_config: collections.OrderedDict - The spider configuration based on ZapConfiguration. - """ - raise NotImplementedError - - @abstractmethod - def wait_until_finished(self, scanner_id: int): - """Wait until the running ZAP Scanner finished and log results.""" - raise NotImplementedError diff --git a/scanners/zap-advanced/scanner/zapclient/scanner/zap_scanner_active.py b/scanners/zap-advanced/scanner/zapclient/scanner/zap_scanner_active.py deleted file mode 100644 index 94e7603613..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/scanner/zap_scanner_active.py +++ /dev/null @@ -1,320 +0,0 @@ -#!/usr/bin/env python - -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# -*- coding: utf-8 -*- - -import time -import collections -import logging - -from zapv2 import ZAPv2, ascan - -from ..configuration import ZapConfiguration -from . import ZapConfigureScanner -from ..configuration.helpers import ZapConfigurationContextUsers - -# set up logging to file - see previous section for more details -logging.basicConfig( - level=logging.INFO, - format="%(asctime)s %(name)-12s %(levelname)-8s: %(message)s", - datefmt="%Y-%m-%d %H:%M", -) - -logging = logging.getLogger("ZapConfigureActiveScanner") - - -class ZapConfigureActiveScanner(ZapConfigureScanner): - """This class configures a scanner in a running ZAP instance, based on a ZAP Configuration. - - Based on this opensource ZAP Python example: - - https://github.com/zaproxy/zap-api-python/blob/9bab9bf1862df389a32aab15ea4a910551ba5bfc/src/examples/zap_example_api_script.py - """ - - def __init__(self, zap: ZAPv2, config: ZapConfiguration): - """Initial constructor used for this class - - Parameters - ---------- - zap : ZAPv2 - The running ZAP instance to configure. - config : ZapConfiguration - The configuration object containing all ZAP configs (based on the class ZapConfiguration). - """ - - super().__init__(zap, config) - - def start_scanner(self, url: str, scanner_config: collections.OrderedDict) -> int: - """Starts a ZAP ActiveScan with the given name for the scanners configuration, based on the given configuration and ZAP instance. - - Parameters - ---------- - scanner_config: collections.OrderedDict - The scanner configuration based on a ZapConfiguration. - """ - scannerId = -1 - - # Clear all excisting/previous scanner data - logging.debug("Cleaning all existing ActiveScans") - self.get_zap.ascan.remove_all_scans() - - if scanner_config is not None: - scannerId = self.__start_scanner_with_config( - url=url, scanner_config=scanner_config - ) - else: - logging.info( - "Starting ActiveScan(url='%s') without any additional scanner configuration!", - url, - ) - scannerId = self.get_zap.ascan.scan(url=url, contextid=None) - - logging.info("ActiveScan returned: %s", scannerId) - - if not str(scannerId).isdigit() or int(scannerId) < 0: - logging.error("ActiveScan couldn't be started due to errors: %s", scannerId) - raise RuntimeError( - "ActiveScan couldn't be started due to errors: %s", scannerId - ) - else: - logging.info("ActiveScan successfully started with id: %s", scannerId) - # Give the scanner a chance to start - time.sleep(5) - - self.wait_until_finished(int(scannerId)) - - return scannerId - - def __start_scanner_with_config( - self, url: str, scanner_config: collections.OrderedDict - ) -> int: - """Starts a ZAP ActiveScan with the given name for the scanners configuration, based on the given configuration and ZAP instance. - - Parameters - ---------- - scanner_config: collections.OrderedDict - The scanner configuration based on a ZapConfiguration. - """ - scanner_id = -1 - user_id = None - context_id = None - target = None - - if self._is_not_empty("url", scanner_config): - target = str(scanner_config["url"]) - else: - logging.warning( - "The active scanner configuration section has no specific 'url' target defined, trying to use scanType target instead with url: '%s'", - url, - ) - target = url - - # "Context" is an optional config for Scanner - if self._is_not_empty("context", scanner_config): - - scanner_context_config = self.get_config.get_active_context_config - context_id = int(scanner_context_config["id"]) - - # "User" is an optional config for Scanner in addition to the context - if self._is_not_empty("user", scanner_config): - user_name = str(scanner_config["user"]) - # search for the configured user by its user name in the active context - user_id = ZapConfigurationContextUsers.get_context_user_by_name( - scanner_context_config, user_name - )["id"] - - # Configure HTTP ActiveScan - logging.debug("Trying to configure ActiveScan with %s", scanner_config) - self.__configure_scanner(self.get_zap.ascan, scanner_config) - - policy = scanner_config["defaultPolicy"] - if self._is_not_empty_string("policy", scanner_config): - policy = scanner_config["policy"] - - # ActiveScan with user - if ( - (context_id is not None) - and int(context_id) >= 0 - and (user_id is not None) - and int(user_id) >= 0 - ): - logging.info( - "Starting ActiveScan(url=%s, contextid=%s, userid=%s, scanpolicyname=%s)", - target, - context_id, - user_id, - policy, - ) - scanner_id = self.get_zap.ascan.scan_as_user( - url=target, contextid=context_id, userid=user_id, scanpolicyname=policy - ) - else: - logging.info( - "Starting ActiveScan(url=%s, contextid=%s, scanpolicyname=%s)", - target, - context_id, - policy, - ) - scanner_id = self.get_zap.ascan.scan( - url=target, contextid=context_id, scanpolicyname=policy - ) - - return scanner_id - - def __configure_scanner( - self, zap_scanner: ascan, scanner_config: collections.OrderedDict - ): - """Starts a ZAP ActiveScan with the given name for the scanners configuration, based on the given configuration and ZAP instance. - - Parameters - ---------- - zap_scanner: ascan - A reference to the active ZAP scanner (of the running ZAP instance) to configure. - scanner_config: collections.OrderedDict - The scanner configuration based on ZapConfiguration. - """ - - logging.debug("Trying to configure the ActiveScan") - self.configure_scripts(config=scanner_config) - - if self._is_not_empty_integer("maxRuleDurationInMins", scanner_config): - self.check_zap_result( - result=zap_scanner.set_option_max_rule_duration_in_mins( - integer=str(scanner_config["maxRuleDurationInMins"]) - ), - method_name="set_option_max_rule_duration_in_mins", - ) - if self._is_not_empty_integer("maxScanDurationInMins", scanner_config): - self.check_zap_result( - result=zap_scanner.set_option_max_scan_duration_in_mins( - integer=str(scanner_config["maxScanDurationInMins"]) - ), - method_name="set_option_max_scan_duration_in_mins", - ) - if self._is_not_empty_integer("threadPerHost", scanner_config): - self.check_zap_result( - result=zap_scanner.set_option_thread_per_host( - integer=str(scanner_config["threadPerHost"]) - ), - method_name="set_option_thread_per_host", - ) - if self._is_not_empty_integer("delayInMs", scanner_config): - self.check_zap_result( - result=zap_scanner.set_option_delay_in_ms( - integer=str(scanner_config["delayInMs"]) - ), - method_name="set_option_delay_in_ms", - ) - - if self._is_not_empty_bool("addQueryParam", scanner_config): - self.check_zap_result( - result=zap_scanner.set_option_add_query_param( - boolean=str(scanner_config["addQueryParam"]) - ), - method_name="set_option_add_query_param", - ) - if self._is_not_empty_bool("handleAntiCSRFTokens", scanner_config): - self.check_zap_result( - result=zap_scanner.set_option_handle_anti_csrf_tokens( - boolean=str(scanner_config["handleAntiCSRFTokens"]) - ), - method_name="set_option_handle_anti_csrf_tokens", - ) - if self._is_not_empty_bool("injectPluginIdInHeader", scanner_config): - self.check_zap_result( - result=zap_scanner.set_option_inject_plugin_id_in_header( - boolean=str(scanner_config["injectPluginIdInHeader"]) - ), - method_name="set_option_inject_plugin_id_in_header", - ) - if self._is_not_empty_bool("scanHeadersAllRequests", scanner_config): - self.check_zap_result( - result=zap_scanner.set_option_scan_headers_all_requests( - boolean=str(scanner_config["scanHeadersAllRequests"]) - ), - method_name="set_option_scan_headers_all_requests", - ) - if self._is_not_empty_string("defaultPolicy", scanner_config): - self.check_zap_result( - result=zap_scanner.set_option_default_policy( - string=str(scanner_config["defaultPolicy"]) - ), - method_name="set_option_default_policy", - ) - else: - # Ensure a default value even if nothing is defined - scanner_config["defaultPolicy"] = "Default Policy" - - def wait_until_finished(self, scanner_id: int): - """Wait until the running ZAP ActiveScan finished and log results. - - Parameters - ---------- - scanner_id: int - The id of the running scanner instance. - """ - - if scanner_id >= 0: - while int(self.get_zap.ascan.status(scanner_id)) < 100: - logging.info( - "ActiveScan(%s) progress: %s", - scanner_id, - self.get_zap.ascan.status(scanner_id), - ) - time.sleep(1) - - logging.info("ActiveScan(%s) completed", scanner_id) - self.__log_statistics(scanner_id) - - def __log_statistics(self, scanner_id: int): - # Log a count of the number of urls: - num_urls = len(self.get_zap.core.urls()) - if num_urls == 0: - logging.warning( - "No URLs found - is the target URL accessible? Local services may not be accessible from the Docker container" - ) - else: - logging.info( - "ActiveScan(%s) scanned total: %s site URLs", scanner_id, str(num_urls) - ) - - list_of_scans = self.get_zap.ascan.scans - logging.info("ActiveScan(%s) statistics: %s", scanner_id, list_of_scans) - - def get_alerts(self, baseurl, ignore_scan_rules, out_of_scope_dict): - # Retrieve the alerts using paging in case there are lots of them - start = 0 - count_per_page = 5000 - alert_dict = {} - alert_count = 0 - alerts_result = self.get_zap.core.alerts( - baseurl=baseurl, start=start, count=count_per_page - ) - while len(alerts_result) > 0: - logging.info( - "Reading #%s alerts from page: %s", str(count_per_page), str(start) - ) - alert_count += len(alerts_result) - for alert in alerts_result: - plugin_id = str(alert.get("pluginId")) - # if plugin_id in ignore_scan_rules: - # continue - # if not is_in_scope(plugin_id, alert.get('url'), out_of_scope_dict): - # continue - # if alert.get('risk') == 'Informational': - # # Ignore all info alerts - some of them may have been downgraded by security annotations - # continue - if plugin_id not in alert_dict: - alert_dict[plugin_id] = [] - alert_dict[plugin_id].append(alert) - start += count_per_page - alerts_result = self.get_zap.core.alerts(start=start, count=count_per_page) - - logging.info( - "Total number of alert categories found: #%s with in total #%s alerts.", - str(alert_count), - alert_count, - ) - return alert_dict diff --git a/scanners/zap-advanced/scanner/zapclient/settings/__init__.py b/scanners/zap-advanced/scanner/zapclient/settings/__init__.py deleted file mode 100644 index fe449edc4d..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/settings/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -""" -zapclient -A Python package containing secureCodeBox specific ZAPv2 Client extensions to configure global ZAP settings. -""" - -__all__ = ["zap_global"] - -from .zap_settings import ZapConfigureSettings diff --git a/scanners/zap-advanced/scanner/zapclient/settings/zap_settings.py b/scanners/zap-advanced/scanner/zapclient/settings/zap_settings.py deleted file mode 100644 index 258e846066..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/settings/zap_settings.py +++ /dev/null @@ -1,272 +0,0 @@ -#!/usr/bin/env python - -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# -*- coding: utf-8 -*- - -import time -import collections -import logging - -from zapv2 import ZAPv2 - -from .. import ZapClient -from ..configuration import ZapConfiguration - -# set up logging to file - see previous section for more details -logging.basicConfig( - level=logging.INFO, - format="%(asctime)s %(name)-12s %(levelname)-8s: %(message)s", - datefmt="%Y-%m-%d %H:%M", -) - -logging = logging.getLogger("ZapConfigureSettings") - - -class ZapConfigureSettings(ZapClient): - """This class configures a running ZAP instance, based on a ZAP Global Configuration - - Based on this opensource ZAP Python example: - - https://github.com/zaproxy/zap-api-python/blob/9bab9bf1862df389a32aab15ea4a910551ba5bfc/src/examples/zap_example_api_script.py - """ - - def __init__(self, zap: ZAPv2, config: ZapConfiguration): - """Initial constructor used for this class - - Parameters - ---------- - zap : ZAPv2 - The running ZAP instance to configure. - config : ZapConfiguration - The configuration object containing all ZAP configs (based on the class ZapConfiguration). - """ - - super().__init__(zap, config) - - self.__global_config = None - - if self.get_config.has_global_configurations(): - self.__global_config = self.get_config.get_global - logging.debug( - "Found the following ZAP Global config: %s", self.get_global_config - ) - else: - logging.debug("No ZAP settings defined!") - - @property - def get_global_config(self) -> collections.OrderedDict: - """Returns the global config of the currently running ZAP instance.""" - return self.__global_config - - def configure(self): - """Configure a new active ZAP Session with all Settings, based on the configuration settings.""" - - if self.get_config.has_global_configurations(): - self.__create_session() - self.__configure_global_settings() - self.__configure_exclude_paths() - self.__configure_proxy() - self.configure_scripts(config=self.get_global_config) - - def __create_session(self): - """Private method to configure a new active ZAP Session, based on the configuration settings.""" - - session_name = "secureCodeBox" - - if self._is_not_empty_string("sessionName", self.get_global_config): - session_name = self.get_global_config["sessionName"] - - # Start the ZAP session - logging.info("Creating a new ZAP session with the name: %s", session_name) - self.check_zap_result( - result=self.get_zap.core.new_session(name=session_name, overwrite=True), - method_name="new_session", - ) - - # Wait for ZAP to update the internal caches - time.sleep(5) - - def __configure_global_settings(self): - """Configures some global ZAP Configurations, based on the running ZAP instance and given config YAML""" - - logging.debug("Trying to configure the ZAP Global Settings") - - if self._is_not_empty_integer("timeoutInSeconds", self.get_global_config): - self.check_zap_result( - result=self.get_zap.core.set_option_timeout_in_secs( - integer=str(self.get_global_config["timeoutInSeconds"]) - ), - method_name="set_option_timeout_in_secs", - ) - if self._is_not_empty_string("defaultUserAgent", self.get_global_config): - self.check_zap_result( - result=self.get_zap.core.set_option_default_user_agent( - string=str(self.get_global_config["defaultUserAgent"]) - ), - method_name="set_option_default_user_agent", - ) - if self._is_not_empty_string("mode", self.get_global_config): - self.check_zap_result( - result=self.get_zap.core.set_mode( - mode=str(self.get_global_config["mode"]) - ), - method_name="set_mode", - ) - - def __configure_exclude_paths(self): - """Private method to configure the ZAP Global 'Proxy Settings' based on a given ZAP config.""" - - if "globalExcludePaths" in self.get_global_config: - for regex in self.get_global_config["globalExcludePaths"]: - logging.debug("Excluding regex '%s' from global proxy setting", regex) - self.check_zap_result( - result=self.get_zap.core.exclude_from_proxy(regex=regex), - method_name="exclude_from_proxy", - ) - else: - logging.debug( - "No global exclude paths configuration defined (global.globalExcludePaths: )." - ) - - def __configure_proxy(self): - """Private method to configure the ZAP Global 'Proxy Settings' based on a given ZAP config.""" - - if self._is_not_empty("proxy", self.get_global_config): - proxy_config = self.get_global_config["proxy"] - - if self._is_not_empty_bool("enabled", proxy_config): - - self.check_zap_result( - result=self.get_zap.core.set_option_use_proxy_chain( - boolean=str(proxy_config["enabled"]).lower() - ), - method_name="set_option_use_proxy_chain", - ) - self.__configure_proxy_settings(proxy_config) - self.__configure_proxy_authentication(proxy_config) - self.__configure_socks(proxy_config) - else: - logging.debug( - "Proxy configuration is not enabled (global.proxy.enabled: true)" - ) - else: - logging.debug("No proxy configuration defined (global.proxy: ...).") - - def __configure_proxy_settings(self, proxy_config: collections.OrderedDict): - """Private method to configure all proxy specific setings, based on the configuration settings.""" - - if self._is_not_empty_string("address", proxy_config): - self.check_zap_result( - result=self.get_zap.core.set_option_proxy_chain_name( - string=str(proxy_config["address"]) - ), - method_name="set_option_proxy_chain_name", - ) - if self._is_not_empty_integer("port", proxy_config): - self.check_zap_result( - result=self.get_zap.core.set_option_proxy_chain_port( - integer=str(proxy_config["port"]) - ), - method_name="set_option_proxy_chain_port", - ) - if "skipProxyAddresses" in proxy_config and ( - proxy_config["skipProxyAddresses"] is not None - ): - logging.debug( - "Disabling all possible pre existing proxy excluded domains before adding new ones." - ) - self.check_zap_result( - result=self.get_zap.core.disable_all_proxy_chain_excluded_domains(), - method_name="add_proxy_chain_excluded_domain", - ) - for address in proxy_config["skipProxyAddresses"]: - logging.debug( - "Excluding (skip) address '%s' from global proxy setting", address - ) - self.check_zap_result( - result=self.get_zap.core.add_proxy_chain_excluded_domain( - value=address, isregex=True, isenabled=True - ), - method_name="add_proxy_chain_excluded_domain", - ) - - def __configure_proxy_authentication(self, proxy_config: collections.OrderedDict): - """Private method to configure the proxy authenication, based on the configuration settings.""" - - # Configure ZAP outgoing proxy server authentication - if "authentication" in proxy_config and ( - proxy_config["authentication"] is not None - ): - proxy_authentication_config = proxy_config["authentication"] - - if ( - "enabled" in proxy_authentication_config - and proxy_authentication_config["enabled"] - ): - self.check_zap_result( - result=self.get_zap.core.set_option_use_proxy_chain_auth( - boolean=str(proxy_authentication_config["enabled"]).lower() - ), - method_name="set_option_use_proxy_chain_auth", - ) - self.__configure_proxy_authentication_settings( - proxy_authentication_config - ) - else: - logging.debug( - "Proxy Authentication configuration is not enabled (global.proxy.authentication.enabled: true)" - ) - else: - logging.debug( - "No authentication configuration defined for proxy (global.proxy.authentication: )." - ) - - def __configure_proxy_authentication_settings( - self, proxy_authentication_config: collections.OrderedDict - ): - """Private method to configure the proxy authenication specific settings, based on the configuration settings.""" - - if self._is_not_empty_string("username", proxy_authentication_config): - self.check_zap_result( - result=self.get_zap.core.set_option_proxy_chain_user_name( - string=str(proxy_authentication_config["username"]) - ), - method_name="set_option_proxy_chain_user_name", - ) - if self._is_not_empty_string("password", proxy_authentication_config): - self.check_zap_result( - result=self.get_zap.core.set_option_proxy_chain_password( - string=str(proxy_authentication_config["password"]) - ), - method_name="set_option_proxy_chain_password", - ) - if self._is_not_empty_string("realm", proxy_authentication_config): - self.check_zap_result( - result=self.get_zap.core.set_option_proxy_chain_realm( - string=str(proxy_authentication_config["realm"]) - ), - method_name="set_option_proxy_chain_realm", - ) - - def __configure_socks(self, proxy_config: collections.OrderedDict): - """Private method to configure the proxy socks settings, based on the configuration settings.""" - - # Configure ZAP outgoing proxy server authentication - if self._is_not_empty("socks", proxy_config): - socks_config = proxy_config["socks"] - - if self._is_not_empty_bool("enabled", socks_config): - self.check_zap_result( - result=self.get_zap.core.set_option_use_socks_proxy( - boolean=str(socks_config["enabled"]).lower() - ), - method_name="set_option_use_socks_proxy", - ) - else: - logging.debug( - "Proxy Socks configuration is not enabled (global.proxy.socks.enabled: true)" - ) - else: - logging.debug("No proxy sock configuration found (global.proxy.socks: ).") diff --git a/scanners/zap-advanced/scanner/zapclient/spider/__init__.py b/scanners/zap-advanced/scanner/zapclient/spider/__init__.py deleted file mode 100644 index 5046f548d5..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/spider/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -""" -zapclient -A Python package containing secureCodeBox specific ZAPv2 Client extensions to automate ZAP spider. -""" - -__all__ = ["zap_abstract_spider", "zap_spider_http", "zap_spider_ajax"] - -from .zap_abstract_spider import ZapConfigureSpider -from .zap_spider_ajax import ZapConfigureSpiderAjax -from .zap_spider_http import ZapConfigureSpiderHttp diff --git a/scanners/zap-advanced/scanner/zapclient/spider/zap_abstract_spider.py b/scanners/zap-advanced/scanner/zapclient/spider/zap_abstract_spider.py deleted file mode 100644 index 1bd56998b0..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/spider/zap_abstract_spider.py +++ /dev/null @@ -1,180 +0,0 @@ -#!/usr/bin/env python - -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# -*- coding: utf-8 -*- - -import collections -import logging -import time - -from abc import abstractmethod -from zapv2 import ZAPv2, spider - -from .. import ZapClient -from ..configuration import ZapConfiguration - -# set up logging to file - see previous section for more details -logging.basicConfig( - level=logging.INFO, - format="%(asctime)s %(name)-12s %(levelname)-8s: %(message)s", - datefmt="%Y-%m-%d %H:%M", -) - -logging = logging.getLogger("ZapConfigureSpider") - - -class ZapConfigureSpider(ZapClient): - """This abstract class configures a ZAP Spider in a running ZAP instance, based on a ZAP Configuration. - - Based on this opensource ZAP Python example: - - https://github.com/zaproxy/zap-api-python/blob/9bab9bf1862df389a32aab15ea4a910551ba5bfc/src/examples/zap_example_api_script.py - """ - - def __init__(self, zap: ZAPv2, config: ZapConfiguration): - """Initial constructor used for this class - - Parameters - ---------- - zap : ZAPv2 - The running ZAP instance to configure. - config : ZapConfiguration - The configuration object containing all ZAP configs (based on the class ZapConfiguration). - """ - super().__init__(zap, config) - - self.__spider_config = None - self.__ajax = False - - @property - def get_spider_config(self) -> collections.OrderedDict: - """Returns the spider config of the currently running ZAP instance.""" - return self.__spider_config - - def is_ajax_spider_enabled(self) -> bool: - # "Context" is an optional config for spider - if ( - self.get_spider_config is not None - and "ajax" in self.get_spider_config - and self.get_spider_config["ajax"] - ): - self.__ajax = bool(self.get_spider_config["ajax"]) - else: - logging.debug( - "No Ajax configuration 'ajax: true' found in spider configuration: %s", - self.get_spider_config, - ) - - return self.__ajax - - def start_spider_by_url(self, url: str): - """Starts a ZAP Spider for the given url, based on the given configuration and ZAP instance. - - Parameters - ---------- - url: str - The url to spider. - """ - - spider_context = self.get_config.get_active_context_config - self.__spider_config = self.get_config.get_active_spider_config - - if self.__spider_config is not None: - # Search for a API configuration referencing the context identified by url - if spider_context is None: - logging.warning( - "No context configuration found for target: '%s'! Starting spider without any related context.", - url, - ) - else: - logging.info( - "Trying to start Spider (Ajax: %s) with target url: '%s'", - str(self.is_ajax_spider_enabled()), - url, - ) - else: - logging.warning( - "There is no spider specific configuration section defined in your configuration YAML to start by url: %s.", - url, - ) - - self.start_spider(url=url, spider_config=self.get_spider_config) - - @abstractmethod - def configure_spider(self, spider_config: collections.OrderedDict): - """Configures a ZAP HTTP Spider with the given spider configuration, based on the running ZAP instance. - - Parameters - ---------- - spider_config: collections.OrderedDict - The spider configuration based on ZapConfiguration. - """ - raise NotImplementedError - - @abstractmethod - def start_spider(self, url: str, spider_config: collections.OrderedDict): - """Starts a ZAP Spider with the given spiders configuration, based on the internal referenced ZAP instance. - - Parameters - ---------- - spider_config: collections.OrderedDict - The spider configuration based on ZapConfiguration. - """ - raise NotImplementedError - - @abstractmethod - def check_if_spider_completed(self): - """Method to ask ZAP Api if the Spider has completed. - - Returns - ------- - true: if spider has completed - false: if spider is still working - """ - raise NotImplementedError - - @abstractmethod - def print_spider_summary(self): - """Method to print out a summary of the spider results""" - raise NotImplementedError - - @abstractmethod - def stop_spider(self): - """Method to stop the spider""" - raise NotImplementedError - - def wait_until_spider_finished(self): - """ - Waits for the ZAP Spider to complete. - - This method also enforces the "maxDuration" limit of the spider, ZAP normally enforces it on its own, - but there are cases where the spider has stalled and ZAP was unable to enforce it on its own. - """ - if ( - self.get_config.get_active_spider_config is not None - and "maxDuration" in self.get_config.get_active_spider_config - ): - # convert to seconds - max_duration = self.get_config.get_active_spider_config["maxDuration"] * 60 - else: - max_duration = None - - wait_time = 0 - # time to wait above the configured max duration, to give ZAP time to enforce the maxDuration itself if possible - tolerance_duration = 60 - - while self.check_if_spider_completed() is not True: - time.sleep(1) - wait_time += 1 - if max_duration is not None and wait_time > ( - max_duration + tolerance_duration - ): - logging.info( - "Spider has run over its configured maxDuration. Stopping Spider." - ) - self.stop_spider() - break - - self.print_spider_summary() diff --git a/scanners/zap-advanced/scanner/zapclient/spider/zap_spider_ajax.py b/scanners/zap-advanced/scanner/zapclient/spider/zap_spider_ajax.py deleted file mode 100644 index 2bd9ae399b..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/spider/zap_spider_ajax.py +++ /dev/null @@ -1,247 +0,0 @@ -#!/usr/bin/env python - -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# -*- coding: utf-8 -*- - -import time -import collections -import logging - -from zapv2 import ZAPv2, ajaxSpider - -from ..configuration.helpers import ZapConfigurationContextUsers -from ..configuration import ZapConfiguration -from . import ZapConfigureSpider - -# set up logging to file - see previous section for more details -logging.basicConfig( - level=logging.INFO, - format="%(asctime)s %(name)-12s %(levelname)-8s: %(message)s", - datefmt="%Y-%m-%d %H:%M", -) - -logging = logging.getLogger("ZapConfigureSpiderAjax") - - -class ZapConfigureSpiderAjax(ZapConfigureSpider): - """This class configures a ZAP Ajax Spider in a running ZAP instance, based on a ZAP Configuration. - - Based on this opensource ZAP Python example: - - https://github.com/zaproxy/zap-api-python/blob/9bab9bf1862df389a32aab15ea4a910551ba5bfc/src/examples/zap_example_api_script.py - """ - - def __init__(self, zap: ZAPv2, config: ZapConfiguration): - """Initial constructor used for this class - - Parameters - ---------- - zap : ZAPv2 - The running ZAP instance to configure. - config : ZapConfiguration - The configuration object containing all ZAP configs (based on the class ZapConfiguration). - """ - super().__init__(zap, config) - - @property - def get_zap_spider(self) -> ajaxSpider: - """Returns the ajax spider of the currently running ZAP instance.""" - return self.get_zap.ajaxSpider - - def start_spider(self, url: str, spider_config: collections.OrderedDict): - """Starts a ZAP Spider with the given spiders configuration, based on the internal referenced ZAP instance. - - Parameters - ---------- - spider_config: collections.OrderedDict - The spider configuration based on ZapConfiguration. - """ - user_name = None - context_name = None - target = "" - - # Clear all existing/previous spider data - self.get_zap.spider.remove_all_scans() - - # Open first URL before the spider start's to crawl - self.get_zap.core.access_url(url) - - if spider_config is not None: - - if "url" in spider_config: - target = str(spider_config["url"]) - else: - logging.warning( - "The spider configuration section has no specific 'url' target defined, trying to use scanType target instead with url: '%s'", - url, - ) - target = url - - # Configure Ajax Spider - self.configure_spider(spider_config) - - # "Context" is an optional config for spider - if "context" in spider_config: - context_name = str(spider_config["context"]) - spider_context_config = self.get_config.get_active_context_config - - # "User" is an optional config for spider in addition to the context - if "user" in spider_config: - # this lookup is required as name != username and the ajax spider needs the username - user_name = ZapConfigurationContextUsers.get_context_user_by_name( - spider_context_config, str(spider_config["user"]) - )["username"] - else: - logging.warning( - "No context 'context: XYZ' referenced within the spider config. This is ok but maybe not intended." - ) - - if ( - (context_name is not None) - and len(context_name) >= 0 - and (user_name is not None) - and len(user_name) >= 0 - ): - logging.info( - "Starting Ajax Spider(target=%s) with Context(%s) and User(%s)", - target, - context_name, - user_name, - ) - result = self.get_zap_spider.scan_as_user( - url=target, contextname=context_name, username=user_name - ) - else: - logging.debug( - "Starting Ajax Spider(target=%s) with Context(%s)", - target, - context_name, - ) - result = self.get_zap_spider.scan(url=target, contextname=context_name) - else: - logging.info( - "Starting Ajax Spider(target=%s) without any additinal Config!", url - ) - result = self.get_zap_spider.scan(url=url, contextname=None) - - if "OK" != str(result): - logging.error("Spider couldn't be started due to errors: %s", result) - raise RuntimeError("Spider couldn't be started due to errors: %s", result) - else: - # due to the fact that there can be only one ajax spider at once the id is "pinned" to 1 - logging.info("Ajax Spider successfully started!") - # Give the scanner a chance to start - time.sleep(5) - - self.wait_until_spider_finished() - - def configure_spider(self, spider_config: collections.OrderedDict): - """Configures a ZAP Ajax Spider with the given spider configuration, based on the running ZAP instance. - - Parameters - ---------- - spider_config: collections.OrderedDict - The spider configuration based on ZapConfiguration. - """ - - logging.debug("Trying to configure the AjaxSpider") - self.configure_scripts(config=spider_config) - - # Configure Spider (ajax or http) - - if self._is_not_empty_integer("maxDuration", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_max_duration( - integer=str(spider_config["maxDuration"]) - ), - method_name="set_option_max_duration", - ) - if self._is_not_empty_integer("maxDepth", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_max_crawl_depth( - integer=str(spider_config["maxDepth"]) - ), - method_name="set_option_max_crawl_depth", - ) - if self._is_not_empty_integer("maxStates", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_max_crawl_states( - integer=str(spider_config["maxStates"]) - ), - method_name="set_option_max_crawl_states", - ) - if self._is_not_empty_string("browserId", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_browser_id( - string=str(spider_config["browserId"]) - ), - method_name="set_option_browser_id", - ) - if self._is_not_empty_integer("browserCount", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_number_of_browsers( - integer=str(spider_config["browserCount"]) - ), - method_name="set_option_number_of_browsers", - ) - if self._is_not_empty_integer("randomInputs", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_random_inputs( - boolean=str(spider_config["randomInputs"]) - ), - method_name="set_option_random_inputs", - ) - - if self._is_not_empty_integer("failIfFoundUrlsLessThan", spider_config): - self.failIfFoundUrlsLessThan = spider_config["failIfFoundUrlsLessThan"] - else: - self.failIfFoundUrlsLessThan = 0 # Default value - - if self._is_not_empty_integer("warnIfFoundUrlsLessThan", spider_config): - self.warnIfFoundUrlsLessThan = spider_config["warnIfFoundUrlsLessThan"] - else: - self.warnIfFoundUrlsLessThan = 0 # Default value - - def check_if_spider_completed(self): - finished = self.get_zap_spider.status != "running" - logging.info( - "Ajax Spider running, found urls: %s", self.get_zap_spider.number_of_results - ) - return finished - - def print_spider_summary(self): - """Method to print out a summary of the spider results""" - - logging.info("Ajax Spider complete") - - # Print out a count of the number of urls - num_urls = len(self.get_zap.core.urls()) - if num_urls == 0: - logging.error( - "No URLs found - is the target URL accessible? Local services may not be accessible from the Docker container" - ) - raise RuntimeError( - "No URLs found by ZAP Spider :-( - is the target URL accessible? Local services may not be accessible from the Docker container" - ) - elif num_urls < self.failIfFoundUrlsLessThan: - logging.error( - "Found URLs are less than {failIfFoundUrlsLessThan}, failing process." - ) - raise RuntimeError( - "Found URLs are less than {failIfFoundUrlsLessThan} by ZAP Spider, failing process." - ) - - elif num_urls < self.warnIfFoundUrlsLessThan: - logging.warning( - "Found URLs are less than {warnIfFoundUrlsLessThan}, continuing process." - ) - - else: - logging.info("Ajax Spider found total: %s URLs", str(num_urls)) - for url in self.get_zap_spider.results(): - logging.debug("URL: %s", url["requestHeader"]) - - def stop_spider(self): - self.get_zap_spider.stop() diff --git a/scanners/zap-advanced/scanner/zapclient/spider/zap_spider_http.py b/scanners/zap-advanced/scanner/zapclient/spider/zap_spider_http.py deleted file mode 100644 index 631889f9db..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/spider/zap_spider_http.py +++ /dev/null @@ -1,354 +0,0 @@ -#!/usr/bin/env python - -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# -*- coding: utf-8 -*- - -import time -import collections -import logging - -from zapv2 import ZAPv2, spider - -from ..configuration import ZapConfiguration -from . import ZapConfigureSpider - -# set up logging to file - see previous section for more details -from ..configuration.helpers import ZapConfigurationContextUsers - -logging.basicConfig( - level=logging.INFO, - format="%(asctime)s %(name)-12s %(levelname)-8s: %(message)s", - datefmt="%Y-%m-%d %H:%M", -) - -logging = logging.getLogger("ZapConfigureSpiderHttp") - - -class ZapConfigureSpiderHttp(ZapConfigureSpider): - """This class configures a ZAP HTTP Spider in a running ZAP instance, based on a ZAP Configuration. - - Based on this opensource ZAP Python example: - - https://github.com/zaproxy/zap-api-python/blob/9bab9bf1862df389a32aab15ea4a910551ba5bfc/src/examples/zap_example_api_script.py - """ - - def __init__(self, zap: ZAPv2, config: ZapConfiguration): - """Initial constructor used for this class - - Parameters - ---------- - zap : ZAPv2 - The running ZAP instance to configure. - config : ZapConfiguration - The configuration object containing all ZAP configs (based on the class ZapConfiguration). - """ - self.__spider_id = -1 - - super().__init__(zap, config) - - @property - def get_zap_spider(self) -> spider: - """Returns the spider of the currently running ZAP instance.""" - return self.get_zap.spider - - @property - def get_spider_id(self) -> int: - """Returns the spider id of the currently running ZAP instance.""" - return self.__spider_id - - def has_spider_id(self) -> bool: - """Returns a spider is currently running in the ZAP instance.""" - return self.__spider_id > 0 - - def start_spider(self, url: str, spider_config: collections.OrderedDict): - """Starts a ZAP Spider with the given spiders configuration, based on the internal referenced ZAP instance. - - Parameters - ---------- - spider_config: collections.OrderedDict - The spider configuration based on ZapConfiguration. - """ - user_id = None - context_id = None - context_name = None - target = "" - - # Clear all existing/previous spider data - logging.debug("Removing all pre existing spider scans.") - self.get_zap.spider.remove_all_scans() - - # Open first URL before the spider start's to crawl - self.get_zap.core.access_url(url) - - if spider_config is not None: - - if "url" in spider_config: - target = str(spider_config["url"]) - else: - logging.warning( - "The spider configuration section has no specific 'url' target defined, trying to use scanType target instead with url: '%s'", - url, - ) - target = url - - # Configure Spider Options if there are any - self.configure_spider(spider_config) - - # "Context" is an optional config for spider - if self._is_not_empty("context", spider_config): - - context_name = str(spider_config["context"]) - spider_context_config = self.get_config.get_active_context_config - context_id = int(spider_context_config["id"]) - - # "User" is an optional config for spider in addition to the context - if self._is_not_empty("user", spider_config): - user_name = str(spider_config["user"]) - # search for the configured user by its user name in the active context - user_id = ZapConfigurationContextUsers.get_context_user_by_name( - spider_context_config, user_name - )["id"] - else: - logging.warning( - "No context 'context: XYZ' referenced within the spider config. This is ok but maybe not intended." - ) - - logging.warning("context_id is currently: %s", context_id) - logging.warning("user_id is currently: %s", user_id) - if ( - (context_id is not None) - and int(context_id) >= 0 - and (user_id is not None) - and int(user_id) >= 0 - ): - logging.info( - "Starting 'traditional' Spider(target=%s) with Context(%s) and User(%s)", - target, - context_id, - user_id, - ) - result = self.get_zap_spider.scan_as_user( - url=target, contextid=context_id, userid=user_id - ) - else: - logging.info( - "Starting 'traditional' Spider(target=%s) with Context(%s)", - target, - context_name, - ) - result = self.get_zap_spider.scan(url=target, contextname=context_name) - else: - logging.info( - "Starting 'traditional' Spider(target=%s) without any additinal configuration!", - url, - ) - result = self.get_zap_spider.scan(url=url, contextname=None) - - # Check if spider is running successfully - if (not str(result).isdigit()) or int(result) < 0: - logging.error("Spider couldn't be started due to errors: %s", result) - raise RuntimeError("Spider couldn't be started due to errors: %s", result) - else: - logging.info("HTTP Spider successfully started with id: %s", result) - self.__spider_id = int(result) - # Give the scanner a chance to start - time.sleep(5) - - self.wait_until_spider_finished() - - def configure_spider(self, spider_config: collections.OrderedDict): - """Configures a ZAP HTTP Spider with the given spider configuration, based on the running ZAP instance. - - Parameters - ---------- - spider_config: collections.OrderedDict - The spider configuration based on ZapConfiguration. - """ - - logging.debug("Trying to configure the Spider") - self.configure_scripts(config=spider_config) - - # Configure Spider (ajax or http) - - if self._is_not_empty_integer("maxDuration", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_max_duration( - integer=str(spider_config["maxDuration"]) - ), - method_name="set_option_max_duration", - ) - if self._is_not_empty_integer("maxDepth", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_max_depth( - integer=str(spider_config["maxDepth"]) - ), - method_name="set_option_max_depth", - ) - if self._is_not_empty_integer("maxChildren", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_max_children( - integer=str(spider_config["maxChildren"]) - ), - method_name="set_option_max_children", - ) - if self._is_not_empty_integer("maxParseSizeBytes", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_max_parse_size_bytes( - integer=str(spider_config["maxParseSizeBytes"]) - ), - method_name="set_option_max_parse_size_bytes", - ) - if self._is_not_empty_bool("acceptCookies", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_accept_cookies( - boolean=str(spider_config["acceptCookies"]) - ), - method_name="set_option_accept_cookies", - ) - if self._is_not_empty_bool("handleODataParametersVisited", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_handle_o_data_parameters_visited( - boolean=str(spider_config["handleODataParametersVisited"]) - ), - method_name="set_option_handle_o_data_parameters_visited", - ) - if self._is_not_empty_bool("handleParameters", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_handle_parameters( - string=str(spider_config["handleParameters"]) - ), - method_name="set_option_handle_parameters", - ) - - if self._is_not_empty_bool("parseComments", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_parse_comments( - boolean=str(spider_config["parseComments"]) - ), - method_name="set_option_parse_comments", - ) - if self._is_not_empty_bool("parseGit", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_parse_git( - boolean=str(spider_config["parseGit"]) - ), - method_name="set_option_parse_git", - ) - if self._is_not_empty_bool("parseRobotsTxt", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_parse_robots_txt( - boolean=str(spider_config["parseRobotsTxt"]) - ), - method_name="set_option_parse_robots_txt", - ) - if self._is_not_empty_bool("parseSitemapXml", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_parse_sitemap_xml( - boolean=str(spider_config["parseSitemapXml"]) - ), - method_name="set_option_parse_sitemap_xml", - ) - if self._is_not_empty_bool("parseSVNEntries", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_parse_svn_entries( - boolean=str(spider_config["parseSVNEntries"]) - ), - method_name="set_option_parse_svn_entries", - ) - if self._is_not_empty_bool("postForm", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_post_form( - boolean=str(spider_config["postForm"]) - ), - method_name="set_option_post_form", - ) - if self._is_not_empty_bool("processForm", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_process_form( - boolean=str(spider_config["processForm"]) - ), - method_name="set_option_process_form", - ) - - if self._is_not_empty_integer("requestWaitTime", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_request_wait_time( - integer=str(spider_config["requestWaitTime"]) - ), - method_name="set_option_request_wait_time", - ) - if self._is_not_empty_bool("sendRefererHeader", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_send_referer_header( - boolean=str(spider_config["sendRefererHeader"]) - ), - method_name="set_option_send_referer_header", - ) - if self._is_not_empty_integer("threadCount", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_thread_count( - integer=str(spider_config["threadCount"]) - ), - method_name="set_option_thread_count", - ) - if self._is_not_empty_string("userAgent", spider_config): - self.check_zap_result( - result=self.get_zap_spider.set_option_user_agent( - string=str(spider_config["userAgent"]) - ), - method_name="set_option_user_agent", - ) - - if self._is_not_empty_integer("failIfFoundUrlsLessThan", spider_config): - self.failIfFoundUrlsLessThan = spider_config["failIfFoundUrlsLessThan"] - else: - self.failIfFoundUrlsLessThan = 0 # Default value - - if self._is_not_empty_integer("warnIfFoundUrlsLessThan", spider_config): - self.warnIfFoundUrlsLessThan = spider_config["warnIfFoundUrlsLessThan"] - else: - self.warnIfFoundUrlsLessThan = 0 # Default value - - def check_if_spider_completed(self): - progress = int(self.get_zap_spider.status(self.get_spider_id)) - logging.info("HTTP Spider(%d) progress: %d", self.get_spider_id, progress) - return progress >= 100 - - def print_spider_summary(self): - """Method to print out a summary of the spider results""" - logging.info("HTTP Spider(%s) completed", str(self.get_spider_id)) - - num_urls = len(self.get_zap.core.urls()) - if num_urls == 0: - logging.error( - "No URLs found - is the target URL accessible? Local services may not be accessible from the Docker container." - ) - raise RuntimeError( - "No URLs found by ZAP Spider :-( - is the target URL accessible? Local services may not be accessible from the Docker container." - ) - - elif num_urls < self.failIfFoundUrlsLessThan: - logging.error( - "Found URLs are less than {self.failIfFoundUrlsLessThan}, failing process." - ) - raise RuntimeError( - "Found URLs are less than {self.failIfFoundUrlsLessThan} by ZAP Spider, failing process." - ) - - elif num_urls < self.warnIfFoundUrlsLessThan: - logging.warning( - "Found URLs are less than {self.warnIfFoundUrlsLessThan}, continuing process." - ) - else: - for url in self.get_zap_spider.results(scanid=self.get_spider_id): - logging.info("Spidered URL: %s", url) - logging.info( - "Spider(%s) found total: %s URLs", - str(self.get_spider_id), - str(num_urls), - ) - - def stop_spider(self): - self.get_zap_spider.stop() diff --git a/scanners/zap-advanced/scanner/zapclient/zap_abstract_client.py b/scanners/zap-advanced/scanner/zapclient/zap_abstract_client.py deleted file mode 100644 index 38d47e5fa3..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/zap_abstract_client.py +++ /dev/null @@ -1,237 +0,0 @@ -#!/usr/bin/env python - -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# -*- coding: utf-8 -*- - -import collections -import logging - -from abc import ABC, abstractmethod -from zapv2 import ZAPv2 - -from .configuration import ZapConfiguration - -# set up logging to file - see previous section for more details -logging.basicConfig( - level=logging.INFO, - format="%(asctime)s %(name)-12s %(levelname)-8s: %(message)s", - datefmt="%Y-%m-%d %H:%M", -) - -logging = logging.getLogger("ZapClient") - - -class ZapClient(ABC): - """This abstract class configures a ZAP Client using in a running ZAP instance.""" - - def __init__(self, zap: ZAPv2, config: ZapConfiguration): - """Initial constructor used for this class - - Parameters - ---------- - zap : ZAPv2 - The running ZAP instance to configure. - config : ZapConfiguration - The configuration object containing all ZAP configs (based on the class ZapConfiguration). - """ - - self.__zap = zap - self.__config = config - - @property - def get_config(self) -> ZapConfiguration: - """Returns the complete config of the currently running ZAP instance.""" - return self.__config - - @property - def get_zap(self) -> ZAPv2: - """Returns the currently running ZAP instance.""" - return self.__zap - - def check_zap_result( - self, result: str, method_name: str, exception_message=None - ) -> bool: - """Checks the given result for ZAP API Call for errors and logs a warning messages if there are errors returened by ZAP. - - Parameters - ---------- - result: str - The result of a ZAP API Call. - method_name: str - The name of the method used (to call ZAP) used to log a warning, if the given result is not "OK". - exception_message: str - The exception message that must be thrown with an Exception, if the given result is not "OK". - """ - - __result = False - - if "OK" != result: - __result = False - if exception_message is not None: - logging.error(exception_message) - raise Exception(exception_message) - else: - logging.warning( - "Failed to call ZAP Method ['%s'], result is: '%s'", - method_name, - result, - ) - else: - logging.debug( - "Successful called ZAP Method ['%s'], result is: '%s'", - method_name, - result, - ) - __result = True - - return __result - - def configure_scripts(self, config: collections.OrderedDict): - """Private method to configure the script settings, based on the configuration settings.""" - - if self._is_not_empty("scripts", config): - self._log_all_scripts() - for script in config["scripts"]: - logging.debug("Configuring Script: '%s'", script["name"]) - self._configure_load_script(script_config=script, script_type=None) - self._log_all_scripts() - else: - logging.debug("No Scripts found to configure.") - - def _configure_load_script( - self, script_config: collections.OrderedDict, script_type: str - ): - """Protected method to load a new ZAP Script based on a given ZAP config. - - Parameters - ---------- - script_config : collections.OrderedDict - The current 'script' configuration object containing the ZAP script configuration (based on the class ZapConfiguration). - """ - - if self._is_not_empty("name", script_config): - - # Set default to script_type if it is defined - if ( - script_type is not None - and isinstance(script_type, str) - and len(script_type) > 0 - ): - script_config["type"] = script_type - - # Only try to add new scripts if the definition contains all nessesary config options, otherwise try to only activate/deactivate a given script name - if ( - "filePath" in script_config - and "engine" in script_config - and "type" in script_config - ): - # Remove existing Script, if already pre-existing - logging.debug( - "Trying to remove pre-existing Script '%s' at '%s'", - script_config["name"], - script_config["filePath"], - ) - self.get_zap.script.remove(scriptname=script_config["name"]) - - # Add Script again - logging.info( - "Loading new Script '%s' at '%s' with type: '%s' and engine '%s'", - script_config["name"], - script_config["filePath"], - script_config["type"], - script_config["engine"], - ) - self.check_zap_result( - result=self.get_zap.script.load( - scriptname=script_config["name"], - scripttype=script_config["type"], - scriptengine=script_config["engine"], - filename=script_config["filePath"], - scriptdescription=script_config["description"], - ), - method_name="script.load", - exception_message="The script couldn't be loaded due to errors!", - ) - - # Set default to: True - if not self._is_not_empty("enabled", script_config): - script_config["enabled"] = True - - logging.info( - "Activating Script '%s' with 'enabled: %s'", - script_config["name"], - str(script_config["enabled"]).lower(), - ) - if script_config["enabled"]: - self.check_zap_result( - result=self.get_zap.script.enable(scriptname=script_config["name"]), - method_name="script.enable", - ) - else: - self.check_zap_result( - result=self.get_zap.script.disable( - scriptname=script_config["name"] - ), - method_name="script.disable", - ) - else: - logging.warning( - "Important script configs (name, type, filePath, engine) are missing! Ignoring the script configuration. Please check your YAML configuration." - ) - - def _log_all_scripts(self): - """Protected method to log all currently configured ZAP Scripts.""" - - for scripts in self.get_zap.script.list_scripts: - logging.debug(scripts) - - def _is_not_empty(self, item_name: str, config: collections.OrderedDict) -> bool: - """Return True if the item with the name 'item_name' is exisiting and not None, otherwise false.""" - result = False - if ( - config is not None - and item_name in config - and (config[item_name] is not None) - ): - result = True - return result - - def _is_not_empty_integer( - self, item_name: str, config: collections.OrderedDict - ) -> bool: - """Return True if the item with the name 'item_name' is exisiting and a valid integer >= 0, otherwise false.""" - result = False - if ( - self._is_not_empty(item_name, config) - and isinstance(config[item_name], int) - and config[item_name] >= 0 - ): - result = True - return result - - def _is_not_empty_string( - self, item_name: str, config: collections.OrderedDict - ) -> bool: - """Return True if the item with the name 'item_name' is exisiting and a valid string with len() >= 0, otherwise false.""" - result = False - if ( - self._is_not_empty(item_name, config) - and isinstance(config[item_name], str) - and len(config[item_name]) > 0 - ): - result = True - return result - - def _is_not_empty_bool( - self, item_name: str, config: collections.OrderedDict - ) -> bool: - """Return True if the item with the name 'item_name' is exisiting and a valid bool, otherwise false.""" - result = False - if self._is_not_empty(item_name, config) and isinstance( - config[item_name], bool - ): - result = True - return result diff --git a/scanners/zap-advanced/scanner/zapclient/zap_automation.py b/scanners/zap-advanced/scanner/zapclient/zap_automation.py deleted file mode 100644 index a106620320..0000000000 --- a/scanners/zap-advanced/scanner/zapclient/zap_automation.py +++ /dev/null @@ -1,258 +0,0 @@ -#!/usr/bin/env python - -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# -*- coding: utf-8 -*- - -import logging -import time -import errno - -from pathlib import Path -from zapv2 import ZAPv2 - -from .configuration import ZapConfiguration -from .settings import ZapConfigureSettings -from .context import ZapConfigureContext -from .api import ZapConfigureApi -from .spider import ZapConfigureSpider, ZapConfigureSpiderHttp, ZapConfigureSpiderAjax -from .scanner import ZapConfigureActiveScanner - -# set up logging to file - see previous section for more details -logging.basicConfig( - level=logging.INFO, - format="%(asctime)s %(name)-12s %(levelname)-8s: %(message)s", - datefmt="%Y-%m-%d %H:%M", -) - -logging = logging.getLogger("ZapClient") - - -class ZapAutomation: - """This class configures running ZAP instance - - Based on this opensource ZAP Python example: - - https://github.com/zaproxy/zap-api-python/blob/9bab9bf1862df389a32aab15ea4a910551ba5bfc/src/examples/zap_example_api_script.py - """ - - def __init__( - self, zap: ZAPv2, config_dir: str, target: str, forced_context: str = None - ): - """Initial constructor used for this class - - Parameters - ---------- - zap : ZAPv2 - The running ZAP instance to configure. - config_dir : ZapConfiguration - The configuration object containing all ZAP configs (based on the class ZapConfiguration). - """ - - self.__zap = zap - self.__config_dir = config_dir - - self.__config = ZapConfiguration( - self.__config_dir, target, forced_context=forced_context - ) - - self.__zap_scanner = None - - @property - def get_configuration(self) -> ZapConfiguration: - return self.__config - - @property - def get_zap_scanner(self) -> ZapConfigureActiveScanner: - return self.__zap_scanner - - def scan_target(self, target: str): - # Wait at least 3 minutes for ZAP to start - self.wait_for_zap_start(3 * 60) - - logging.info("Configuring ZAP Global") - if self.get_configuration.has_global_configurations: - # Starting to configure the ZAP Instance based on the given Configuration - zap_settings = ZapConfigureSettings(self.__zap, self.__config) - zap_settings.configure() - else: - logging.info("No ZAP global settings specific YAML configuration found.") - - self.zap_tune(target) - # self.zap_access_target(target) - - logging.info("Configuring ZAP Context") - # Starting to configure the ZAP Instance based on the given Configuration - if self.get_configuration.get_active_context_config is not None: - zap_context = ZapConfigureContext(self.__zap, self.__config) - zap_context.configure_contexts() - else: - logging.info("No ZAP context specific YAML configuration found.") - - self.__start_api_import(target) - self.__start_spider(target) - self.__start_scanner(target) - - def __start_api_import(self, target: str): - logging.info("Configuring API Import") - # Starting to configure the ZAP Instance based on the given Configuration - if self.get_configuration.get_active_api_config is not None: - zap_api = ZapConfigureApi(self.__zap, self.__config) - zap_api.start_api_import( - target, - self.get_configuration.get_active_context_config, - self.get_configuration.get_active_api_config, - ) - - # Wait for ZAP to update the internal caches - time.sleep(5) - else: - logging.info("No ZAP API specific YAML configuration found.") - - def __start_spider(self, target: str): - logging.info("Starting ZAP Spider with target %s", target) - # if a ZAP Configuration is defined start to configure the running ZAP instance (`zap`) - if self.get_configuration.get_active_spider_config is not None: - # Starting to configure the ZAP Spider Instance based on the given Configuration - zap_spider = ZapConfigureSpiderHttp(zap=self.__zap, config=self.__config) - zap_spider.start_spider_by_url(target) - - # Wait for ZAP to update the internal caches - time.sleep(5) - - # Additionally start the ZAP Ajax Spider if enabled - if zap_spider.is_ajax_spider_enabled(): - zap_spider = ZapConfigureSpiderAjax( - zap=self.__zap, config=self.__config - ) - zap_spider.start_spider_by_url(target) - - # Wait for ZAP to update the internal caches - time.sleep(5) - else: - logging.info("No ZAP AjaxSpider specific YAML configuration found.") - - else: - logging.info( - "No ZAP Spider specific YAML configuration found. Stating spider without any configuration." - ) - zap_spider = ZapConfigureSpiderHttp(zap=self.__zap, config=self.__config) - zap_spider.start_spider_by_url(target) - - def __start_scanner(self, target: str): - # if a ZAP Configuration is defined start to configure the running ZAP instance (`zap`) - if self.get_configuration.get_active_scanner_config is not None: - logging.info("Starting ZAP Scanner with target %s", target) - else: - logging.info( - "No ZAP Scanner specific YAML configuration found. Stating Active Scanner without any configuration." - ) - - # Starting to configure the ZAP Instance based on the given Configuration - self.__zap_scanner = ZapConfigureActiveScanner( - zap=self.__zap, config=self.__config - ) - # Search for the corresponding context based on the given targetUrl which should correspond to defined the spider url - self.__zap_scanner.start_scan_by_url(target) - - def get_report_template_for_file_type(self, file_type: str): - if file_type == "XML": - return "traditional-xml" - elif file_type == "XML-plus": - return "traditional-xml-plus" - elif file_type == "JSON": - return "traditional-json" - elif file_type == "JSON-plus": - return "traditional-json-plus" - elif file_type == "HTML": - return "traditional-html" - elif file_type == "HTML-plus": - return "traditional-html-plus" - elif file_type == "MD": - return "traditional-md" - else: - raise RuntimeError( - "Report file type: '" - + file_type - + "' hasn't been implemented. Available: XML, XML-plus, JSON, JSON-plus, HTML, HTML-plus, or MD" - ) - - def generate_report_file(self, file_path: str, report_type: str): - # To retrieve ZAP report in XML or HTML format - logging.info( - "Creating a new ZAP Report file with type '%s' at location: '%s'", - report_type, - file_path, - ) - - if report_type is None: - report_type = "XML" - - # Remove any trailing "-plus" from the file ending, as this is an artifact of the - # XML-plus / JSON-plus / HTML-plus report format selector. - report_file = "zap-results." + report_type.lower().replace('-plus', '') - self.__zap.reports.generate( - title="ZAP Report", - template=self.get_report_template_for_file_type(report_type), - reportdir=file_path, - contexts=self.__config.get_active_context_config["name"] if self.__config is not None and self.__config.get_active_context_config is not None else None, - reportfilename=report_file - ) - - def wait_for_zap_start(self, timeout_in_secs=600): - version = None - if not timeout_in_secs: - # if ZAP doesn't start in 10 mins then its probably not going to start - timeout_in_secs = 600 - - for x in range(0, timeout_in_secs): - try: - version = self.__zap.core.version - logging.debug("ZAP Version " + version) - logging.debug("Took " + str(x) + " seconds") - break - except IOError: - time.sleep(1) - - if not version: - raise IOError( - errno.EIO, - "Failed to connect to ZAP after {0} seconds".format(timeout_in_secs), - ) - - def zap_access_target(self, target: str): - logging.info("Testing ZAP Access to target URL: %s", target) - - res = self.__zap.urlopen(target) - if res.startswith("ZAP Error"): - raise IOError(errno.EIO, "ZAP failed to access: {0}".format(target)) - - def zap_tune(self, target: str): - logging.debug("Tune") - logging.debug("Disable all tags") - self.__zap.pscan.disable_all_tags() - logging.debug("Set max pscan alerts") - self.__zap.pscan.set_max_alerts_per_rule(10) - if ( - self.get_configuration.get_active_context_config is not None - and "includePaths" not in self.get_configuration.get_active_context_config - ): - logging.debug( - "Ensure the target is included in the active context by adding '%s.*' to the includePaths", - target, - ) - self.get_configuration.get_active_context_config["includePaths"] = [] - self.get_configuration.get_active_context_config["includePaths"].append( - target + ".*" - ) - - def zap_shutdown(self): - """This shutdown ZAP and prints out ZAP Scanning stats before shutting down.""" - - logging.info(":: Show all Statistics") - stats = self.__zap.stats.all_sites_stats() - logging.info(stats) - - logging.info(":: Shutting down the running ZAP Instance.") - self.__zap.core.shutdown() diff --git a/scanners/zap-advanced/templates/_helpers.tpl b/scanners/zap-advanced/templates/_helpers.tpl deleted file mode 100644 index 17841ea9a4..0000000000 --- a/scanners/zap-advanced/templates/_helpers.tpl +++ /dev/null @@ -1,55 +0,0 @@ -{{/* - SPDX-FileCopyrightText: the secureCodeBox authors - - SPDX-License-Identifier: Apache-2.0 -*/}} - -{{/* -Expand the name of the chart. -*/}} -{{- define "zap.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -If release name contains chart name it will be used as a full name. -*/}} -{{- define "zap.fullname" -}} -{{- if .Values.fullnameOverride -}} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- if contains $name .Release.Name -}} -{{- .Release.Name | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} -{{- end -}} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "zap.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Common labels -*/}} -{{- define "zap.labels" -}} -app: {{ .Release.Name | trunc 63 | trimSuffix "-" }} -chart: {{ include "zap.chart" . }} -release: {{ .Release.Name | trunc 63 | trimSuffix "-" }} -heritage: {{ .Release.Service }} -{{- end -}} - -{{/* -Create the name of the service -*/}} -{{- define "zap.makeServiceName" -}} - {{- $servicename := tpl (.Values.application.serviceName | toString) $ -}} - {{- printf "%s" $servicename -}} -{{- end -}} diff --git a/scanners/zap-advanced/templates/_probes.tpl b/scanners/zap-advanced/templates/_probes.tpl deleted file mode 100644 index 71ad9773bf..0000000000 --- a/scanners/zap-advanced/templates/_probes.tpl +++ /dev/null @@ -1,19 +0,0 @@ -{{/* - SPDX-FileCopyrightText: the secureCodeBox authors - - SPDX-License-Identifier: Apache-2.0 -*/}} - -{{- define "tcp-socket.liveness" }} -tcpSocket: - port: {{ .Values.container.port }} -initialDelaySeconds: 15 -periodSeconds: 20 -{{- end -}} - -{{- define "tcp-socket.readiness" }} -tcpSocket: - port: {{ .Values.container.port }} -initialDelaySeconds: 5 -periodSeconds: 10 -{{- end -}} diff --git a/scanners/zap-advanced/templates/cascading-rules.yaml b/scanners/zap-advanced/templates/cascading-rules.yaml deleted file mode 100644 index fe0ac6b903..0000000000 --- a/scanners/zap-advanced/templates/cascading-rules.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# We only want to import the default cascading rules if they are enabled -{{ if .Values.cascadingRules.enabled }} -# The CascadingRules are not directly in the /templates directory as their curly bracket syntax clashes with helms templates ... :( -# We import them as raw files to avoid these clashes as escaping them is even more messy -{{ range $path, $_ := .Files.Glob "cascading-rules/*" }} -# Include File -{{ $.Files.Get $path }} -# Separate multiple files ---- -{{ end }} -{{ end }} diff --git a/scanners/zap-advanced/templates/zap-advanced-parse-definition.yaml b/scanners/zap-advanced/templates/zap-advanced-parse-definition.yaml deleted file mode 100644 index 1cc0213999..0000000000 --- a/scanners/zap-advanced/templates/zap-advanced-parse-definition.yaml +++ /dev/null @@ -1,34 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -apiVersion: "execution.securecodebox.io/v1" -kind: ParseDefinition -metadata: - name: "zap-advanced-xml" - labels: - {{- include "zap.labels" . | nindent 4 }} -spec: - image: "{{ .Values.parser.image.repository }}:{{ .Values.parser.image.tag | default .Chart.Version }}" - imagePullPolicy: {{ .Values.parser.image.pullPolicy }} - ttlSecondsAfterFinished: {{ .Values.parser.ttlSecondsAfterFinished }} - env: - {{- toYaml .Values.parser.env | nindent 4 }} - scopeLimiterAliases: - {{- toYaml .Values.parser.scopeLimiterAliases | nindent 4 }} - affinity: - {{- toYaml .Values.parser.affinity | nindent 4 }} - tolerations: - {{- toYaml .Values.parser.tolerations | nindent 4 }} - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.parser.resources }} - resources: - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.parser.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 4 }} - {{- end }} diff --git a/scanners/zap-advanced/templates/zap-advanced-scan-type.yaml b/scanners/zap-advanced/templates/zap-advanced-scan-type.yaml deleted file mode 100644 index f07a2f10e6..0000000000 --- a/scanners/zap-advanced/templates/zap-advanced-scan-type.yaml +++ /dev/null @@ -1,139 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -{{- if not (empty .Values.zapConfiguration) }} -kind: ConfigMap -apiVersion: v1 -metadata: - name: zap-advanced-scantype-config - labels: - {{- include "zap.labels" . | nindent 4 }} -data: - 1-zap-advanced-scantype.yaml: | - {{- .Values.zapConfiguration | toYaml | nindent 4 -}} -{{- end }} ---- -apiVersion: "execution.securecodebox.io/v1" -kind: ScanType -metadata: - name: "zap-advanced-scan{{ .Values.scanner.nameAppend | default ""}}" - labels: - {{- include "zap.labels" . | nindent 4 }} - annotations: - {{- range $path, $d := .Files.Glob "scanner/scripts/authentication/*" }} - checksum.securecodebox.io/{{ $path | base }}: {{ $d | toString | sha256sum }} - {{ end }} - {{- range $path, $d := .Files.Glob "scanner/scripts/session/*" }} - checksum.securecodebox.io/{{ $path | base }}: {{ $d | toString | sha256sum }} - {{ end }} -spec: - extractResults: - type: zap-advanced-xml - location: "/home/securecodebox/zap-results.xml" - jobTemplate: - spec: - suspend: {{ .Values.scanner.suspend | default false }} - {{- if .Values.scanner.ttlSecondsAfterFinished }} - ttlSecondsAfterFinished: {{ .Values.scanner.ttlSecondsAfterFinished }} - {{- end }} - backoffLimit: {{ .Values.scanner.backoffLimit }} - {{- if .Values.scanner.activeDeadlineSeconds }} - activeDeadlineSeconds: {{ .Values.scanner.activeDeadlineSeconds }} - {{- end }} - template: - spec: - restartPolicy: Never - affinity: - {{- toYaml .Values.scanner.affinity | nindent 12 }} - tolerations: - {{- toYaml .Values.scanner.tolerations | nindent 12 }} - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 12 }} - {{- end }} - securityContext: - {{- toYaml .Values.scanner.podSecurityContext | nindent 12 }} - containers: - - name: zap-advanced-scan - image: "{{ .Values.scanner.image.repository }}:{{ .Values.scanner.image.tag | default .Chart.Version }}" - imagePullPolicy: {{ .Values.scanner.image.pullPolicy }} - command: - - "python3" - - "-m" - - "zapclient" - - "--report-type" - - {{ .Values.scanner.reportType | default "XML" }} - - "--zap-url" - - "localhost:8080" - - "--config-folder" - - "/home/securecodebox/configs/" - - "--output-folder" - - "/home/securecodebox/" - resources: - {{- toYaml .Values.scanner.resources | nindent 16 }} - securityContext: - {{- toYaml .Values.scanner.securityContext | nindent 16 }} - env: - {{- toYaml .Values.scanner.env | nindent 16 }} - envFrom: - {{- toYaml .Values.scanner.envFrom | nindent 16 }} - volumeMounts: - {{- toYaml .Values.scanner.extraVolumeMounts | nindent 16 }} - {{- if .Values.scanner.extraContainers }} - {{- toYaml .Values.scanner.extraContainers | nindent 12 }} - {{- end }} - - name: zap-sidecar - image: "{{ .Values.zapContainer.image.repository }}:{{ .Values.zapContainer.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: {{ .Values.zapContainer.image.pullPolicy }} - command: - - "zap.sh" - - "-daemon" - - "-port" - - "8080" - - "-host" - - "0.0.0.0" - - "-config" - - "database.recoverylog=false" # Tune ZAP, DB recovery is not needed here - - "-config" - - "connection.timeoutInSecs=120" # Tune ZAP timeout by default to be 2minutes - {{ if .Values.zapConfiguration.global}} - {{ if .Values.zapConfiguration.global.addonUpdate }} - - "-addonupdate" # Enable AddOn Updates on startup if possible - {{- end }} - {{- if .Values.zapConfiguration.global.addonInstall }} - {{- range .Values.zapConfiguration.global.addonInstall }} - - "-addoninstall" - - {{ . | quote }} - {{- end }} - {{- end }} - {{- end }} - - "-config" - - "api.disablekey=true" # Disble API Key because not required. Only pod local access allowed (localhost binding). - resources: - {{- toYaml .Values.zapContainer.resources | nindent 16 }} - securityContext: - {{- toYaml .Values.zapContainer.securityContext | nindent 16 }} - env: - {{- toYaml .Values.zapContainer.env | nindent 16 }} - envFrom: - {{- toYaml .Values.zapContainer.envFrom | nindent 16 }} - volumeMounts: - - mountPath: /home/securecodebox/ - name: scan-results - readOnly: false - {{ if .Values.zapContainer.extraVolumeMounts }} - {{- toYaml .Values.zapContainer.extraVolumeMounts | nindent 16 }} - {{- end }} - ports: - - containerPort: 8080 - {{- if .Values.zapContainer.extraContainers }} - {{- toYaml .Values.zapContainer.extraContainers | nindent 12 }} - {{- end }} - volumes: - {{- toYaml .Values.scanner.extraVolumes | nindent 12 }} - {{- with .Values.scanner.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 12 }} - {{- end }} diff --git a/scanners/zap-advanced/templates/zap-scripts-configmaps.yaml b/scanners/zap-advanced/templates/zap-scripts-configmaps.yaml deleted file mode 100644 index 0e03bbd900..0000000000 --- a/scanners/zap-advanced/templates/zap-scripts-configmaps.yaml +++ /dev/null @@ -1,28 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: zap-scripts-authentication - labels: - {{- include "zap.labels" . | nindent 4 }} -binaryData: - {{- range $path, $d := .Files.Glob "scanner/scripts/authentication/*" }} - {{ $path | base }}: |- - {{- $d | toString | b64enc | nindent 4 }} - {{ end }} ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: zap-scripts-session - labels: - {{- include "zap.labels" . | nindent 4 }} -binaryData: - {{- range $path, $d := .Files.Glob "scanner/scripts/session/*" }} - {{ $path | base }}: |- - {{- $d | toString | b64enc | nindent 4 }} - {{ end }} \ No newline at end of file diff --git a/scanners/zap-advanced/tests/__snapshot__/scanner_test.yaml.snap b/scanners/zap-advanced/tests/__snapshot__/scanner_test.yaml.snap deleted file mode 100644 index d6740a7bd7..0000000000 --- a/scanners/zap-advanced/tests/__snapshot__/scanner_test.yaml.snap +++ /dev/null @@ -1,217 +0,0 @@ -matches the snapshot: - 1: | - apiVersion: cascading.securecodebox.io/v1 - kind: CascadingRule - metadata: - labels: - securecodebox.io/intensive: medium - securecodebox.io/invasive: non-invasive - name: zap-advanced-http - spec: - matches: - anyOf: - - attributes: - service: http - state: open - category: Open Port - - attributes: - service: http-* - state: open - category: Open Port - scanSpec: - parameters: - - -t - - http://{{$.hostOrIP}}:{{attributes.port}} - scanType: zap-advanced-scan - 2: | - apiVersion: cascading.securecodebox.io/v1 - kind: CascadingRule - metadata: - labels: - securecodebox.io/intensive: medium - securecodebox.io/invasive: non-invasive - name: zap-advanced-https - spec: - matches: - anyOf: - - attributes: - service: https* - state: open - category: Open Port - scanSpec: - parameters: - - -t - - https://{{$.hostOrIP}}:{{attributes.port}} - scanType: zap-advanced-scan - 3: | - apiVersion: execution.securecodebox.io/v1 - kind: ParseDefinition - metadata: - labels: - app: RELEASE-NAME - chart: zap-advanced-0.0.0 - heritage: Helm - release: RELEASE-NAME - name: zap-advanced-xml - spec: - affinity: - foo: bar - env: - - name: foo - value: bar - image: docker.io/securecodebox/parser-zap:0.0.0 - imagePullPolicy: IfNotPresent - imagePullSecrets: - - name: foo - resources: - foo: bar - scopeLimiterAliases: - foo: bar - tolerations: - - foo: bar - ttlSecondsAfterFinished: null - 4: | - apiVersion: execution.securecodebox.io/v1 - kind: ScanType - metadata: - annotations: - checksum.securecodebox.io/juiceshop-session-management.js: 1bbd1c2634d732aff866d91acaeb29e68c13a0c5993ba8e16038adfbae2d7a99 - checksum.securecodebox.io/scb-oidc-password-grand-type.js: b2b91312a80cf4cb4f401672189ade16ebc99455e0ddf78d7920d1ed3caa0f6f - checksum.securecodebox.io/scb-oidc-session-management.js: d10dfd4afc34b85f758794d98dfb9076e7b4d14b5a81e9df3dfa3ae2b98077fa - labels: - app: RELEASE-NAME - chart: zap-advanced-0.0.0 - heritage: Helm - release: RELEASE-NAME - name: zap-advanced-scanfoo - spec: - extractResults: - location: /home/securecodebox/zap-results.xml - type: zap-advanced-xml - jobTemplate: - spec: - backoffLimit: 3 - suspend: false - template: - spec: - affinity: - foo: bar - containers: - - command: - - python3 - - -m - - zapclient - - --report-type - - XML - - --zap-url - - localhost:8080 - - --config-folder - - /home/securecodebox/configs/ - - --output-folder - - /home/securecodebox/ - env: - - name: foo - value: bar - envFrom: [] - image: docker.io/securecodebox/scanner-zap-advanced:0.0.0 - imagePullPolicy: IfNotPresent - name: zap-advanced-scan - resources: - foo: bar - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - all - privileged: false - readOnlyRootFilesystem: false - runAsNonRoot: false - volumeMounts: - - mountPath: /home/securecodebox/configs/1-zap-advanced-scantype.yaml - name: zap-advanced-scantype-config - readOnly: true - subPath: 1-zap-advanced-scantype.yaml - - image: bar - name: foo - - command: - - zap.sh - - -daemon - - -port - - "8080" - - -host - - 0.0.0.0 - - -config - - database.recoverylog=false - - -config - - connection.timeoutInSecs=120 - - -config - - api.disablekey=true - env: [] - envFrom: [] - image: docker.io/zaproxy/zap-stable:0.0.0 - imagePullPolicy: IfNotPresent - name: zap-sidecar - ports: - - containerPort: 8080 - resources: {} - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - all - privileged: false - readOnlyRootFilesystem: false - runAsNonRoot: false - volumeMounts: - - mountPath: /home/securecodebox/ - name: scan-results - readOnly: false - - mountPath: /home/zap/.ZAP_D/scripts/scripts/authentication/ - name: zap-scripts-authentication - readOnly: true - - mountPath: /home/zap/.ZAP_D/scripts/scripts/session/ - name: zap-scripts-session - readOnly: true - imagePullSecrets: - - name: foo - restartPolicy: Never - securityContext: - fsGroup: 1234 - tolerations: - - foo: bar - volumes: - - configMap: - name: zap-advanced-scantype-config - optional: true - name: zap-advanced-scantype-config - - configMap: - name: zap-scripts-authentication - name: zap-scripts-authentication - - configMap: - name: zap-scripts-session - name: zap-scripts-session - 5: | - apiVersion: v1 - binaryData: - scb-oidc-password-grand-type.js: Ly8gU1BEWC1GaWxlQ29weXJpZ2h0VGV4dDogdGhlIHNlY3VyZUNvZGVCb3ggYXV0aG9ycwovLwovLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMAoKdmFyIEh0dHBSZXF1ZXN0SGVhZGVyID0gSmF2YS50eXBlKCJvcmcucGFyb3Nwcm94eS5wYXJvcy5uZXR3b3JrLkh0dHBSZXF1ZXN0SGVhZGVyIiksCiAgICBIdHRwSGVhZGVyID0gSmF2YS50eXBlKCJvcmcucGFyb3Nwcm94eS5wYXJvcy5uZXR3b3JrLkh0dHBIZWFkZXIiKSwKICAgIFVSSSA9IEphdmEudHlwZSgib3JnLmFwYWNoZS5jb21tb25zLmh0dHBjbGllbnQuVVJJIik7Ci8qKgogKiBPSURDIFBhc3N3b3JkIEdyYW50IFR5cGUgYmFzZWQgYXV0aGVudGljYXRpb24gc2NyaXB0IGZvciBaQVAuCiAqCiAqIFRoaXMgYXV0aGVudGljYXRlIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aGVuZXZlciBaQVAgcmVxdWlyZXMgdG8gYXV0aGVudGljYXRlLAogKiBmb3IgYSBDb250ZXh0IHdoaWNoIGhhcyB0aGlzIHNjcmlwdCBzZWxlY3RlZCBhcyB0aGUgYXV0aGVudGljYXRpb24gbWV0aG9kLgogKgogKiBUaGlzIGZ1bmN0aW9uIHNob3VsZCBzZW5kIGFueSBtZXNzYWdlcyB0aGF0IGFyZSByZXF1aXJlZCB0byBkbyB0aGUgYXV0aGVudGljYXRpb24KICogYW5kIHNob3VsZCByZXR1cm4gYSBtZXNzYWdlIHdpdGggYW4gYXV0aGVudGljYXRlZCByZXNwb25zZS4KICoKICogVGhpcyBhdXRoIGlzIGJhc2VkIG9uIHRoZSBncmFuZCB0eXBlICJwYXNzd29yZCIgdG8gcmV0cmlldmUgZnJlc2ggdG9rZW5zOgogKiBodHRwczovL2RldmVsb3Blci5va3RhLmNvbS9ibG9nLzIwMTgvMDYvMjkvd2hhdC1pcy10aGUtb2F1dGgyLXBhc3N3b3JkLWdyYW50CiAqCiAqIEZvciBBdXRoZW50aWNhdGlvbiBzZWxlY3QvY29uZmlndXJlIGluIHlvdXIgWkFQIENvbnRleHQ6CiAqCiAqIC0gQXV0aGVudGljYXRpb24gbWV0aG9kOiBTY3JpcHRCYXNlZCBBdXRoZW50aWNhdGlvbgogKiAtIExvZ2luIEZPUk0gdGFyZ2V0IFVSTDogaHR0cHM6Ly8ka2V5Y2xvYWstdXJsL2F1dGgvcmVhbG1zLyRhcHAvcHJvdG9jb2wvb3BlbmlkLWNvbm5lY3QvdG9rZW4KICogLSB1c2VybmFtZSBwYXJhbWV0ZXI6IHlvdXItdXNlcm5hbWUtdG8tZ2V0LXRva2VucwogKiAtIHBhc3N3b3JkIHBhcmFtZXRlcjogeW91ci1wYXNzd29yZC10by1nZXQtdG9rZW5zCiAqIC0gTG9nZ2VkIG91dCByZWdleDogIi4qQ3JlZGVudGlhbHMgYXJlIHJlcXVpcmVkIHRvIGFjY2VzcyB0aGlzIHJlc291cmNlLioiCiAqCiAqIE5PVEU6IEFueSBtZXNzYWdlIHNlbnQgaW4gdGhlIGZ1bmN0aW9uIHNob3VsZCBiZSBvYnRhaW5lZCB1c2luZyB0aGUgJ2hlbHBlci5wcmVwYXJlTWVzc2FnZSgpJwogKiAgICAgICBtZXRob2QuCiAqCiAqIEBwYXJhbSB7T2JqZWN0fSBoZWxwZXIgLSBIZWxwZXIgY2xhc3MgcHJvdmlkaW5nIHVzZWZ1bCBtZXRob2RzOiBwcmVwYXJlTWVzc2FnZSgpLCBzZW5kQW5kUmVjZWl2ZShtc2cpLgogKiBAcGFyYW0ge09iamVjdH0gcGFyYW1zVmFsdWVzIC0gVmFsdWVzIG9mIHRoZSBwYXJhbWV0ZXJzIGNvbmZpZ3VyZWQgaW4gdGhlIFNlc3Npb24gUHJvcGVydGllcyAtPiBBdXRoZW50aWNhdGlvbiBwYW5lbC4KICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoZSBwYXJhbXNWYWx1ZXMgaXMgYSBtYXAgd2l0aCBwYXJhbWV0ZXJzIG5hbWVzIGFzIGtleXMgKGxpa2UgcmV0dXJuZWQKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5IHRoZSBnZXRSZXF1aXJlZFBhcmFtc05hbWVzKCkgYW5kIGdldE9wdGlvbmFsUGFyYW1zTmFtZXMoKSBmdW5jdGlvbnMgYmVsb3cpLgogKiBAcGFyYW0ge09iamVjdH0gY3JlZGVudGlhbHMgLSBPYmplY3QgY29udGFpbmluZyB0aGUgY3JlZGVudGlhbHMgY29uZmlndXJlZCBpbiB0aGUgU2Vzc2lvbiBQcm9wZXJ0aWVzIC0+IFVzZXJzIHBhbmVsLgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGUgY3JlZGVudGlhbCB2YWx1ZXMgY2FuIGJlIG9idGFpbmVkIHZpYSBjYWxscyB0byB0aGUgZ2V0UGFyYW0ocGFyYW1OYW1lKSBtZXRob2QuCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoZSBwYXJhbSBuYW1lcyBhcmUgdGhlIG9uZXMgcmV0dXJuZWQgYnkgdGhlIGdldENyZWRlbnRpYWxzUGFyYW1zTmFtZXMoKSBiZWxvdy4KICovCmZ1bmN0aW9uIGF1dGhlbnRpY2F0ZShoZWxwZXIsIHBhcmFtc1ZhbHVlcywgY3JlZGVudGlhbHMpIHsKICAgIHByaW50KCJBdXRoZW50aWNhdGlvbiB2aWEgc2NiLW9pZGMtcGFzc3dvcmQtZ3JhbmQtdHlwZS5qcy4uLiIpOwoKICAgIC8vIFByZXBhcmUgdGhlIGxvZ2luIHJlcXVlc3QgZGV0YWlscwogICAgdmFyIHVybCA9IHBhcmFtc1ZhbHVlcy5nZXQoIlVSTCIpOwogICAgdmFyIGNsaWVudElkID0gcGFyYW1zVmFsdWVzLmdldCgiY2xpZW50SWQiKTsKICAgIHByaW50KCJMb2dnaW5nIGluIHRvIHVybDogIiArIHVybCArICIgY2xpZW50SWQ6ICIgKyBjbGllbnRJZCk7CgogICAgdmFyIHJlcXVlc3RVcmkgPSBuZXcgVVJJKHVybCwgZmFsc2UpOwogICAgdmFyIHJlcXVlc3RNZXRob2QgPSBIdHRwUmVxdWVzdEhlYWRlci5QT1NUOwoKICAgIC8vIEJ1aWxkIHRoZSByZXF1ZXN0IGJvZHkgdXNpbmcgdGhlIGNyZWRlbnRpYWxzIHZhbHVlcwogICAgLy8gVGhpcyBhdXRoIGlzIGJhc2VkIG9uIHRoZSBncmFuZCB0eXBlICJwYXNzd29yZCIgdG8gcmV0cmlldmUgZnJlc2ggdG9rZW5zCiAgICAvLyBodHRwczovL2RldmVsb3Blci5va3RhLmNvbS9ibG9nLzIwMTgvMDYvMjkvd2hhdC1pcy10aGUtb2F1dGgyLXBhc3N3b3JkLWdyYW50CiAgICB2YXIgcmVxdWVzdEJvZHkgPSAiZ3JhbnRfdHlwZT1wYXNzd29yZCZjbGllbnRfaWQ9IiArIGNsaWVudElkICsgIiZ1c2VybmFtZT0iICsgY3JlZGVudGlhbHMuZ2V0UGFyYW0oInVzZXJuYW1lIikgKyAiJnBhc3N3b3JkPSIgKyBjcmVkZW50aWFscy5nZXRQYXJhbSgicGFzc3dvcmQiKTsKCiAgICAvLyBCdWlsZCB0aGUgYWN0dWFsIG1lc3NhZ2UgdG8gYmUgc2VudAogICAgcHJpbnQoIlNlbmRpbmcgIiArIHJlcXVlc3RNZXRob2QgKyAiIHJlcXVlc3QgdG8gIiArIHJlcXVlc3RVcmkgKyAiIHdpdGggYm9keTogIiArIHJlcXVlc3RCb2R5KTsKICAgIHZhciBtc2cgPSBoZWxwZXIucHJlcGFyZU1lc3NhZ2UoKTsKICAgIG1zZy5zZXRSZXF1ZXN0Qm9keShyZXF1ZXN0Qm9keSk7CgogICAgdmFyIHJlcXVlc3RIZWFkZXIgPSBuZXcgSHR0cFJlcXVlc3RIZWFkZXIocmVxdWVzdE1ldGhvZCwgcmVxdWVzdFVyaSwgSHR0cEhlYWRlci5IVFRQMTApOwogICAgbXNnLnNldFJlcXVlc3RIZWFkZXIocmVxdWVzdEhlYWRlcik7CiAgICBwcmludCgiTXNnIHByZXBhcmVkIikKCiAgICAvLyBTZW5kIHRoZSBhdXRoZW50aWNhdGlvbiBtZXNzYWdlIGFuZCByZXR1cm4gaXQKICAgIHRyeSB7CiAgICAgICAgaGVscGVyLnNlbmRBbmRSZWNlaXZlKG1zZyk7CiAgICAgICAgcHJpbnQoIlJlY2VpdmVkIHJlc3BvbnNlIHN0YXR1cyBjb2RlIGZvciBhdXRoZW50aWNhdGlvbiByZXF1ZXN0OiAiICsgbXNnLmdldFJlc3BvbnNlSGVhZGVyKCkuZ2V0U3RhdHVzQ29kZSgpKTsKICAgICAgICByZXR1cm4gbXNnOwogICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgcHJpbnQoIkdvdCBlcnJvciIpOwogICAgICAgIHByaW50KGVycik7CiAgICB9CgogICAgcmV0dXJuIG51bGwKfQoKLyoqCiAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGR1cmluZyB0aGUgc2NyaXB0IGxvYWRpbmcgdG8gb2J0YWluIGEgbGlzdCBvZiByZXF1aXJlZCBjb25maWd1cmF0aW9uIHBhcmFtZXRlciBuYW1lcy4KICoKICogVGhlc2UgbmFtZXMgd2lsbCBiZSBzaG93biBpbiB0aGUgU2Vzc2lvbiBQcm9wZXJ0aWVzIC0+IEF1dGhlbnRpY2F0aW9uIHBhbmVsIGZvciBjb25maWd1cmF0aW9uLiBUaGV5IGNhbiBiZSB1c2VkCiAqIHRvIGlucHV0IGR5bmFtaWMgZGF0YSBpbnRvIHRoZSBzY3JpcHQsIGZyb20gdGhlIHVzZXIgaW50ZXJmYWNlIChlLmcuIGEgbG9naW4gVVJMLCBuYW1lIG9mIFBPU1QgcGFyYW1ldGVycyBldGMuKS4KICovCmZ1bmN0aW9uIGdldFJlcXVpcmVkUGFyYW1zTmFtZXMoKSB7CiAgICByZXR1cm4gWyJVUkwiLCAiY2xpZW50SWQiXTsKfQoKLyoqCiAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGR1cmluZyB0aGUgc2NyaXB0IGxvYWRpbmcgdG8gb2J0YWluIGEgbGlzdCBvZiBvcHRpb25hbCBjb25maWd1cmF0aW9uIHBhcmFtZXRlciBuYW1lcy4KICoKICogVGhlc2Ugd2lsbCBiZSBzaG93biBpbiB0aGUgU2Vzc2lvbiBQcm9wZXJ0aWVzIC0+IEF1dGhlbnRpY2F0aW9uIHBhbmVsIGZvciBjb25maWd1cmF0aW9uLiBUaGV5IGNhbiBiZSB1c2VkCiAqIHRvIGlucHV0IGR5bmFtaWMgZGF0YSBpbnRvIHRoZSBzY3JpcHQsIGZyb20gdGhlIHVzZXIgaW50ZXJmYWNlIChlLmcuIGEgbG9naW4gVVJMLCBuYW1lIG9mIFBPU1QgcGFyYW1ldGVycyBldGMuKS4KICovCmZ1bmN0aW9uIGdldE9wdGlvbmFsUGFyYW1zTmFtZXMoKSB7CiAgICByZXR1cm4gW107Cn0KCi8qKgogKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBkdXJpbmcgdGhlIHNjcmlwdCBsb2FkaW5nIHRvIG9idGFpbiBhIGxpc3Qgb2YgcmVxdWlyZWQgY3JlZGVudGlhbCBwYXJhbWV0ZXIgbmFtZXMuCiAqCiAqIFRoZXkgYXJlIGNvbmZpZ3VyZWQgZm9yIGVhY2ggdXNlciBjb3JyZXNwb25kaW5nIHRvIGFuIGF1dGhlbnRpY2F0aW9uIHVzaW5nIHRoaXMgc2NyaXB0LgogKi8KZnVuY3Rpb24gZ2V0Q3JlZGVudGlhbHNQYXJhbXNOYW1lcygpIHsKICAgIHJldHVybiBbInVzZXJuYW1lIiwgInBhc3N3b3JkIl07Cn0= - kind: ConfigMap - metadata: - labels: - app: RELEASE-NAME - chart: zap-advanced-0.0.0 - heritage: Helm - release: RELEASE-NAME - name: zap-scripts-authentication - 6: | - apiVersion: v1 - binaryData: - juiceshop-session-management.js: Ly8gU1BEWC1GaWxlQ29weXJpZ2h0VGV4dDogdGhlIHNlY3VyZUNvZGVCb3ggYXV0aG9ycwovLwovLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMAoKLyoKICogU2Vzc2lvbiBNYW5hZ2VtZW50IHNjcmlwdCBmb3IgT1dBU1AgSnVpY2UgU2hvcDogaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3phcHJveHkvY29tbXVuaXR5LXNjcmlwdHMvbWFzdGVyL3Nlc3Npb24vSnVpY2UlMjBTaG9wJTIwU2Vzc2lvbiUyME1hbmFnZW1lbnQuanMKICogCiAqIEZvciBBdXRoZW50aWNhdGlvbiBzZWxlY3Q6CiAqIAkJQXV0aGVudGljYXRpb24gbWV0aG9kOgkJSlNPTi1iYXNlZCBhdXRoZW50aWNhdGlvbgogKiAJCUxvZ2luIEZPUk0gdGFyZ2V0IFVSTDoJCWh0dHA6Ly9sb2NhbGhvc3Q6MzAwMC9yZXN0L3VzZXIvbG9naW4KICogCQlVUkwgdG8gR0VUIExvZ2luIFBhZ2U6CQlodHRwOi8vbG9jYWxob3N0OjMwMDAvCiAqIAkJTG9naW4gUmVxdWVzdCBQT1NUIGRhdGE6CXsiZW1haWwiOiJ0ZXN0QHRlc3QuY29tIiwicGFzc3dvcmQiOiJ0ZXN0MSJ9CiAqIAkJVXNlcm5hbWUgUGFyYW1ldGVyOgkJCWVtYWlsCiAqIAkJUGFzc3dvcmQgUGFyYW1ldGVyOgkJCXBhc3N3b3JkCiAqIAkJTG9nZ2VkIG91dCByZWdleDoJCQlcUXsidXNlciI6e319XEUKICogCiAqIE9idmlvdXNseSB1cGRhdGUgd2l0aCBhbnkgbG9jYWwgY2hhbmdlcyBhcyBuZWNlc3NhcnkuCiAqLwoKdmFyIENPT0tJRV9UWVBFICAgPSBvcmcucGFyb3Nwcm94eS5wYXJvcy5uZXR3b3JrLkh0bWxQYXJhbWV0ZXIuVHlwZS5jb29raWU7CnZhciBIdG1sUGFyYW1ldGVyID0gSmF2YS50eXBlKCdvcmcucGFyb3Nwcm94eS5wYXJvcy5uZXR3b3JrLkh0bWxQYXJhbWV0ZXInKQp2YXIgU2NyaXB0VmFycyA9IEphdmEudHlwZSgnb3JnLnphcHJveHkuemFwLmV4dGVuc2lvbi5zY3JpcHQuU2NyaXB0VmFycycpOwoKZnVuY3Rpb24gZXh0cmFjdFdlYlNlc3Npb24oc2Vzc2lvbldyYXBwZXIpIHsKCS8vIHBhcnNlIHRoZSBhdXRoZW50aWNhdGlvbiByZXNwb25zZQoJdmFyIGpzb24gPSBKU09OLnBhcnNlKHNlc3Npb25XcmFwcGVyLmdldEh0dHBNZXNzYWdlKCkuZ2V0UmVzcG9uc2VCb2R5KCkudG9TdHJpbmcoKSk7Cgl2YXIgdG9rZW4gPSBqc29uLmF1dGhlbnRpY2F0aW9uLnRva2VuOwoJLy8gc2F2ZSB0aGUgYXV0aGVudGljYXRpb24gdG9rZW4KCXNlc3Npb25XcmFwcGVyLmdldFNlc3Npb24oKS5zZXRWYWx1ZSgidG9rZW4iLCB0b2tlbik7CglTY3JpcHRWYXJzLnNldEdsb2JhbFZhcigianVpY2VzaG9wLnRva2VuIiwgdG9rZW4pOwp9CiAgICAJCmZ1bmN0aW9uIGNsZWFyV2ViU2Vzc2lvbklkZW50aWZpZXJzKHNlc3Npb25XcmFwcGVyKSB7Cgl2YXIgaGVhZGVycyA9IHNlc3Npb25XcmFwcGVyLmdldEh0dHBNZXNzYWdlKCkuZ2V0UmVxdWVzdEhlYWRlcigpOwoJaGVhZGVycy5zZXRIZWFkZXIoIkF1dGhvcml6YXRpb24iLCBudWxsKTsKCVNjcmlwdFZhcnMuc2V0R2xvYmFsVmFyKCJqdWljZXNob3AudG9rZW4iLCBudWxsKTsKfQogICAgCQpmdW5jdGlvbiBwcm9jZXNzTWVzc2FnZVRvTWF0Y2hTZXNzaW9uKHNlc3Npb25XcmFwcGVyKSB7Cgl2YXIgdG9rZW4gPSBzZXNzaW9uV3JhcHBlci5nZXRTZXNzaW9uKCkuZ2V0VmFsdWUoInRva2VuIik7CglpZiAodG9rZW4gPT09IG51bGwpIHsKCQlwcmludCgnSlMgbWdtdCBzY3JpcHQ6IG5vIHRva2VuJyk7CgkJcmV0dXJuOwoJfQoJdmFyIGNvb2tpZSA9IG5ldyBIdG1sUGFyYW1ldGVyKENPT0tJRV9UWVBFLCAidG9rZW4iLCB0b2tlbik7CgkvLyBhZGQgdGhlIHNhdmVkIGF1dGhlbnRpY2F0aW9uIHRva2VuIGFzIGFuIEF1dGhlbnRpY2F0aW9uIGhlYWRlciBhbmQgYSBjb29raWUKCXZhciBtc2cgPSBzZXNzaW9uV3JhcHBlci5nZXRIdHRwTWVzc2FnZSgpOwoJbXNnLmdldFJlcXVlc3RIZWFkZXIoKS5zZXRIZWFkZXIoIkF1dGhvcml6YXRpb24iLCAiQmVhcmVyICIgKyB0b2tlbik7Cgl2YXIgY29va2llcyA9IG1zZy5nZXRSZXF1ZXN0SGVhZGVyKCkuZ2V0Q29va2llUGFyYW1zKCk7Cgljb29raWVzLmFkZChjb29raWUpOwoJbXNnLmdldFJlcXVlc3RIZWFkZXIoKS5zZXRDb29raWVQYXJhbXMoY29va2llcyk7Cn0KCmZ1bmN0aW9uIGdldFJlcXVpcmVkUGFyYW1zTmFtZXMoKSB7CglyZXR1cm4gW107Cn0KCmZ1bmN0aW9uIGdldE9wdGlvbmFsUGFyYW1zTmFtZXMoKSB7CglyZXR1cm4gW107Cn0K - scb-oidc-session-management.js: Ly8gU1BEWC1GaWxlQ29weXJpZ2h0VGV4dDogdGhlIHNlY3VyZUNvZGVCb3ggYXV0aG9ycwovLwovLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMAoKLyoqCiAqIFNlc3Npb24gTWFuYWdlbWVudCBzY3JpcHQgZm9yIE9JREMgQXV0aGVudGljYXRpb24uCiAqCiAqIEFkYXB0ZWQgZnJvbSBPV0FTUCBKdWljZSBTaG9wIEV4YW1wbGU6IGh0dHBzOi8vd3d3LnphcHJveHkub3JnL2Jsb2cvMjAyMC0wNi0wNC16YXAtMi05LTAtaGlnaGxpZ2h0cy8KICovCgpmdW5jdGlvbiBleHRyYWN0V2ViU2Vzc2lvbihzZXNzaW9uV3JhcHBlcikgewogICAgcHJpbnQoImV4dHJhY3RXZWJTZXNzaW9uIikKICAgIC8vIHBhcnNlIHRoZSBhdXRoZW50aWNhdGlvbiByZXNwb25zZQogICAgdmFyIGpzb24gPSBKU09OLnBhcnNlKHNlc3Npb25XcmFwcGVyLmdldEh0dHBNZXNzYWdlKCkuZ2V0UmVzcG9uc2VCb2R5KCkudG9TdHJpbmcoKSk7CiAgICB2YXIgdG9rZW4gPSBqc29uLmFjY2Vzc190b2tlbjsKICAgIC8vIHNhdmUgdGhlIGF1dGhlbnRpY2F0aW9uIHRva2VuCiAgICBzZXNzaW9uV3JhcHBlci5nZXRTZXNzaW9uKCkuc2V0VmFsdWUoInRva2VuIiwgdG9rZW4pOwp9CgpmdW5jdGlvbiBjbGVhcldlYlNlc3Npb25JZGVudGlmaWVycyhzZXNzaW9uV3JhcHBlcikgewogICAgcHJpbnQoImNsZWFyV2ViU2Vzc2lvbklkZW50aWZpZXJzIikKICAgIHZhciBoZWFkZXJzID0gc2Vzc2lvbldyYXBwZXIuZ2V0SHR0cE1lc3NhZ2UoKS5nZXRSZXF1ZXN0SGVhZGVyKCk7CiAgICBoZWFkZXJzLnNldEhlYWRlcigiQXV0aG9yaXphdGlvbiIsIG51bGwpOwp9CgpmdW5jdGlvbiBwcm9jZXNzTWVzc2FnZVRvTWF0Y2hTZXNzaW9uKHNlc3Npb25XcmFwcGVyKSB7CiAgICBwcmludCgicHJvY2Vzc01lc3NhZ2VUb01hdGNoU2Vzc2lvbiIpCiAgICB2YXIgdG9rZW4gPSBzZXNzaW9uV3JhcHBlci5nZXRTZXNzaW9uKCkuZ2V0VmFsdWUoInRva2VuIik7CiAgICBpZiAodG9rZW4gPT09IG51bGwpIHsKICAgICAgICBwcmludCgnSlMgbWdtdCBzY3JpcHQ6IG5vIHRva2VuJyk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8vIGFkZCB0aGUgc2F2ZWQgYXV0aGVudGljYXRpb24gdG9rZW4gYXMgYW4gQXV0aGVudGljYXRpb24gaGVhZGVyIGFuZCBhIGNvb2tpZQogICAgdmFyIG1zZyA9IHNlc3Npb25XcmFwcGVyLmdldEh0dHBNZXNzYWdlKCk7CiAgICBtc2cuZ2V0UmVxdWVzdEhlYWRlcigpLnNldEhlYWRlcigiQXV0aG9yaXphdGlvbiIsICJCZWFyZXIgIiArIHRva2VuKTsKfQoKLyoqCiAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGR1cmluZyB0aGUgc2NyaXB0IGxvYWRpbmcgdG8gb2J0YWluIGEgbGlzdCBvZiByZXF1aXJlZCBjb25maWd1cmF0aW9uIHBhcmFtZXRlciBuYW1lcy4KICoKICogVGhlc2UgbmFtZXMgd2lsbCBiZSBzaG93biBpbiB0aGUgU2Vzc2lvbiBQcm9wZXJ0aWVzIC0+IEF1dGhlbnRpY2F0aW9uIHBhbmVsIGZvciBjb25maWd1cmF0aW9uLiBUaGV5IGNhbiBiZSB1c2VkCiAqIHRvIGlucHV0IGR5bmFtaWMgZGF0YSBpbnRvIHRoZSBzY3JpcHQsIGZyb20gdGhlIHVzZXIgaW50ZXJmYWNlIChlLmcuIGEgbG9naW4gVVJMLCBuYW1lIG9mIFBPU1QgcGFyYW1ldGVycyBldGMuKS4KICovCmZ1bmN0aW9uIGdldFJlcXVpcmVkUGFyYW1zTmFtZXMoKSB7CiAgICByZXR1cm4gW107Cn0KCi8qKgogKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBkdXJpbmcgdGhlIHNjcmlwdCBsb2FkaW5nIHRvIG9idGFpbiBhIGxpc3Qgb2Ygb3B0aW9uYWwgY29uZmlndXJhdGlvbiBwYXJhbWV0ZXIgbmFtZXMuCiAqCiAqIFRoZXNlIHdpbGwgYmUgc2hvd24gaW4gdGhlIFNlc3Npb24gUHJvcGVydGllcyAtPiBBdXRoZW50aWNhdGlvbiBwYW5lbCBmb3IgY29uZmlndXJhdGlvbi4gVGhleSBjYW4gYmUgdXNlZAogKiB0byBpbnB1dCBkeW5hbWljIGRhdGEgaW50byB0aGUgc2NyaXB0LCBmcm9tIHRoZSB1c2VyIGludGVyZmFjZSAoZS5nLiBhIGxvZ2luIFVSTCwgbmFtZSBvZiBQT1NUIHBhcmFtZXRlcnMgZXRjLikuCiAqLwpmdW5jdGlvbiBnZXRPcHRpb25hbFBhcmFtc05hbWVzKCkgewogICAgcmV0dXJuIFtdOwp9Cg== - kind: ConfigMap - metadata: - labels: - app: RELEASE-NAME - chart: zap-advanced-0.0.0 - heritage: Helm - release: RELEASE-NAME - name: zap-scripts-session diff --git a/scanners/zap-advanced/tests/scanner_test.yaml b/scanners/zap-advanced/tests/scanner_test.yaml deleted file mode 100644 index c5b3b49c3a..0000000000 --- a/scanners/zap-advanced/tests/scanner_test.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -suite: Full Snapshot - -tests: - - it: matches the snapshot - chart: - version: 0.0.0 - appVersion: 0.0.0 - set: - cascadingRules.enabled: true - imagePullSecrets: [{name: foo}] - parser: - env: [{name: foo, value: bar}] - scopeLimiterAliases: {foo: bar} - affinity: {foo: bar} - tolerations: [{foo: bar}] - resources: {foo: bar} - scanner: - nameAppend: foo - resources: {foo: bar} - env: [{name: foo, value: bar}] - extraContainers: [{name: foo, image: bar}] - podSecurityContext: {fsGroup: 1234} - affinity: {foo: bar} - tolerations: [{foo: bar}] - asserts: - - matchSnapshot: {} diff --git a/scanners/zap-advanced/values.yaml b/scanners/zap-advanced/values.yaml deleted file mode 100644 index 436bce6289..0000000000 --- a/scanners/zap-advanced/values.yaml +++ /dev/null @@ -1,200 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 -# -- Define imagePullSecrets when a private registry is used (see: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) -imagePullSecrets: [] - -parser: - image: - # parser.image.repository -- Parser image repository - repository: docker.io/securecodebox/parser-zap - # parser.image.tag -- Parser image tag - # @default -- defaults to the charts version - tag: null - # -- Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images - pullPolicy: IfNotPresent - - # parser.ttlSecondsAfterFinished -- seconds after which the Kubernetes job for the parser will be deleted. Requires the Kubernetes TTLAfterFinished controller: https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/ - ttlSecondsAfterFinished: null - # parser.env -- Optional environment variables mapped into each parseJob (see: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) - env: [] - - # parser.scopeLimiterAliases -- Optional finding aliases to be used in the scopeLimiter. - scopeLimiterAliases: {} - - # parser.nodeSelector -- Optional nodeSelector settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/) - nodeSelector: {} - - # parser.affinity -- Optional affinity settings that control how the parser job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) - affinity: {} - - # parser.tolerations -- Optional tolerations settings that control how the parser job is scheduled (see: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) - tolerations: [] - - # -- Optional resources lets you control resource limits and requests for the parser container. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - # @default -- `{ requests: { cpu: "200m", memory: "100Mi" }, limits: { cpu: "400m", memory: "200Mi" } }` - resources: {} - -scanner: - image: - # scanner.image.repository -- Container Image to run the scan - repository: docker.io/securecodebox/scanner-zap-advanced - # scanner.image.tag -- defaults to the charts version - tag: null - # -- Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images - pullPolicy: IfNotPresent - - # scanner.nameAppend -- append a string to the default scantype name. - nameAppend: null - - # -- seconds after which the Kubernetes job for the scanner will be deleted. Requires the Kubernetes TTLAfterFinished controller: https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/ - ttlSecondsAfterFinished: null - # -- There are situations where you want to fail a scan Job after some amount of time. To do so, set activeDeadlineSeconds to define an active deadline (in seconds) when considering a scan Job as failed. (see: https://kubernetes.io/docs/concepts/workloads/controllers/job/#job-termination-and-cleanup) - activeDeadlineSeconds: null - # -- There are situations where you want to fail a scan Job after some amount of retries due to a logical error in configuration etc. To do so, set backoffLimit to specify the number of retries before considering a scan Job as failed. (see: https://kubernetes.io/docs/concepts/workloads/controllers/job/#pod-backoff-failure-policy) - # @default -- 3 - backoffLimit: 3 - - # scanner.resources -- CPU/memory resource requests/limits (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/, https://kubernetes.io/docs/tasks/configure-pod-container/assign-cpu-resource/) - resources: {} - # resources: - # requests: - # memory: "256Mi" - # cpu: "250m" - # limits: - # memory: "512Mi" - # cpu: "500m" - - # scanner.env -- Optional environment variables mapped into each scanJob (see: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) - env: [] - - # scanner.envFrom -- Optional mount environment variables from configMaps or secrets (see: https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/#configure-all-key-value-pairs-in-a-secret-as-container-environment-variables) - envFrom: [] - - # scanner.extraVolumes -- Optional Volumes mapped into each scanJob (see: https://kubernetes.io/docs/concepts/storage/volumes/) - extraVolumes: - - name: zap-advanced-scantype-config - configMap: - name: zap-advanced-scantype-config - optional: true - - name: zap-scripts-authentication - configMap: - name: zap-scripts-authentication - - name: zap-scripts-session - configMap: - name: zap-scripts-session - - # scanner.extraVolumeMounts -- Optional VolumeMounts mapped into each scanJob (see: https://kubernetes.io/docs/concepts/storage/volumes/) - extraVolumeMounts: - - name: zap-advanced-scantype-config - mountPath: /home/securecodebox/configs/1-zap-advanced-scantype.yaml - subPath: 1-zap-advanced-scantype.yaml - readOnly: true - - # scanner.extraContainers -- Optional additional Containers started with each scanJob (see: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/) - extraContainers: [] - - # scanner.podSecurityContext -- Optional securityContext set on scanner pod (see: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) - podSecurityContext: - {} - # fsGroup: 2000 - - # scanner.securityContext -- Optional securityContext set on scanner container (see: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) - securityContext: - # scanner.securityContext.runAsNonRoot -- Enforces that the scanner image is run as a non root user - runAsNonRoot: false - # scanner.securityContext.readOnlyRootFilesystem -- Prevents write access to the containers file system - readOnlyRootFilesystem: false - # scanner.securityContext.allowPrivilegeEscalation -- Ensure that users privileges cannot be escalated - allowPrivilegeEscalation: false - # scanner.securityContext.privileged -- Ensures that the scanner container is not run in privileged mode - privileged: false - capabilities: - drop: - # scanner.securityContext.capabilities.drop[0] -- This drops all linux privileges from the container. - - all - - # scanner.nodeSelector -- Optional nodeSelector settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/) - nodeSelector: {} - - # scanner.affinity -- Optional affinity settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) - affinity: {} - - # scanner.tolerations -- Optional tolerations settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) - tolerations: [] - - # -- if set to true the scan job will be suspended after creation. You can then resume the job using `kubectl resume ` or using a job scheduler like kueue - suspend: false - - # -- Optional to configure the reportType of the scan ZAP Scan. Must be one of the supported formats: XML,XML-plus,JSON,JSON-plus,HTML,HTML-plus,MD - # @default -- "XML" - reportType: "XML" - -zapContainer: - image: - # -- Container Image to run the scan - repository: docker.io/zaproxy/zap-stable - # -- defaults to the charts appVersion - tag: null - # -- Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images - pullPolicy: IfNotPresent - - # -- CPU/memory resource requests/limits (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/, https://kubernetes.io/docs/tasks/configure-pod-container/assign-cpu-resource/) - resources: {} - # resources: - # requests: - # memory: "256Mi" - # cpu: "250m" - # limits: - # memory: "512Mi" - # cpu: "500m" - - # -- Optional environment variables mapped into each scanJob (see: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) - env: [] - - # -- Optional mount environment variables from configMaps or secrets (see: https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/#configure-all-key-value-pairs-in-a-secret-as-container-environment-variables) - envFrom: [] - - # -- Optional VolumeMounts mapped into each scanJob (see: https://kubernetes.io/docs/concepts/storage/volumes/) - extraVolumeMounts: - - name: zap-scripts-authentication - mountPath: /home/zap/.ZAP_D/scripts/scripts/authentication/ - readOnly: true - - name: zap-scripts-session - mountPath: /home/zap/.ZAP_D/scripts/scripts/session/ - readOnly: true - - # scanner.securityContext -- Optional securityContext set on scanner container (see: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) - securityContext: - # scanner.securityContext.runAsNonRoot -- Enforces that the scanner image is run as a non root user - runAsNonRoot: false - # scanner.securityContext.readOnlyRootFilesystem -- Prevents write access to the containers file system - readOnlyRootFilesystem: false - # scanner.securityContext.allowPrivilegeEscalation -- Ensure that users privileges cannot be escalated - allowPrivilegeEscalation: false - # scanner.securityContext.privileged -- Ensures that the scanner container is not run in privileged mode - privileged: false - capabilities: - drop: - # scanner.securityContext.capabilities.drop[0] -- This drops all linux privileges from the container. - - all - -# -- All `scanType` specific configuration options. Feel free to add more configuration options. All configuration options can be overridden by scan specific configurations if defined. Please have a look into the README.md to find more configuration options. -zapConfiguration: - {} - # # -- Optional general ZAP Configurations settings. - # global: - # # -- The ZAP internal Session name. Default: secureCodeBox - # sessionName: secureCodeBox - # # -- Updates all installed ZAP AddOns on startup if true, otherwise false. - # addonUpdate: true - # # -- Installs additional ZAP AddOns on startup, listed by their name: - # addonInstall: - # - pscanrulesBeta - # - ascanrulesBeta - # - pscanrulesAlpha - # - ascanrulesAlpha - -cascadingRules: - # cascadingRules.enabled -- Enables or disables the installation of the default cascading rules for this scanner - enabled: false diff --git a/scanners/zap-automation-framework/cascading-rules/http.yaml b/scanners/zap-automation-framework/cascading-rules/http.yaml index 0251dfccbf..098838a3ac 100644 --- a/scanners/zap-automation-framework/cascading-rules/http.yaml +++ b/scanners/zap-automation-framework/cascading-rules/http.yaml @@ -22,4 +22,17 @@ spec: state: open scanSpec: scanType: "zap-automation-framework" - parameters: ["-t", "http://{{$.hostOrIP}}:{{attributes.port}}"] + parameters: + - "-autorun" + - "/home/securecodebox/scb-automation/automation.yaml" + volumeMounts: + - name: zap-automation-framework-baseline-config + mountPath: /home/securecodebox/scb-automation/automation.yaml + subPath: automation.yaml + volumes: + - name: zap-automation-framework-baseline-config + configMap: + name: zap-automation-framework-baseline-config + env: + - name: TARGET_URL + value: "http://{{$.hostOrIP}}:{{attributes.port}}" diff --git a/scanners/zap-automation-framework/cascading-rules/https.yaml b/scanners/zap-automation-framework/cascading-rules/https.yaml index 9711e50741..a273da2dfd 100644 --- a/scanners/zap-automation-framework/cascading-rules/https.yaml +++ b/scanners/zap-automation-framework/cascading-rules/https.yaml @@ -18,4 +18,17 @@ spec: state: open scanSpec: scanType: "zap-automation-framework" - parameters: ["-t", "https://{{$.hostOrIP}}:{{attributes.port}}"] + parameters: + - "-autorun" + - "/home/securecodebox/scb-automation/automation.yaml" + volumeMounts: + - name: zap-automation-framework-baseline-config + mountPath: /home/securecodebox/scb-automation/automation.yaml + subPath: automation.yaml + volumes: + - name: zap-automation-framework-baseline-config + configMap: + name: zap-automation-framework-baseline-config + env: + - name: TARGET_URL + value: "https://{{$.hostOrIP}}:{{attributes.port}}" diff --git a/scanners/zap-automation-framework/examples/demo-zap-baseline-scan/scan.yaml b/scanners/zap-automation-framework/examples/demo-zap-baseline-scan/scan.yaml index 628b5dfed8..41517f5656 100644 --- a/scanners/zap-automation-framework/examples/demo-zap-baseline-scan/scan.yaml +++ b/scanners/zap-automation-framework/examples/demo-zap-baseline-scan/scan.yaml @@ -17,7 +17,7 @@ data: jobs: - type: spider # The traditional spider - fast but doesnt handle modern apps so well parameters: - context: zap-baseline-automation-scan # String: Name of the context to spider, default: first context + context: baseline-config # String: Name of the context to spider, default: first context maxDuration: 1 # Int: The max time in minutes the spider will be allowed to run for, default: 0 unlimited - type: passiveScan-wait # Passive scan wait for the passive scanner to finish parameters: diff --git a/scanners/zap-automation-framework/tests/__snapshot__/scanner_test.yaml.snap b/scanners/zap-automation-framework/tests/__snapshot__/scanner_test.yaml.snap index 30e6519eb9..0b40b866dd 100644 --- a/scanners/zap-automation-framework/tests/__snapshot__/scanner_test.yaml.snap +++ b/scanners/zap-automation-framework/tests/__snapshot__/scanner_test.yaml.snap @@ -48,10 +48,21 @@ matches the snapshot: state: open category: Open Port scanSpec: + env: + - name: TARGET_URL + value: http://{{$.hostOrIP}}:{{attributes.port}} parameters: - - -t - - http://{{$.hostOrIP}}:{{attributes.port}} + - -autorun + - /home/securecodebox/scb-automation/automation.yaml scanType: zap-automation-framework + volumeMounts: + - mountPath: /home/securecodebox/scb-automation/automation.yaml + name: zap-automation-framework-baseline-config + subPath: automation.yaml + volumes: + - configMap: + name: zap-automation-framework-baseline-config + name: zap-automation-framework-baseline-config 3: | apiVersion: cascading.securecodebox.io/v1 kind: CascadingRule @@ -68,10 +79,21 @@ matches the snapshot: state: open category: Open Port scanSpec: + env: + - name: TARGET_URL + value: https://{{$.hostOrIP}}:{{attributes.port}} parameters: - - -t - - https://{{$.hostOrIP}}:{{attributes.port}} + - -autorun + - /home/securecodebox/scb-automation/automation.yaml scanType: zap-automation-framework + volumeMounts: + - mountPath: /home/securecodebox/scb-automation/automation.yaml + name: zap-automation-framework-baseline-config + subPath: automation.yaml + volumes: + - configMap: + name: zap-automation-framework-baseline-config + name: zap-automation-framework-baseline-config 4: | apiVersion: v1 data: diff --git a/scanners/zap/.gitignore b/scanners/zap/.gitignore deleted file mode 100644 index a5be59dc8d..0000000000 --- a/scanners/zap/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -*.tar diff --git a/scanners/zap/.helm-docs.gotmpl b/scanners/zap/.helm-docs.gotmpl deleted file mode 100644 index b28bc3dc64..0000000000 --- a/scanners/zap/.helm-docs.gotmpl +++ /dev/null @@ -1,255 +0,0 @@ -{{- /* -SPDX-FileCopyrightText: the secureCodeBox authors - -SPDX-License-Identifier: Apache-2.0 -*/ -}} - -{{- define "extra.docsSection" -}} ---- -title: "ZAP" -category: "scanner" -type: "WebApplication" -state: "released" -appVersion: "{{ template "chart.appVersion" . }}" -usecase: "WebApp & OpenAPI Vulnerability Scanner" ---- - -![zap logo](https://raw.githubusercontent.com/wiki/zaproxy/zaproxy/images/zap32x32.png) - -{{- end }} - -{{- define "extra.dockerDeploymentSection" -}} -## Supported Tags -- `latest` (represents the latest stable release build) -- tagged releases, e.g. `3.0.0`, `2.9.0`, `2.8.0`, `2.7.0` -{{- end }} - -{{- define "extra.chartAboutSection" -}} -## What is ZAP? - -:::caution Deprecation Notice -The `zap-advanced` and `zap` ScanType are being deprecated in favor of the `zap-automation-framework`, which encompasses all functionalities of the previous ScanTypes. We recommend transitioning to "zap-automation-framework". This change will take effect in the upcoming release cycle. For guidance on migrating to "zap-automation-framework," please refer to [here](/docs/scanners/zap-automation-framework#migration-to-zap-automation-framework). -::: - -The Zed Attack Proxy (ZAP) is one of the world’s most popular free security tools and is actively maintained by hundreds of international volunteers*. It can help you automatically find security vulnerabilities in your web applications while you are developing and testing your applications. It's also a great tool for experienced pentesters to use for manual security testing. - -To learn more about the ZAP scanner itself visit [https://www.zaproxy.org/](https://www.zaproxy.org/). -To learn more about the ZAP Automation Framework itself visit [https://www.zaproxy.org/docs/desktop/addons/automation-framework/](https://www.zaproxy.org/docs/desktop/addons/automation-framework/). -{{- end }} - -{{- define "extra.scannerConfigurationSection" -}} -## Scanner Configuration - -The following security scan configuration example are based on the ZAP Docker Scan Scripts. By default, the secureCodeBox ZAP Helm Chart installs all four ZAP scripts: `zap-baseline`, `zap-full-scan` , `zap-api-scan` & `zap-automation-scan`. Listed below are the arguments supported by the `zap-baseline` script, which are mostly interchangeable with the other ZAP scripts (except for `zap-automation-scan`). For a more complete reference check out the [ZAP Documentation](https://www.zaproxy.org/docs/docker/) and the secureCodeBox based ZAP examples listed below. - -The command line interface can be used to easily run server scans: `-t www.example.com` - -```bash -Usage: zap-baseline.py -t [options] - -t target target URL including the protocol, eg https://www.example.com -Options: - -h print this help message - -c config_file config file to use to INFO, IGNORE or FAIL warnings - -u config_url URL of config file to use to INFO, IGNORE or FAIL warnings - -g gen_file generate default config file (all rules set to WARN) - -m mins the number of minutes to spider for (default 1) - -r report_html file to write the full ZAP HTML report - -w report_md file to write the full ZAP Wiki (Markdown) report - -x report_xml file to write the full ZAP XML report - -J report_json file to write the full ZAP JSON document - -a include the alpha passive scan rules as well - -d show debug messages - -P specify listen port - -D delay in seconds to wait for passive scanning - -i default rules not in the config file to INFO - -I do not return failure on warning - -j use the Ajax spider in addition to the traditional one - -l level minimum level to show: PASS, IGNORE, INFO, WARN or FAIL, use with -s to hide example URLs - -n context_file context file which will be loaded prior to spidering the target - -p progress_file progress file which specifies issues that are being addressed - -s short output format - dont show PASSes or example URLs - -T max time in minutes to wait for ZAP to start and the passive scan to run - -z zap_options ZAP command line options e.g. -z "-config aaa=bbb -config ccc=ddd" - --hook path to python file that define your custom hooks -``` - -## ZAP Automation Scanner Configuration - -The Automation Framework allows for higher flexibility in configuring ZAP scans. Its goal is the automation of the full functionality of ZAP's GUI. The configuration of the Automation Framework differs from the other three ZAP scan types. The following security scan configuration example highlights the differences for running a `zap-automation-scan`. -Of particular interest for us will be the -autorun option. `zap-automation-scan` allows for providing an automation file as a ConfigMap that defines the details of the scan. See the secureCodeBox based ZAP Automation example listed below for what such a ConfigMap would look like. - -```bash -Usage: zap.sh -cmd -host [options] - -t target target URL including the protocol, eg https://www.example.com -Add-on options: - -script ", - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/websocket/drawboard.xhtml", - "method": "GET", - "evidence": "", - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/websocket/snake.xhtml", - "method": "GET", - "evidence": "", - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/websocket/chat.xhtml", - "method": "GET", - "evidence": "", - }, - ], - }, - "id": "d6dc3899-b3fc-46cd-b544-590badef18fc", - }, - { - "name": "Weak Authentication Method", - "description": "HTTP basic or digest authentication has been used over an unsecured connection. The credentials can be read and then reused by someone with access to the network.", - "category": "Weak Authentication Method", - "location": "http://bodgeit.demo-targets.svc:8080", - "osi_layer": "APPLICATION", - "severity": "MEDIUM", - "attributes": - { - "hostname": "bodgeit.demo-targets.svc", - "zap_confidence": "2", - "zap_count": "3", - "zap_solution": "Protect the connection using HTTPS or use a stronger authentication mechanism", - "zap_otherinfo": null, - "zap_reference": "https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html", - "zap_cweid": "326", - "zap_wascid": "4", - "zap_riskcode": "2", - "zap_pluginid": "10105", - "zap_finding_urls": - [ - { - "uri": "http://bodgeit.demo-targets.svc:8080/manager/html", - "method": "GET", - "evidence": 'WWW-Authenticate: Basic realm="Tomcat Manager Application"', - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/manager/status", - "method": "GET", - "evidence": 'WWW-Authenticate: Basic realm="Tomcat Manager Application"', - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/host-manager/html", - "method": "GET", - "evidence": 'WWW-Authenticate: Basic realm="Tomcat Host Manager Application"', - }, - ], - }, - "id": "ed7e142a-ea90-4cff-9bfa-214eb99fdf91", - }, - { - "name": "Content-Type Header Missing", - "description": "The Content-Type header was either missing or empty.", - "category": "Content-Type Header Missing", - "location": "http://bodgeit.demo-targets.svc:8080", - "osi_layer": "APPLICATION", - "severity": "INFORMATIONAL", - "attributes": - { - "hostname": "bodgeit.demo-targets.svc", - "zap_confidence": "2", - "zap_count": "2", - "zap_solution": "Ensure each page is setting the specific and appropriate content-type value for the content being delivered.", - "zap_otherinfo": null, - "zap_reference": "http://msdn.microsoft.com/en-us/library/ie/gg622941%28v=vs.85%29.aspx", - "zap_cweid": "345", - "zap_wascid": "12", - "zap_riskcode": "0", - "zap_pluginid": "10019", - "zap_finding_urls": - [ - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/appdev/sample/sample.war", - "method": "GET", - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/async/async2", - "method": "GET", - }, - ], - }, - "id": "e56b88b8-68cd-4b11-b826-208126850a87", - }, - { - "name": "Cookie Without SameSite Attribute", - "description": "A cookie has been set without the SameSite attribute, which means that the cookie can be sent as a result of a 'cross-site' request. The SameSite attribute is an effective counter measure to cross-site request forgery, cross-site script inclusion, and timing attacks.", - "category": "Cookie Without SameSite Attribute", - "location": "http://bodgeit.demo-targets.svc:8080", - "osi_layer": "APPLICATION", - "severity": "LOW", - "attributes": - { - "hostname": "bodgeit.demo-targets.svc", - "zap_confidence": "2", - "zap_count": "4", - "zap_solution": "Ensure that the SameSite attribute is set to either 'lax' or ideally 'strict' for all cookies.", - "zap_otherinfo": null, - "zap_reference": "https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site", - "zap_cweid": "16", - "zap_wascid": "13", - "zap_riskcode": "1", - "zap_pluginid": "10054", - "zap_finding_urls": - [ - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/security/protected/index.jsp", - "method": "GET", - "param": "JSESSIONID", - "evidence": "Set-Cookie: JSESSIONID", - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/el/basic-arithmetic.jsp", - "method": "GET", - "param": "JSESSIONID", - "evidence": "Set-Cookie: JSESSIONID", - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/el/basic-comparisons.jsp", - "method": "GET", - "param": "JSESSIONID", - "evidence": "Set-Cookie: JSESSIONID", - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/servlets/servlet/CookieExample", - "method": "POST", - "param": "ZAP", - "evidence": "Set-Cookie: ZAP", - }, - ], - }, - "id": "fcbdde04-17da-482c-9c68-e9a3b8cdf1fb", - }, - { - "name": "Cookie Poisoning", - "description": "This check looks at user-supplied input in query string parameters and POST data to identify where cookie parameters might be controlled. This is called a cookie poisoning attack, and becomes exploitable when an attacker can manipulate the cookie in various ways. In some cases this will not be exploitable, however, allowing URL parameters to set cookie values is generally considered a bug.", - "category": "Cookie Poisoning", - "location": "http://bodgeit.demo-targets.svc:8080", - "osi_layer": "APPLICATION", - "severity": "INFORMATIONAL", - "attributes": - { - "hostname": "bodgeit.demo-targets.svc", - "zap_confidence": "1", - "zap_count": "2", - "zap_solution": "Do not allow user input to control cookie names and values. If some query string parameters must be set in cookie values, be sure to filter out semicolon's that can serve as name/value pair delimiters.", - "zap_otherinfo": "An attacker may be able to poison cookie values through POST parameters. To test if this is a more serious issue, you should try resending that request as a GET, with the POST parameter included as a query string parameter. For example: http://nottrusted.com/page?value=maliciousInput.This was identified at:http://bodgeit.demo-targets.svc:8080/examples/servlets/servlet/CookieExampleUser-input was found in the following cookie:ZAP=ZAP; Path=/examples/The user input was:cookievalue=ZAP", - "zap_reference": "http://websecuritytool.codeplex.com/wikipage?title=Checks#user-controlled-cookie", - "zap_cweid": "20", - "zap_wascid": "20", - "zap_riskcode": "0", - "zap_pluginid": "10029", - "zap_finding_urls": - [ - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/servlets/servlet/CookieExample", - "method": "POST", - "param": "cookievalue", - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/servlets/servlet/CookieExample", - "method": "POST", - "param": "cookiename", - }, - ], - }, - "id": "f548884e-276e-4631-a32d-1ee3a803e031", - }, - { - "name": "Information Disclosure - Suspicious Comments", - "description": "The response appears to contain suspicious comments which may help an attacker. Note: Matches made within script blocks or files are against the entire content not only comments.", - "category": "Information Disclosure - Suspicious Comments", - "location": "http://bodgeit.demo-targets.svc:8080", - "osi_layer": "APPLICATION", - "severity": "INFORMATIONAL", - "attributes": - { - "hostname": "bodgeit.demo-targets.svc", - "zap_confidence": "1", - "zap_count": "5", - "zap_solution": "Remove all comments that return information that may help an attacker and fix any underlying problems they refer to.", - "zap_otherinfo": "The following comment/snippet was identified via the pattern: \\bADMIN\\b \"use strict\"; // Enable strict mode (function() { var thisScript = document.currentScript; if (!thisScript) { // Workaround for IE var scripts = document.getElementsByTagName(\"script\"); thisScript = scripts[scripts.length - 1]; } document.addEventListener(\"DOMContentLoaded\", (function() { var commentsDiv = document.getElementById(\"comments_thread\"); var commentsShortname = \"tomcat\"; var commentsIdentifier = \"http://tomcat.apache.org/\" + thisScript.getAttribute(\"data-comments-identifier\") + \".html\"; (function(w, d) { if (w.location.hostname.toLowerCase() == \"tomcat.apache.org\") { var s = d.createElement(\"script\"); s.type = \"application/javascript\"; s.async = true; s.src = \"https://comments.apache.org/show_comments.lua?site=\" + encodeURIComponent(commentsShortname) + \"&page=\" + encodeURIComponent(commentsIdentifier); d.head.appendChild(s); } else { commentsDiv.appendChild(d.createTextNode(\"Comments are disabled for this page at the moment.\")); } })(window, document); }), false); })(); ", - "zap_reference": null, - "zap_cweid": "200", - "zap_wascid": "13", - "zap_riskcode": "0", - "zap_pluginid": "10027", - "zap_finding_urls": - [ - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/funcspecs/fs-admin-opers.html", - "method": "GET", - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/websocket/drawboard.xhtml", - "method": "GET", - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/funcspecs/fs-admin-objects.html", - "method": "GET", - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/websocket/echo.xhtml", - "method": "GET", - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/funcspecs/fs-admin-apps.html", - "method": "GET", - }, - ], - }, - "id": "3d9212bf-54d8-4be4-8c47-18c7f006dee7", - }, - { - "name": "Cookie No HttpOnly Flag", - "description": "A cookie has been set without the HttpOnly flag, which means that the cookie can be accessed by JavaScript. If a malicious script can be run on this page then the cookie will be accessible and can be transmitted to another site. If this is a session cookie then session hijacking may be possible.", - "category": "Cookie No HttpOnly Flag", - "location": "http://bodgeit.demo-targets.svc:8080", - "osi_layer": "APPLICATION", - "severity": "LOW", - "attributes": - { - "hostname": "bodgeit.demo-targets.svc", - "zap_confidence": "2", - "zap_count": "1", - "zap_solution": "Ensure that the HttpOnly flag is set for all cookies.", - "zap_otherinfo": null, - "zap_reference": "https://owasp.org/www-community/HttpOnly", - "zap_cweid": "16", - "zap_wascid": "13", - "zap_riskcode": "1", - "zap_pluginid": "10010", - "zap_finding_urls": - [ - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/servlets/servlet/CookieExample", - "method": "POST", - "param": "ZAP", - "evidence": "Set-Cookie: ZAP", - }, - ], - }, - "id": "7854eea8-b291-4273-ab3a-4ada6ba472f2", - }, - { - "name": "Information Disclosure - Suspicious Comments", - "description": "The response appears to contain suspicious comments which may help an attacker. Note: Matches made within script blocks or files are against the entire content not only comments.", - "category": "Information Disclosure - Suspicious Comments", - "location": "http://bodgeit.demo-targets.svc:8080", - "osi_layer": "APPLICATION", - "severity": "INFORMATIONAL", - "attributes": - { - "hostname": "bodgeit.demo-targets.svc", - "zap_confidence": "2", - "zap_count": "2", - "zap_solution": "Remove all comments that return information that may help an attacker and fix any underlying problems they refer to.", - "zap_otherinfo": "The following comment/snippet was identified via the pattern: \\bADMINISTRATOR\\b String constants used within your application, which can be customized by the system administrator who is installing your application. The values actually assigned to these parameters can be retrieved in a servlet or JSP page by calling: String value = getServletContext().getInitParameter(\"name\"); where \"name\" matches the element of one of these initialization parameters. You can define any number of context initialization parameters, including zero. -->The following comment/snippet was identified via the pattern: \\bWHERE\\b your web application, including initialization parameters. With Tomcat, you can also send requests to servlets not listed here with a request like this: http://localhost:8080/{context-path}/servlet/{classname} but this usage is not guaranteed to be portable. It also makes relative references to images and other resources required by your servlet more complicated, so defining all of your servlets (and defining a mapping to them with a servlet-mapping element) is recommended. Servlet initialization parameters can be retrieved in a servlet or JSP page by calling: String value = getServletConfig().getInitParameter(\"name\"); where \"name\" matches the element of one of these initialization parameters. You can define any number of servlets, including zero. -->The following comment/snippet was identified via the pattern: \\bFROM\\b in minutes. From a servlet or JSP page, you can modify the timeout for a particular session dynamically by using HttpSession.getMaxInactiveInterval(). -->", - "zap_reference": null, - "zap_cweid": "200", - "zap_wascid": "13", - "zap_riskcode": "0", - "zap_pluginid": "10027", - "zap_finding_urls": - [ - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/appdev/web.xml.txt", - "method": "GET", - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/appdev/build.xml.txt", - "method": "GET", - }, - ], - }, - "id": "dbf95dc8-8a08-43a6-86c7-e34e892410d4", - }, - { - "name": "Application Error Disclosure", - "description": "This page contains an error/warning message that may disclose sensitive information like the location of the file that produced the unhandled exception. This information can be used to launch further attacks against the web application. The alert could be a false positive if the error message is found inside a documentation page.", - "category": "Application Error Disclosure", - "location": "http://bodgeit.demo-targets.svc:8080", - "osi_layer": "APPLICATION", - "severity": "LOW", - "attributes": - { - "hostname": "bodgeit.demo-targets.svc", - "zap_confidence": "2", - "zap_count": "1", - "zap_solution": "Review the source code of this page. Implement custom error pages. Consider implementing a mechanism to provide a unique error reference/identifier to the client (browser) while logging the details on the server side and not exposing them to the user.", - "zap_otherinfo": null, - "zap_reference": null, - "zap_cweid": "200", - "zap_wascid": "13", - "zap_riskcode": "1", - "zap_pluginid": "90022", - "zap_finding_urls": - [ - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/error/err.jsp?name=bmw328i&submit=Submit", - "method": "GET", - "evidence": "HTTP/1.1 500 Internal Server Error", - }, - ], - }, - "id": "bfe66cec-6da6-474c-933e-683c2c9fffbf", - }, - { - "name": "Information Disclosure - Debug Error Messages", - "description": "The response appeared to contain common error messages returned by platforms such as ASP.NET, and Web-servers such as IIS and Apache. You can configure the list of common debug messages.", - "category": "Information Disclosure - Debug Error Messages", - "location": "http://bodgeit.demo-targets.svc:8080", - "osi_layer": "APPLICATION", - "severity": "LOW", - "attributes": - { - "hostname": "bodgeit.demo-targets.svc", - "zap_confidence": "2", - "zap_count": "1", - "zap_solution": "Disable debugging messages before pushing to production.", - "zap_otherinfo": null, - "zap_reference": null, - "zap_cweid": "200", - "zap_wascid": "13", - "zap_riskcode": "1", - "zap_pluginid": "10023", - "zap_finding_urls": - [ - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/changelog.html", - "method": "GET", - "evidence": "internal server error", - }, - ], - }, - "id": "325de9a9-63f3-4ec1-a6aa-fd0e1eeae7c4", - }, -] diff --git a/scanners/zap/examples/demo-bodgeit-baseline-scan/scan.yaml b/scanners/zap/examples/demo-bodgeit-baseline-scan/scan.yaml deleted file mode 100644 index 8f1b39a18e..0000000000 --- a/scanners/zap/examples/demo-bodgeit-baseline-scan/scan.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -apiVersion: "execution.securecodebox.io/v1" -kind: Scan -metadata: - name: "zap-baseline-scan-bodgeit" -spec: - scanType: "zap-baseline-scan" - parameters: - # target URL including the protocol - - "-t" - - "http://bodgeit.demo-targets.svc:8080" - # show debug messages - - "-d" - # the number of minutes to spider for (default 1) - - "-m" - - "2" diff --git a/scanners/zap/examples/demo-bodgeit-baseline-scan/zap-results.json b/scanners/zap/examples/demo-bodgeit-baseline-scan/zap-results.json deleted file mode 100644 index 8b870b1a47..0000000000 --- a/scanners/zap/examples/demo-bodgeit-baseline-scan/zap-results.json +++ /dev/null @@ -1,1240 +0,0 @@ -{ - "@version": "2.9.0", - "@generated": "Sun, 28 Jun 2020 18:22:42", - "site": [ - { - "@name": "http://bodgeit.demo-targets.svc:8080", - "@host": "bodgeit.demo-targets.svc", - "@port": "8080", - "@ssl": "false", - "alerts": [ - { - "pluginid": "10038", - "alert": "Content Security Policy (CSP) Header Not Set", - "name": "Content Security Policy (CSP) Header Not Set", - "riskcode": "1", - "confidence": "2", - "riskdesc": "Low (Medium)", - "desc": "

Content Security Policy (CSP) is an added layer of security that helps to detect and mitigate certain types of attacks, including Cross Site Scripting (XSS) and data injection attacks. These attacks are used for everything from data theft to site defacement or distribution of malware. CSP provides a set of standard HTTP headers that allow website owners to declare approved sources of content that browsers should be allowed to load on that page — covered types are JavaScript, CSS, HTML frames, fonts, images and embeddable objects such as Java applets, ActiveX, audio and video files.<\/p>", - "instances": [ - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/tagplugin/choose.html", - "method": "GET" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/valve.html", - "method": "GET" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/tagfiles/panel.jsp.html", - "method": "GET" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/loader.html", - "method": "GET" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/connectors.html", - "method": "GET" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/simpletag/HelloWorldSimpleTag.java.html", - "method": "GET" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/apr.html", - "method": "GET" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/appdev/introduction.html", - "method": "GET" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/listeners.html", - "method": "GET" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/servlets/servlet/SessionExample", - "method": "POST" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/class-loader-howto.html", - "method": "GET" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/servlets/servlet/RequestParamExample", - "method": "POST" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/jspx/textRotate.jspx.html", - "method": "GET" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/servlets/helloworld.html", - "method": "GET" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/sessions/carts.html", - "method": "GET" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/security-howto.html", - "method": "GET" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/jasper-howto.html", - "method": "GET" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/misc/config.jsp.html", - "method": "GET" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/cluster-interceptor.html", - "method": "GET" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/index.html", - "method": "GET" - } - ], - "count": "298", - "solution": "

Ensure that your web server, application server, load balancer, etc. is configured to set the Content-Security-Policy header, to achieve optimal browser support: \"Content-Security-Policy\" for Chrome 25+, Firefox 23+ and Safari 7+, \"X-Content-Security-Policy\" for Firefox 4.0+ and Internet Explorer 10+, and \"X-WebKit-CSP\" for Chrome 14+ and Safari 6+.<\/p>", - "reference": "

https://developer.mozilla.org/en-US/docs/Web/Security/CSP/Introducing_Content_Security_Policy<\/p>

https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html<\/p>

http://www.w3.org/TR/CSP/<\/p>

http://w3c.github.io/webappsec/specs/content-security-policy/csp-specification.dev.html<\/p>

http://www.html5rocks.com/en/tutorials/security/content-security-policy/<\/p>

http://caniuse.com/#feat=contentsecuritypolicy<\/p>

http://content-security-policy.com/<\/p>", - "cweid": "16", - "wascid": "15", - "sourceid": "3" - }, - { - "pluginid": "10020", - "alert": "X-Frame-Options Header Not Set", - "name": "X-Frame-Options Header Not Set", - "riskcode": "2", - "confidence": "2", - "riskdesc": "Medium (Medium)", - "desc": "

X-Frame-Options header is not included in the HTTP response to protect against 'ClickJacking' attacks.<\/p>", - "instances": [ - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/rewrite.html", - "method": "GET", - "param": "X-Frame-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/funcspecs/mbean-names.html", - "method": "GET", - "param": "X-Frame-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/tribes/faq.html", - "method": "GET", - "param": "X-Frame-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/include/include.jsp.html", - "method": "GET", - "param": "X-Frame-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/cluster.html", - "method": "GET", - "param": "X-Frame-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/automatic-deployment.html", - "method": "GET", - "param": "X-Frame-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/colors/colors.html", - "method": "GET", - "param": "X-Frame-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/tagfiles/hello.jsp", - "method": "GET", - "param": "X-Frame-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/jspattribute/shuffle.jsp.html", - "method": "GET", - "param": "X-Frame-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/websocket/index.xhtml", - "method": "GET", - "param": "X-Frame-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/cluster-howto.html", - "method": "GET", - "param": "X-Frame-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/websocket/echo.xhtml", - "method": "GET", - "param": "X-Frame-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsptoserv/jts.html", - "method": "GET", - "param": "X-Frame-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/simpletag/foo.html", - "method": "GET", - "param": "X-Frame-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/el/Functions.java.html", - "method": "GET", - "param": "X-Frame-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/tagplugin/choose.jsp", - "method": "GET", - "param": "X-Frame-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/tribes/interceptors.html", - "method": "GET", - "param": "X-Frame-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/funcspecs/fs-jndi-realm.html", - "method": "GET", - "param": "X-Frame-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/dates/date.html", - "method": "GET", - "param": "X-Frame-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/servlets/servlet/RequestHeaderExample", - "method": "GET", - "param": "X-Frame-Options" - } - ], - "count": "280", - "solution": "

Most modern Web browsers support the X-Frame-Options HTTP header. Ensure it's set on all web pages returned by your site (if you expect the page to be framed only by pages on your server (e.g. it's part of a FRAMESET) then you'll want to use SAMEORIGIN, otherwise if you never expect the page to be framed, you should use DENY. ALLOW-FROM allows specific websites to frame the web page in supported web browsers).<\/p>", - "reference": "

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options<\/p>", - "cweid": "16", - "wascid": "15", - "sourceid": "3" - }, - { - "pluginid": "10036", - "alert": "Server Leaks Version Information via \"Server\" HTTP Response Header Field", - "name": "Server Leaks Version Information via \"Server\" HTTP Response Header Field", - "riskcode": "1", - "confidence": "3", - "riskdesc": "Low (High)", - "desc": "

The web/application server is leaking version information via the \"Server\" HTTP response header. Access to such information may facilitate attackers identifying other vulnerabilities your web/application server is subject to.<\/p>", - "instances": [ - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/filter.html", - "method": "GET", - "evidence": "Apache-Coyote/1.1" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/num/numguess.jsp.html", - "method": "GET", - "evidence": "Apache-Coyote/1.1" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/el/implicit-objects.html", - "method": "GET", - "evidence": "Apache-Coyote/1.1" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/cal/cal2.jsp.html", - "method": "GET", - "evidence": "Apache-Coyote/1.1" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/appdev/index.html", - "method": "GET", - "evidence": "Apache-Coyote/1.1" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/simpletag/hello.html", - "method": "GET", - "evidence": "Apache-Coyote/1.1" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/simpletag/book.jsp.html", - "method": "GET", - "evidence": "Apache-Coyote/1.1" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/el/basic-comparisons.jsp.html", - "method": "GET", - "evidence": "Apache-Coyote/1.1" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/http.html", - "method": "GET", - "evidence": "Apache-Coyote/1.1" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/tribes/developers.html", - "method": "GET", - "evidence": "Apache-Coyote/1.1" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/maven-jars.html", - "method": "GET", - "evidence": "Apache-Coyote/1.1" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/service.html", - "method": "GET", - "evidence": "Apache-Coyote/1.1" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/mbeans-descriptors-howto.html", - "method": "GET", - "evidence": "Apache-Coyote/1.1" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/websocket/chat.xhtml", - "method": "GET", - "evidence": "Apache-Coyote/1.1" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/api/org/apache/catalina/Host.html", - "method": "GET", - "evidence": "Apache-Coyote/1.1" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/snp/snoop.jsp.html", - "method": "GET", - "evidence": "Apache-Coyote/1.1" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/el/functions.jsp.html", - "method": "GET", - "evidence": "Apache-Coyote/1.1" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/jspattribute/shuffle.html", - "method": "GET", - "evidence": "Apache-Coyote/1.1" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/tagplugin/foreach.jsp", - "method": "GET", - "evidence": "Apache-Coyote/1.1" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/funcspecs/fs-admin-objects.html", - "method": "GET", - "evidence": "Apache-Coyote/1.1" - } - ], - "count": "337", - "solution": "

Ensure that your web server, application server, load balancer, etc. is configured to suppress the \"Server\" header or provide generic details.<\/p>", - "reference": "

http://httpd.apache.org/docs/current/mod/core.html#servertokens<\/p>

http://msdn.microsoft.com/en-us/library/ff648552.aspx#ht_urlscan_007<\/p>

http://blogs.msdn.com/b/varunm/archive/2013/04/23/remove-unwanted-http-response-headers.aspx<\/p>

http://www.troyhunt.com/2012/02/shhh-dont-let-your-response-headers.html<\/p>", - "cweid": "200", - "wascid": "13", - "sourceid": "3" - }, - { - "pluginid": "10096", - "alert": "Timestamp Disclosure - Unix", - "name": "Timestamp Disclosure - Unix", - "riskcode": "0", - "confidence": "1", - "riskdesc": "Informational (Low)", - "desc": "

A timestamp was disclosed by the application/web server - Unix<\/p>", - "instances": [ - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/architecture/startup/serverStartup.pdf", - "method": "GET", - "evidence": "0000000039" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/architecture/startup/serverStartup.pdf", - "method": "GET", - "evidence": "0000000008" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/architecture/startup/serverStartup.pdf", - "method": "GET", - "evidence": "0000014963" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/architecture/startup/serverStartup.pdf", - "method": "GET", - "evidence": "0000018373" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/snp/snoop.jsp", - "method": "GET", - "evidence": "20100101" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/architecture/startup/serverStartup.pdf", - "method": "GET", - "evidence": "0000000018" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/architecture/startup/serverStartup.pdf", - "method": "GET", - "evidence": "0000005503" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/architecture/startup/serverStartup.pdf", - "method": "GET", - "evidence": "0000000026" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/architecture/startup/serverStartup.pdf", - "method": "GET", - "evidence": "0000015294" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/architecture/startup/serverStartup.pdf", - "method": "GET", - "evidence": "0000016347" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/architecture/startup/serverStartup.pdf", - "method": "GET", - "evidence": "0000002280" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/architecture/startup/serverStartup.pdf", - "method": "GET", - "evidence": "0000043589" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/architecture/startup/serverStartup.pdf", - "method": "GET", - "evidence": "0000015448" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/architecture/startup/serverStartup.pdf", - "method": "GET", - "evidence": "0000007734" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/architecture/startup/serverStartup.pdf", - "method": "GET", - "evidence": "0000010013" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/manager-howto.html", - "method": "GET", - "evidence": "46800300" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/architecture/startup/serverStartup.pdf", - "method": "GET", - "evidence": "0000005214" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/architecture/startup/serverStartup.pdf", - "method": "GET", - "evidence": "0000043442" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/architecture/startup/serverStartup.pdf", - "method": "GET", - "evidence": "0000005368" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/architecture/startup/serverStartup.pdf", - "method": "GET", - "evidence": "0000000301" - } - ], - "count": "51", - "solution": "

Manually confirm that the timestamp data is not sensitive, and that the data cannot be aggregated to disclose exploitable patterns.<\/p>", - "otherinfo": "

0000000039, which evaluates to: 1970-01-01 00:00:39<\/p>", - "reference": "

http://projects.webappsec.org/w/page/13246936/Information%20Leakage<\/p>", - "cweid": "200", - "wascid": "13", - "sourceid": "3" - }, - { - "pluginid": "10108", - "alert": "Reverse Tabnabbing", - "name": "Reverse Tabnabbing", - "riskcode": "2", - "confidence": "2", - "riskdesc": "Medium (Medium)", - "desc": "

At least one link on this page is vulnerable to Reverse tabnabbing as it uses a target attribute without using both of the \"noopener\" and \"noreferrer\" keywords in the \"rel\" attribute, which allows the target page to take control of this page.<\/p>", - "instances": [ - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/class-loader-howto.html", - "method": "GET", - "evidence": "\"The<\/a>" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/virtual-hosting-howto.html", - "method": "GET", - "evidence": "\"The<\/a>" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/cluster-valve.html", - "method": "GET", - "evidence": "\"The<\/a>" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/windows-service-howto.html", - "method": "GET", - "evidence": "\"The<\/a>" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/cluster-manager.html", - "method": "GET", - "evidence": "\"The<\/a>" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/apr.html", - "method": "GET", - "evidence": "\"The<\/a>" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/connectors.html", - "method": "GET", - "evidence": "\"The<\/a>" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/security-howto.html", - "method": "GET", - "evidence": "\"The<\/a>" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/cluster-channel.html", - "method": "GET", - "evidence": "\"The<\/a>" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/jasper-howto.html", - "method": "GET", - "evidence": "\"The<\/a>" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/tribes/transport.html", - "method": "GET", - "evidence": "\"The<\/a>" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/tribes/status.html", - "method": "GET", - "evidence": "\"The<\/a>" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/appdev/processes.html", - "method": "GET", - "evidence": "\"The<\/a>" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/realm.html", - "method": "GET", - "evidence": "\"The<\/a>" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/funcspecs/index.html", - "method": "GET", - "evidence": "\"The<\/a>" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/building.html", - "method": "GET", - "evidence": "\"The<\/a>" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/tribes/introduction.html", - "method": "GET", - "evidence": "\"The<\/a>" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/systemprops.html", - "method": "GET", - "evidence": "\"The<\/a>" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/tribes/membership.html", - "method": "GET", - "evidence": "\"The<\/a>" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/cluster-deployer.html", - "method": "GET", - "evidence": "\"The<\/a>" - } - ], - "count": "102", - "solution": "

Do not use a target attribute, or if you have to then also add the attribute: rel=\"noopener noreferrer\".<\/p>", - "reference": "

https://owasp.org/www-community/attacks/Reverse_Tabnabbing<\/p>

https://dev.to/ben/the-targetblank-vulnerability-by-example<\/p>

https://mathiasbynens.github.io/rel-noopener/<\/p>

https://medium.com/@jitbit/target-blank-the-most-underestimated-vulnerability-ever-96e328301f4c<\/p>

<\/p>", - "sourceid": "3" - }, - { - "pluginid": "10021", - "alert": "X-Content-Type-Options Header Missing", - "name": "X-Content-Type-Options Header Missing", - "riskcode": "1", - "confidence": "2", - "riskdesc": "Low (Medium)", - "desc": "

The Anti-MIME-Sniffing header X-Content-Type-Options was not set to 'nosniff'. This allows older versions of Internet Explorer and Chrome to perform MIME-sniffing on the response body, potentially causing the response body to be interpreted and displayed as a content type other than the declared content type. Current (early 2014) and legacy versions of Firefox will use the declared content type (if one is set), rather than performing MIME-sniffing.<\/p>", - "instances": [ - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsptoserv/jts.html", - "method": "GET", - "param": "X-Content-Type-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/automatic-deployment.html", - "method": "GET", - "param": "X-Content-Type-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/funcspecs/mbean-names.html", - "method": "GET", - "param": "X-Content-Type-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/include/include.jsp.html", - "method": "GET", - "param": "X-Content-Type-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/rewrite.html", - "method": "GET", - "param": "X-Content-Type-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/cluster.html", - "method": "GET", - "param": "X-Content-Type-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/el/basic-arithmetic.jsp", - "method": "GET", - "param": "X-Content-Type-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/tomcat.png", - "method": "GET", - "param": "X-Content-Type-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/colors/colors.html", - "method": "GET", - "param": "X-Content-Type-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/images/asf-feather.png", - "method": "GET", - "param": "X-Content-Type-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/funcspecs/fs-admin-apps.html", - "method": "GET", - "param": "X-Content-Type-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/introduction.html", - "method": "GET", - "param": "X-Content-Type-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/tribes/faq.html", - "method": "GET", - "param": "X-Content-Type-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/servletapi/index.html", - "method": "GET", - "param": "X-Content-Type-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/misc/dynamicattrs.jsp.html", - "method": "GET", - "param": "X-Content-Type-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/building.html", - "method": "GET", - "param": "X-Content-Type-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/jspattribute/shuffle.jsp.html", - "method": "GET", - "param": "X-Content-Type-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/images/code.gif", - "method": "GET", - "param": "X-Content-Type-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/cluster-receiver.html", - "method": "GET", - "param": "X-Content-Type-Options" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/deployer-howto.html", - "method": "GET", - "param": "X-Content-Type-Options" - } - ], - "count": "316", - "solution": "

Ensure that the application/web server sets the Content-Type header appropriately, and that it sets the X-Content-Type-Options header to 'nosniff' for all web pages.<\/p>

If possible, ensure that the end user uses a standards-compliant and modern web browser that does not perform MIME-sniffing at all, or that can be directed by the web application/web server to not perform MIME-sniffing.<\/p>", - "otherinfo": "

This issue still applies to error type pages (401, 403, 500, etc.) as those pages are often still affected by injection issues, in which case there is still concern for browsers sniffing pages away from their actual content type.<\/p>

At \"High\" threshold this scanner will not alert on client or server error responses.<\/p>", - "reference": "

http://msdn.microsoft.com/en-us/library/ie/gg622941%28v=vs.85%29.aspx<\/p>

https://owasp.org/www-community/Security_Headers<\/p>", - "cweid": "16", - "wascid": "15", - "sourceid": "3" - }, - { - "pluginid": "10202", - "alert": "Absence of Anti-CSRF Tokens", - "name": "Absence of Anti-CSRF Tokens", - "riskcode": "1", - "confidence": "2", - "riskdesc": "Low (Medium)", - "desc": "

No Anti-CSRF tokens were found in a HTML submission form.<\/p>

A cross-site request forgery is an attack that involves forcing a victim to send an HTTP request to a target destination without their knowledge or intent in order to perform an action as the victim. The underlying cause is application functionality using predictable URL/form actions in a repeatable way. The nature of the attack is that CSRF exploits the trust that a web site has for a user. By contrast, cross-site scripting (XSS) exploits the trust that a user has for a web site. Like XSS, CSRF attacks are not necessarily cross-site, but they can be. Cross-site request forgery is also known as CSRF, XSRF, one-click attack, session riding, confused deputy, and sea surf.<\/p>

<\/p>

CSRF attacks are effective in a number of situations, including:<\/p>

* The victim has an active session on the target site.<\/p>

* The victim is authenticated via HTTP auth on the target site.<\/p>

* The victim is on the same local network as the target site.<\/p>

<\/p>

CSRF has primarily been used to perform an action against a target site using the victim's privileges, but recent techniques have been discovered to disclose information by gaining access to the response. The risk of information disclosure is dramatically increased when the target site is vulnerable to XSS, because XSS can be used as a platform for CSRF, allowing the attack to operate within the bounds of the same-origin policy.<\/p>", - "instances": [ - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/num/numguess.jsp", - "method": "GET", - "evidence": "

" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/servlets/servlet/SessionExample?dataname=foo&datavalue=bar", - "method": "GET", - "evidence": "" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/sessions/carts.html", - "method": "GET", - "evidence": "" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/cal/cal1.jsp?action=Submit&email=ZAP&name=ZAP", - "method": "GET", - "evidence": "" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/servlets/servlet/CookieExample", - "method": "POST", - "evidence": "" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/servlets/servlet/SessionExample", - "method": "GET", - "evidence": "" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/servlets/servlet/SessionExample?dataname=ZAP&datavalue=ZAP", - "method": "GET", - "evidence": "" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/checkbox/check.html", - "method": "GET", - "evidence": "" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/error/error.html", - "method": "GET", - "evidence": "" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/sessions/carts.jsp?item=X-files+movie&submit=add", - "method": "GET", - "evidence": "" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/el/implicit-objects.jsp?foo=bar", - "method": "GET", - "evidence": "" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/security/protected/index.jsp", - "method": "GET", - "evidence": "" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/servlets/servlet/RequestParamExample", - "method": "POST", - "evidence": "" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/el/functions.jsp?foo=JSP+2.0", - "method": "GET", - "evidence": "" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/servlets/nonblocking/bytecounter.html", - "method": "GET", - "evidence": "" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/colors/colors.html", - "method": "GET", - "evidence": "" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/servlets/servlet/SessionExample", - "method": "GET", - "evidence": "" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/cal/login.html", - "method": "GET", - "evidence": "" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/num/numguess.jsp?guess=ZAP", - "method": "GET", - "evidence": "" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/sessions/carts.jsp?item=X-files+movie&submit=remove", - "method": "GET", - "evidence": "" - } - ], - "count": "29", - "solution": "

Phase: Architecture and Design<\/p>

Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid.<\/p>

For example, use anti-CSRF packages such as the OWASP CSRFGuard.<\/p>

<\/p>

Phase: Implementation<\/p>

Ensure that your application is free of cross-site scripting issues, because most CSRF defenses can be bypassed using attacker-controlled script.<\/p>

<\/p>

Phase: Architecture and Design<\/p>

Generate a unique nonce for each form, place the nonce into the form, and verify the nonce upon receipt of the form. Be sure that the nonce is not predictable (CWE-330).<\/p>

Note that this can be bypassed using XSS.<\/p>

<\/p>

Identify especially dangerous operations. When the user performs a dangerous operation, send a separate confirmation request to ensure that the user intended to perform that operation.<\/p>

Note that this can be bypassed using XSS.<\/p>

<\/p>

Use the ESAPI Session Management control.<\/p>

This control includes a component for CSRF.<\/p>

<\/p>

Do not use the GET method for any request that triggers a state change.<\/p>

<\/p>

Phase: Implementation<\/p>

Check the HTTP Referer header to see if the request originated from an expected page. This could break legitimate functionality, because users or proxies may have disabled sending the Referer for privacy reasons.<\/p>", - "otherinfo": "

No known Anti-CSRF token [anticsrf, CSRFToken, __RequestVerificationToken, csrfmiddlewaretoken, authenticity_token, OWASP_CSRFTOKEN, anoncsrf, csrf_token, _csrf, _csrfSecret] was found in the following HTML form: [Form 1: \"guess\" ].<\/p>", - "reference": "

http://projects.webappsec.org/Cross-Site-Request-Forgery<\/p>

http://cwe.mitre.org/data/definitions/352.html<\/p>", - "cweid": "352", - "wascid": "9", - "sourceid": "3" - }, - { - "pluginid": "10031", - "alert": "User Controllable HTML Element Attribute (Potential XSS)", - "name": "User Controllable HTML Element Attribute (Potential XSS)", - "riskcode": "0", - "confidence": "1", - "riskdesc": "Informational (Low)", - "desc": "

This check looks at user-supplied input in query string parameters and POST data to identify where certain HTML attribute values might be controlled. This provides hot-spot detection for XSS (cross-site scripting) that will require further review by a security analyst to determine exploitability.<\/p>", - "instances": [ - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/colors/colrs.jsp?action=Hint&color1=ZAP&color2=ZAP", - "method": "GET", - "param": "action" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/colors/colrs.jsp?action=Submit&color1=ZAP&color2=ZAP", - "method": "GET", - "param": "action" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/el/functions.jsp?foo=JSP+2.0", - "method": "GET", - "param": "foo" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/jsp2/el/implicit-objects.jsp?foo=bar", - "method": "GET", - "param": "foo" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/sessions/carts.jsp?item=X-files+movie&submit=remove", - "method": "GET", - "param": "submit" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/colors/colrs.jsp?action=Submit&color1=ZAP&color2=ZAP", - "method": "GET", - "param": "action" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/sessions/carts.jsp?item=X-files+movie&submit=add", - "method": "GET", - "param": "submit" - } - ], - "count": "7", - "solution": "

Validate all input and sanitize output it before writing to any HTML attributes.<\/p>", - "otherinfo": "

User-controlled HTML attribute values were found. Try injecting special characters to see if XSS might be possible. The page at the following URL:<\/p>

<\/p>

http://bodgeit.demo-targets.svc:8080/examples/jsp/colors/colrs.jsp?action=Hint&color1=ZAP&color2=ZAP<\/p>

<\/p>

appears to include user input in: <\/p>

<\/p>

a(n) [input] tag [value] attribute <\/p>

<\/p>

The user input found was:<\/p>

action=Hint<\/p>

<\/p>

The user-controlled value was:<\/p>

hint<\/p>", - "reference": "

http://websecuritytool.codeplex.com/wikipage?title=Checks#user-controlled-html-attribute<\/p>", - "cweid": "20", - "wascid": "20", - "sourceid": "3" - }, - { - "pluginid": "2", - "alert": "Private IP Disclosure", - "name": "Private IP Disclosure", - "riskcode": "1", - "confidence": "2", - "riskdesc": "Low (Medium)", - "desc": "

A private IP (such as 10.x.x.x, 172.x.x.x, 192.168.x.x) or an Amazon EC2 private hostname (for example, ip-10-0-56-78) has been found in the HTTP response body. This information might be helpful for further attacks targeting internal systems.<\/p>", - "instances": [ - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/servlets/servlet/RequestInfoExample", - "method": "GET", - "evidence": "10.1.20.26" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/jsp/snp/snoop.jsp", - "method": "GET", - "evidence": "10.1.20.26" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/filter.html", - "method": "GET", - "evidence": "192.168.0.10" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/monitoring.html", - "method": "GET", - "evidence": "192.168.1.75" - } - ], - "count": "4", - "solution": "

Remove the private IP address from the HTTP response body. For comments, use JSP/ASP/PHP comment instead of HTML/JavaScript comment which can be seen by client browsers.<\/p>", - "otherinfo": "

10.1.20.26<\/p>

<\/p>", - "reference": "

https://tools.ietf.org/html/rfc1918<\/p>", - "cweid": "200", - "wascid": "13", - "sourceid": "3" - }, - { - "pluginid": "90022", - "alert": "Application Error Disclosure", - "name": "Application Error Disclosure", - "riskcode": "2", - "confidence": "2", - "riskdesc": "Medium (Medium)", - "desc": "

This page contains an error/warning message that may disclose sensitive information like the location of the file that produced the unhandled exception. This information can be used to launch further attacks against the web application. The alert could be a false positive if the error message is found inside a documentation page.<\/p>", - "instances": [ - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/jndi-resources-howto.html", - "method": "GET", - "evidence": "JDBC Driver" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/manager-howto.html", - "method": "GET", - "evidence": "java.lang.NumberFormatException: For input string:" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/jndi-datasource-examples-howto.html", - "method": "GET", - "evidence": "JDBC Driver" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/listeners.html", - "method": "GET", - "evidence": "JDBC Driver" - }, - { - "uri": "http://bodgeit.demo-targets.svc:8080/docs/config/valve.html", - "method": "GET", - "evidence": "Error Report" - } - ], - "count": "5", - "solution": "

Review the source code of this page. Implement custom error pages. Consider implementing a mechanism to provide a unique error reference/identifier to the client (browser) while logging the details on the server side and not exposing them to the user.<\/p>", - "reference": "

<\/p>", - "cweid": "200", - "wascid": "13", - "sourceid": "3" - }, - { - "pluginid": "10109", - "alert": "Modern Web Application", - "name": "Modern Web Application", - "riskcode": "0", - "confidence": "2", - "riskdesc": "Informational (Medium)", - "desc": "

The application appears to be a modern web application. If you need to explore it automatically then the Ajax Spider may well be more effective than the standard one.<\/p>", - "instances": [ - { - "uri": "http://bodgeit.demo-targets.svc:8080/examples/websocket/echo.xhtml", - "method": "GET", - "evidence": "

Apache Tomcat 8

\n Version 8.0.37,\n

SSI How To

Table of Contents

Introduction

\n\n

SSI (Server Side Includes) are directives that are placed in HTML pages,\nand evaluated on the server while the pages are being served. They let you\nadd dynamically generated content to an existing HTML page, without having\nto serve the entire page via a CGI program, or other dynamic technology.\n

\n\n

Within Tomcat SSI support can be added when using Tomcat as your\nHTTP server and you require SSI support. Typically this is done\nduring development when you don't want to run a web server like Apache.

\n\n

Tomcat SSI support implements the same SSI directives as Apache. See the\n\nApache Introduction to SSI for information on using SSI directives.

\n\n

SSI support is available as a servlet and as a filter. You should use one\nor the other to provide SSI support but not both.

\n\n

Servlet based SSI support is implemented using the class\norg.apache.catalina.ssi.SSIServlet. Traditionally, this servlet\nis mapped to the URL pattern \"*.shtml\".

\n\n

Filter based SSI support is implemented using the class\norg.apache.catalina.ssi.SSIFilter. Traditionally, this filter\nis mapped to the URL pattern \"*.shtml\", though it can be mapped to \"*\" as\nit will selectively enable/disable SSI processing based on mime types. The\ncontentType init param allows you to apply SSI processing to JSP pages,\njavascript, or any other content you wish.

\n

By default SSI support is disabled in Tomcat.

\n

Installation

\n\n

CAUTION - SSI directives can be used to execute programs\nexternal to the Tomcat JVM. If you are using the Java SecurityManager this\nwill bypass your security policy configuration in catalina.policy.\n

\n\n

To use the SSI servlet, remove the XML comments from around the SSI servlet\nand servlet-mapping configuration in\n$CATALINA_BASE/conf/web.xml.

\n\n

To use the SSI filter, remove the XML comments from around the SSI filter\nand filter-mapping configuration in\n$CATALINA_BASE/conf/web.xml.

\n\n

Only Contexts which are marked as privileged may use SSI features (see the\nprivileged property of the Context element).

\n\n

Servlet Configuration

\n\n

There are several servlet init parameters which can be used to\nconfigure the behaviour of the SSI servlet.

\n
    \n
  • buffered - Should output from this servlet be buffered?\n(0=false, 1=true) Default 0 (false).
  • \n
  • debug - Debugging detail level for messages logged\nby this servlet. Default 0.
  • \n
  • expires - The number of seconds before a page with SSI\ndirectives will expire. Default behaviour is for all SSI directives to be\nevaluated for every request.
  • \n
  • isVirtualWebappRelative - Should \"virtual\" SSI directive\npaths be interpreted as relative to the context root, instead of the server\nroot? Default false.
  • \n
  • inputEncoding - The encoding to be assumed for SSI\nresources if one cannot be determined from the resource itself. Default is\nthe default platform encoding.
  • \n
  • outputEncoding - The encoding to be used for the result\nof the SSI processing. Default is UTF-8.
  • \n
  • allowExec - Is the exec command enabled? Default is\nfalse.
  • \n
\n\n\n

Filter Configuration

\n\n

There are several filter init parameters which can be used to\nconfigure the behaviour of the SSI filter.

\n
    \n
  • contentType - A regex pattern that must be matched before\nSSI processing is applied. When crafting your own pattern, don't forget that a\nmime content type may be followed by an optional character set in the form\n\"mime/type; charset=set\" that you must take into account. Default is\n\"text/x-server-parsed-html(;.*)?\".
  • \n
  • debug - Debugging detail level for messages logged\nby this servlet. Default 0.
  • \n
  • expires - The number of seconds before a page with SSI\ndirectives will expire. Default behaviour is for all SSI directives to be\nevaluated for every request.
  • \n
  • isVirtualWebappRelative - Should \"virtual\" SSI directive\npaths be interpreted as relative to the context root, instead of the server\nroot? Default false.
  • \n
  • allowExec - Is the exec command enabled? Default is\nfalse.
  • \n
\n\n\n

Directives

\n

Server Side Includes are invoked by embedding SSI directives in an HTML document\n whose type will be processed by the SSI servlet. The directives take the form of an HTML\n comment. The directive is replaced by the results of interpreting it before sending the\n page to the client. The general form of a directive is:

\n

<!--#directive [parm=value] -->

\n

The directives are:

\n