Project: secureCodeBox (Provisioning / Security & Compliance)
File: scanning-web-applications.md

title: "Scanning Web Applications" description: "Automating ZAP with the secureCodeBox" sidebar_position: 3 In this step-by-step tutorial, we will go through all the required stages to set up an in depth configured ZAP Scan against OWASP Juice Shop with the secureCodeBox. 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 for more information. We will start by installing the ZAP-Advanced scanner: ```bash helm upgrade --install zap-advanced secureCodeBox/zap-advanced ``` And the juice-shop demo-target. ```bash helm upgrade --install juice-shop secureCodeBox/juice-shop ``` We can first start with a basic `zap-advanced` scan. We use here our CRD (Custom Resource definition) and a to configure our scan. ```yaml title="scan.yaml" apiVersion: v1 kind: ConfigMap metadata: name: zap-advanced-scan-config data: 2-zap-advanced-scan.yaml: |- contexts: name: scb-juiceshop-context url: http://juice-shop.default.svc:3000/ apiVersion: "execution.securecodebox.io/v1" kind: Scan metadata: name: "zap-authenticated-full-scan-juiceshop-basic" labels: organization: "OWASP" spec: scanType: "zap-advanced-scan" parameters: "-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 ``` 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 can do a test run via: ```bash kubectl apply -f scan.yaml ``` The ConfigMap right now is minimal. So we can start modifying and adding to it to fit our needs. For example, let's start by setting the scope that we want for our scan. This is done by adding and excluding the paths that the scanner will use. This usually makes the scans faster. Our ConfigMap will then look like this. ```yaml apiVersion: v1 kind: ConfigMap metadata: name: zap-advanced-scan-config data: 2-zap-advanced-scan.yaml: |- contexts: name: scb-juiceshop-context url: http://juice-shop.default.svc:3000/ includePaths: "http://juice-shop.default.svc:3000.*" excludePaths: ".socket\\.io." ".*\\.png" ".*\\.jpeg" ".*\\.jpg" ".*\\.woff" ".*\\.woff2" ".*\\.ttf" ".*\\.ico" ``` ZAP uses a 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: ```yaml apiVersion: v1 kind: ConfigMap metadata: name: zap-advanced-scan-config data: 2-zap-advanced-scan.yaml: |- contexts: name: scb-juiceshop-context url: http://juice-shop.default.svc:3000/ includePaths: "http://juice-shop.default.svc:3000.*" excludePaths: ".socket\\.io." ".*\\.png" ".*\\.jpeg" ".*\\.jpg" ".*\\.woff" ".*\\.woff2" ".*\\.ttf" ".*\\.ico" spiders: name: scb-juiceshop-spider context: scb-juiceshop-context user: juiceshop-user-1 url: http://juice-shop.default.svc:3000/ ajax: true failIfFoundUrlsLessThan: 0 warnIfFoundUrlsLessThan: 0 maxDuration: 5 maxDepth: 10 ``` ZAP also has the option for an . 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: ```yaml scanners: name: scb-juiceshop-scan context: scb-juiceshop-context user: juiceshop-user-1 url:

maxRuleDurationInMins: 1 maxScanDurationInMins: 10 threadPerHost: 5 delayInMs: 0 addQueryParam: false handleAntiCSRFTokens: false injectPluginIdInHeader: 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 . :::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 . ::: Our `contexts` parameter in our scan would then look something like this: ```yaml apiVersion: v1 kind: ConfigMap metadata: name: zap-advanced-scan-config data: 2-zap-advanced-scan.yaml: |- contexts: name: scb-juiceshop-context url: http://juice-shop.default.svc:3000/ includePaths: "http://juice-shop.default.svc:3000.*" excludePaths: ".socket\\.io." ".*\\.png" ".*\\.jpeg" ".*\\.jpg" ".*\\.woff" ".*\\.woff2" ".*\\.ttf" ".*\\.ico" authentication: type: "json-based" json-based: loginUrl: "http://juice-shop.default.svc:3000/rest/user/login" loginRequestData: '{"email":"admin@juice-sh.op","password":"admin123"}' verification: isLoggedOutIndicator: '\Q{"user":{}}\E' users: name: juiceshop-user-1 username: admin@juice-sh.op password: admin123 forced: true session: type: "scriptBasedSessionManagement" scriptBasedSessionManagement: name: "juiceshop-session-management.js" enabled: true engine: "Oracle Nashorn" filePath: "/home/zap/.ZAP_D/scripts/scripts/session/juiceshop-session-management.js" description: "This is a JuiceShop specific SessionManagement Script used to handle JWT." ``` :::note For more information on Authentication/Session parameters check out ZAP's documentation on the matter . ::: Our complete ZAP Scan file is then the following : ```yaml title="scan.yaml" apiVersion: v1 kind: ConfigMap metadata: name: zap-advanced-scan-config data: 2-zap-advanced-scan.yaml: |- contexts: name: scb-juiceshop-context url: http://juice-shop.default.svc:3000/ includePaths: "http://juice-shop.default.svc:3000.*" excludePaths: ".socket\\.io." ".*\\.png" ".*\\.jpeg" ".*\\.jpg" ".*\\.woff" ".*\\.woff2" ".*\\.ttf" ".*\\.ico" authentication: type: "json-based" json-based: loginUrl: "http://juice-shop.default.svc:3000/rest/user/login" loginRequestData: '{"email":"admin@juice-sh.op","password":"admin123"}' verification: isLoggedOutIndicator: '\Q{"user":{}}\E' users: name: juiceshop-user-1 username: admin@juice-sh.op password: admin123 forced: true session: type: "scriptBasedSessionManagement" scriptBasedSessionManagement: name: "juiceshop-session-management.js" enabled: true engine: "Oracle Nashorn" 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 context: scb-juiceshop-context user: juiceshop-user-1 url: http://juice-shop.default.svc:3000/ ajax: true failIfFoundUrlsLessThan: 0 warnIfFoundUrlsLessThan: 0 maxDuration: 5 maxDepth: 10 scanners: name: scb-juiceshop-scan context: scb-juiceshop-context user: juiceshop-user-1 url: http://juice-shop.default.svc:3000/ maxRuleDurationInMins: 1 maxScanDurationInMins: 10 threadPerHost: 5 delayInMs: 0 addQueryParam: false handleAntiCSRFTokens: false injectPluginIdInHeader: false scanHeadersAllRequests: false apiVersion: "execution.securecodebox.io/v1" kind: Scan metadata: name: "zap-authenticated-full-scan-juiceshop" labels: organization: "OWASP" spec: scanType: "zap-advanced-scan" parameters: "-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 ``` Let's delete our first test scan and run a new one via : ```bash kubectl delete -f scan.yaml kubectl apply -f scan.yaml ``` 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 ``` 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 to access the integrated Minio S3 Bucket to view the findings. And we're done! Have Fun Scanning :)