From d53fb7af426856f823924fc7f432030ac297963b Mon Sep 17 00:00:00 2001 From: Ryan Ahearn Date: Thu, 18 Feb 2021 18:07:57 -0500 Subject: [PATCH 1/3] Remediate missing CSP directive --- .circleci/config.yml | 8 +------- .editorconfig | 5 +++++ bin/prod-style-server | 9 +++++++++ src/app.js | 9 ++++++++- zap.conf | 3 ++- 5 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 .editorconfig create mode 100755 bin/prod-style-server diff --git a/.circleci/config.yml b/.circleci/config.yml index b912533503..5a908b451c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -241,13 +241,7 @@ jobs: at: . - run: name: Start up local server - command: | # production style build (single BE server with static FE) - docker-compose -f docker-compose.dss.yml run --rm server yarn install --production=false - docker-compose -f docker-compose.dss.yml run --rm server yarn --cwd frontend install --production=false - docker-compose -f docker-compose.dss.yml run --rm server yarn build - docker-compose -f docker-compose.dss.yml run --rm server yarn --cwd frontend run build - docker-compose -f docker-compose.dss.yml up -d - docker-compose -f docker-compose.dss.yml exec server yarn db:migrate:ci + command: ./bin/prod-style-server - run: name: Pull OWASP ZAP docker image command: docker pull owasp/zap2docker-weekly diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..4a074fa087 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,5 @@ +# EditorConfig is awesome: https://EditorConfig.org + +[zap.conf] +indent_size = 4 +indent_style = tab diff --git a/bin/prod-style-server b/bin/prod-style-server new file mode 100755 index 0000000000..0ae77b7586 --- /dev/null +++ b/bin/prod-style-server @@ -0,0 +1,9 @@ +#!/bin/bash + +# run a production style build (single BE server with static FE) +docker-compose -f docker-compose.dss.yml run --rm server yarn install --production=false +docker-compose -f docker-compose.dss.yml run --rm server yarn --cwd frontend install --production=false +docker-compose -f docker-compose.dss.yml run --rm server yarn build +docker-compose -f docker-compose.dss.yml run --rm server yarn --cwd frontend run build +docker-compose -f docker-compose.dss.yml up -d +docker-compose -f docker-compose.dss.yml run --rm server yarn db:migrate:ci diff --git a/src/app.js b/src/app.js index 8f3ca1f7c5..721217e0a0 100644 --- a/src/app.js +++ b/src/app.js @@ -21,7 +21,14 @@ const oauth2CallbackPath = '/oauth2-client/login/oauth2/code/'; app.use(requestLogger); app.use(express.json()); app.use(express.urlencoded({ extended: true })); -app.use(helmet()); +app.use(helmet({ + contentSecurityPolicy: { + directives: { + ...helmet.contentSecurityPolicy.getDefaultDirectives(), + 'form-action': ["'self'"], + }, + }, +})); app.use(cookieSession({ name: 'session', diff --git a/zap.conf b/zap.conf index 84df7891ef..75839435ed 100644 --- a/zap.conf +++ b/zap.conf @@ -19,6 +19,7 @@ 10040 FAIL (Secure Pages Include Mixed Content) 10105 FAIL (Weak Authentication Method) 10202 FAIL (Absence of Anti-CSRF Tokens) +10055 WARN (CSP) 2 WARN (Private IP Disclosure) 3 FAIL (Session ID in URL Rewrite) 50001 WARN (Script Passive Scan Rules) @@ -26,4 +27,4 @@ 90011 WARN (Charset Mismatch) 90022 WARN (Application Error Disclosure) 90033 FAIL (Loosely Scoped Cookie) -* OUTOFSCOPE .*(robots.txt) +* OUTOFSCOPE .*(robots.txt|sitemap.xml) From 1e0aaa81e56fbf3e48f52ee8a281af7cd0c01a97 Mon Sep 17 00:00:00 2001 From: Ryan Ahearn Date: Fri, 19 Feb 2021 10:20:00 -0500 Subject: [PATCH 2/3] Make it easier to run owasp zap locally --- .circleci/config.yml | 11 +---------- bin/prod-style-server | 5 +++++ bin/run-owasp-scan | 29 +++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 10 deletions(-) create mode 100755 bin/run-owasp-scan diff --git a/.circleci/config.yml b/.circleci/config.yml index 5a908b451c..211d9041ad 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -250,16 +250,7 @@ jobs: command: chmod g+w reports - run: name: Run OWASP ZAP - command: | - docker run \ - -v $(pwd)/zap.conf:/zap/wrk/zap.conf:ro \ - -v $(pwd)/reports:/zap/wrk:rw \ - --rm \ - --user zap:$(id -g) \ - --network="project_smarthub" \ - -t owasp/zap2docker-weekly zap-baseline.py \ - -t http://server:8080 \ - -c zap.conf -I -i -r owasp_report.html + command: ./bin/run-owasp-scan - store_artifacts: path: reports/owasp_report.html accessibility_scan: diff --git a/bin/prod-style-server b/bin/prod-style-server index 0ae77b7586..101b60da5d 100755 --- a/bin/prod-style-server +++ b/bin/prod-style-server @@ -1,4 +1,9 @@ #!/bin/bash +# +# This script sets up a server as run-owasp-scan expects it + +# remove old build directory +rm -r build/ # run a production style build (single BE server with static FE) docker-compose -f docker-compose.dss.yml run --rm server yarn install --production=false diff --git a/bin/run-owasp-scan b/bin/run-owasp-scan new file mode 100755 index 0000000000..9441f487a7 --- /dev/null +++ b/bin/run-owasp-scan @@ -0,0 +1,29 @@ +#!/bin/bash +########################### +# +# Allow running OWASP Zap scans on demand. This script expects +# a server running at http://server:8080. This can be setup with +# +# ./bin/prod-style-server +# +# The only argument for this script is the network name docker will +# find server on. For a default git clone, this should be +# +# ./bin/run-owasp-scan head-start-ttadp_smarthub +# +########################### + +declare network="project_smarthub" +if [ -n "$1" ]; then + network=$1 +fi + +docker run \ + -v $(pwd)/zap.conf:/zap/wrk/zap.conf:ro \ + -v $(pwd)/reports:/zap/wrk:rw \ + --rm \ + --user zap:$(id -g) \ + --network=$network \ + -t owasp/zap2docker-weekly zap-baseline.py \ + -t http://server:8080 \ + -c zap.conf -I -i -r owasp_report.html From ae3a8f5beb8ccd14b71cb31231e3c45708a0082e Mon Sep 17 00:00:00 2001 From: Ryan Ahearn Date: Fri, 19 Feb 2021 14:52:55 -0500 Subject: [PATCH 3/3] Remove deprecated CSP directives that were causing low OWASP findings --- src/app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app.js b/src/app.js index 721217e0a0..cd00462a85 100644 --- a/src/app.js +++ b/src/app.js @@ -5,6 +5,7 @@ import axios from 'axios'; import cookieSession from 'cookie-session'; import path from 'path'; import join from 'url-join'; +import { omit } from 'lodash'; import { INTERNAL_SERVER_ERROR } from 'http-codes'; import { CronJob } from 'cron'; import { hsesAuth } from './middleware/authMiddleware'; @@ -24,7 +25,7 @@ app.use(express.urlencoded({ extended: true })); app.use(helmet({ contentSecurityPolicy: { directives: { - ...helmet.contentSecurityPolicy.getDefaultDirectives(), + ...omit(helmet.contentSecurityPolicy.getDefaultDirectives(), 'upgrade-insecure-requests', 'block-all-mixed-content'), 'form-action': ["'self'"], }, },