diff --git a/.github/actions/django-security-check/Dockerfile b/.github/actions/django-security-check/Dockerfile new file mode 100644 index 000000000..34cd1c6ad --- /dev/null +++ b/.github/actions/django-security-check/Dockerfile @@ -0,0 +1,9 @@ +# Container image that runs your code +FROM python:3-buster + +# Copies your code file from your action repository to the filesystem path `/` of the container +COPY entrypoint.sh /entrypoint.sh + +# Code file to execute when the docker container starts up (`entrypoint.sh`) +ENTRYPOINT ["/entrypoint.sh"] + diff --git a/.github/actions/django-security-check/LICENSE b/.github/actions/django-security-check/LICENSE new file mode 100644 index 000000000..d3fd56fdd --- /dev/null +++ b/.github/actions/django-security-check/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020-2021 Victoria Drake + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/.github/actions/django-security-check/README.md b/.github/actions/django-security-check/README.md new file mode 100644 index 000000000..4eddcf74c --- /dev/null +++ b/.github/actions/django-security-check/README.md @@ -0,0 +1,123 @@ +# Django Security Check + +Helps you continuously monitor and fix common security vulnerabilities in your [Django](https://www.djangoproject.com/) application. + +If you are thinking of using this action, congratulations. You're well on your way to building a secure Django project! + +## Use this in your workflow + +You can use this action in a workflow file to continuously run [Django's `check --deploy`](https://docs.djangoproject.com/en/3.0/ref/django-admin/#check) against your production Django application configuration. Here is an example workflow that runs Django Security Check on any `push` event to the `master` branch. See [below for `env` instructions](https://github.com/victoriadrake/django-security-check#setting-the-env-variables). + +```yml +name: Django Security Check + +on: + push: + branches: + - master + +env: + SECRET_KEY: ${{ secrets.SECRET_KEY }} + FAIL_LEVEL: WARNING + ENV_TYPE: venv + DEP_PATH: app/requirements.txt + APP_PATH: app/ + EXTRA_ARGS: "--settings=app.settings.production" + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - name: Check out master + uses: actions/checkout@master + with: + fetch-depth: 1 + - name: Scan Django settings for security issues + id: check + uses: victoriadrake/django-security-check@master + - name: Upload output + uses: actions/upload-artifact@v2 + with: + name: security-check-output + path: output.txt +``` + +## View results + +In the example workflow file above, you can view results in the Action workflow run, or download them as an [artifact](https://docs.github.com/en/actions/configuring-and-managing-workflows/persisting-workflow-data-using-artifacts). Here is [an example of output from a check](https://github.com/victoriadrake/react-in-django/runs/1016213333?check_suite_focus=true#step:4:45). + +You can also add the check output to a comment, for example, if the workflow was triggered by a pull request. To do this, [set an output parameter](https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-output-parameter) and use `actions/github-script`. Here's an example workflow you can copy that runs on pull requests: + +```yml +name: Django Security Check + +on: pull_request_target + +env: + SECRET_KEY: ${{ secrets.SECRET_KEY }} + FAIL_LEVEL: WARNING + ENV_TYPE: pipenv + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - name: Check out master + uses: actions/checkout@master + with: + fetch-depth: 1 + - name: Scan Django settings for security issues + id: check + uses: victoriadrake/django-security-check@master + - id: results + run: | + OUTPUT=$(cat output.txt) + FORMATTED=${OUTPUT//$'\n'/%0A} + echo ::set-output name=file::**Django Security Check identified issues:** %0A$FORMATTED + - name: Comment with output + uses: actions/github-script@v3 + with: + script: | + github.issues.createComment({ + issue_number: ${{ github.event.number }}, + owner: context.repo.owner, + repo: context.repo.repo, + body: `${{ steps.results.outputs.file }}` + }) +``` + +This produces: + +![Screenshot of security check output in comment](screenshot.png) + +Helpful instructions for remediation are provided by Django in the output. + +### Setting the `env` variables + +There must be a `SECRET_KEY` value available in order for Django to run the checks. Otherwise, an `ImproperlyConfigured` exception is raised. If you don't deploy from your repository, you may use a dummy value. [Set a repository secret](https://docs.github.com/en/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-a-repository) with the name of `SECRET_KEY` and include this as an environment variable as shown in the examples above. + +The `FAIL_LEVEL` environment variable is the minimum severity finding that will cause the check to fail. Choices are `CRITICAL`, `ERROR`, `WARNING`, `INFO`, and `DEBUG`. If not set, it defaults to `ERROR`. + +Depending on what you've set as a `FAIL_LEVEL`, this action may return results without a failed check. For example, the default `ERROR` level may still return `WARNING` results, although the check is a pass. To fail the check on `WARNING` results, set `FAIL_LEVEL` to `WARNING`, `INFO`, or `DEBUG`. + +This action currently supports use of [Pipenv](https://pipenv.pypa.io/en/latest/) or [`venv`](https://docs.python.org/3/library/venv.html#module-venv). + +If you are using Pipenv, set `ENV_TYPE: pipenv`. Set the `DEP_PATH` variable to point to the directory containing your `Pipfile`. For example, if you have `project-root/app/Pipfile`, set `DEP_PATH: app/`. If you have `project-root/Pipfile`, you can leave this unset. + +If you are using `venv`, set `ENV_TYPE: venv` as above. Set the `DEP_PATH` variable to the path of your dependencies file from the root, including the file name, as above. This is usually called `requirements.txt`, but may be different in your application. + +Set the `APP_PATH` to the location of your `manage.py` file. For example, if you have `project-root/application/manage.py`, then set `APP_PATH: application/`. If you have `project-root/manage.py`, you can leave this unset. + +If you are not using a virtual environment, shame on you. This action will still try to help you by installing Django. Ensure you set `APP_PATH` to the directory of your `manage.py` file. + +You can use `EXTRA_ARGS` to pass any additional desired arguments, such as a settings module. + +### Workflow customization + +See full instructions for [Configuring and managing workflows](https://help.github.com/en/actions/configuring-and-managing-workflows). + +For help editing the YAML file, see [Workflow syntax for GitHub Actions](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions). diff --git a/.github/actions/django-security-check/action.yml b/.github/actions/django-security-check/action.yml new file mode 100644 index 000000000..fa3725f65 --- /dev/null +++ b/.github/actions/django-security-check/action.yml @@ -0,0 +1,12 @@ +name: "Django Security Check" +description: "Helps find and remediate common security vulnerabilities in your Django application." +author: "victoriadrake" +branding: + icon: "shield" + color: "green" +outputs: + result: + description: "Django Security Check output" +runs: + using: "docker" + image: "Dockerfile" \ No newline at end of file diff --git a/.github/actions/django-security-check/entrypoint.sh b/.github/actions/django-security-check/entrypoint.sh new file mode 100755 index 000000000..69f8246d7 --- /dev/null +++ b/.github/actions/django-security-check/entrypoint.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# Omits 'set -e' because short-circuiting this script fails the GitHub action unintentionally + + +FAIL=${FAIL_LEVEL:=ERROR} +MANAGE_PATH=${GITHUB_WORKSPACE}/${APP_PATH} +REQS=${GITHUB_WORKSPACE}/${DEP_PATH} +ARGS=${EXTRA_ARGS} + +echo -e "Path to manage.py set as: " $MANAGE_PATH +echo -e "Requirements path set as: " $REQS + +if [[ "$ENV_TYPE" == "pipenv" ]]; then + cd $REQS + pip3 install pipenv + PIPENV_IGNORE_VIRTUALENVS=1 pipenv install + cd $MANAGE_PATH && PIPENV_IGNORE_VIRTUALENVS=1 pipenv run python3 manage.py check --deploy --fail-level ${FAIL} ${ARGS} &> output.txt + EXIT_CODE=$? +fi +if [[ "$ENV_TYPE" == "venv" ]]; then + pip install -r $REQS + cd $MANAGE_PATH && python manage.py check --deploy --fail-level ${FAIL} ${ARGS} &> output.txt + EXIT_CODE=$? +fi +if [[ -z "$ENV_TYPE" ]]; then + echo "No virtual environment specified." + pip install django + cd $MANAGE_PATH && python manage.py check --deploy --fail-level ${FAIL} ${ARGS} &> output.txt + EXIT_CODE=$? +fi + +echo -e "\n--------- Django Security Check results ---------" +cat output.txt + +exit $EXIT_CODE diff --git a/.github/actions/django-security-check/screenshot.png b/.github/actions/django-security-check/screenshot.png new file mode 100644 index 000000000..608b9b1aa Binary files /dev/null and b/.github/actions/django-security-check/screenshot.png differ diff --git a/.github/workflows/security-check.yaml b/.github/workflows/security-check.yaml index 9738c3466..34946fde1 100644 --- a/.github/workflows/security-check.yaml +++ b/.github/workflows/security-check.yaml @@ -8,31 +8,32 @@ on: branches: - main -env: - FAIL_LEVEL: WARNING - ENV_TYPE: pipenv - DEP_PATH: src/ - APP_PATH: src/ - EXTRA_ARGS: "--settings=registrar.config.settings" - DJANGO_SECRET_KEY: not-a-secret-jw7kQcb35fcDRIKp7K4fqZBmVvb+Sy4nkAGf44DxHi6EJl - DATABASE_URL: "postgres://not_a_user:not_a_password@not_a_host" - DJANGO_BASE_URL: "https://not_a_host" - jobs: security-check: name: Django security check runs-on: ubuntu-latest + env: + # fail the Django security check even on warnings + FAIL_LEVEL: WARNING + ENV_TYPE: pipenv + DEP_PATH: src/ + APP_PATH: src/ + EXTRA_ARGS: "--settings=registrar.config.settings" + DJANGO_SECRET_KEY: not-a-secret-jw7kQcb35fcDRIKp7K4fqZBmVvb+Sy4nkAGf44DxHi6EJl + DATABASE_URL: "postgres://not_a_user:not_a_password@not_a_host" + DJANGO_BASE_URL: "https://not_a_host" + steps: - name: Check out uses: actions/checkout@v3 - name: Scan Django settings for security issues id: check - uses: victoriadrake/django-security-check@master + uses: ./.github/actions/django-security-check - name: Upload output uses: actions/upload-artifact@v2 with: name: security-check-output - path: output.txt + path: ./src/output.txt owasp-scan: name: OWASP security scan diff --git a/src/docker-compose.yml b/src/docker-compose.yml index bf8e5c396..b3781716b 100644 --- a/src/docker-compose.yml +++ b/src/docker-compose.yml @@ -73,7 +73,7 @@ services: - pa11y owasp: - image: owasp/zap2docker-weekly + image: owasp/zap2docker-stable command: zap-baseline.py -t http://app:8080 -c zap.conf -I -r zap_report.html volumes: - .:/zap/wrk/ diff --git a/src/registrar/config/settings.py b/src/registrar/config/settings.py index 2e530e6df..406e3b373 100644 --- a/src/registrar/config/settings.py +++ b/src/registrar/config/settings.py @@ -228,6 +228,18 @@ SERVER_EMAIL = "root@get.gov" # endregion # region: Headers-----------------------------------------------------------### +# Content-Security-Policy configuration +# this can be restrictive because we have few external scripts +allowed_sources = ( + "'self'", +) +CSP_DEFAULT_SRC = allowed_sources +# Most things fall back to default-src, but these two do not and should be +# explicitly set +CSP_FRAME_ANCESTORS = allowed_sources +CSP_FORM_ACTION = allowed_sources + + # Content-Length header is set by django.middleware.common.CommonMiddleware # X-Frame-Options header is set by @@ -240,12 +252,6 @@ SERVER_EMAIL = "root@get.gov" # as Host header may contain a proxy rather than the actual client USE_X_FORWARDED_HOST = True -# Content-security policy header configuration -CSP_DEFAULT_SRC = ["'none'"] -CSP_STYLE_SRC = ["'self'"] -CSP_SCRIPT_SRC = ["'self'"] -CSP_IMG_SRC = ["'self'"] - # endregion # region: Internationalisation----------------------------------------------### diff --git a/src/zap.conf b/src/zap.conf index 4fef3aff0..283c36810 100644 --- a/src/zap.conf +++ b/src/zap.conf @@ -1,80 +1,96 @@ # zap-full-scan rule configuration file -# Change WARN to IGNORE to ignore rule or FAIL to fail if rule matches -# Active scan rules set to IGNORE will not be run which will speed up the scan # Only the rule identifiers are used - the names are just for info # You can add your own messages to each rule by appending them after a tab on each line. -0 WARN (Directory Browsing - Active/release) -10003 WARN (Vulnerable JS Library - Passive/release) +0 FAIL (Directory Browsing - Active/release) +10003 FAIL (Vulnerable JS Library - Passive/release) 10010 FAIL (Cookie No HttpOnly Flag - Passive/release) 10011 FAIL (Cookie Without Secure Flag - Passive/release) -10015 WARN (Incomplete or No Cache-control Header Set - Passive/release) +10015 FAIL (Incomplete or No Cache-control Header Set - Passive/release) 10016 FAIL (Web Browser XSS Protection Not Enabled) -10017 WARN (Cross-Domain JavaScript Source File Inclusion - Passive/release) -10019 WARN (Content-Type Header Missing - Passive/release) +10017 FAIL (Cross-Domain JavaScript Source File Inclusion - Passive/release) +10019 FAIL (Content-Type Header Missing - Passive/release) 10020 FAIL (X-Frame-Options Header - Passive/release) -10021 WARN (X-Content-Type-Options Header Missing - Passive/release) -10023 WARN (Information Disclosure - Debug Error Messages - Passive/release) +10021 FAIL (X-Content-Type-Options Header Missing - Passive/release) +# With DEBUG=True Django's internal server serves static files without this +# header, but it is not an issue in production +10021 OUTOFSCOPE http://app:8080/public/.*$ +10023 FAIL (Information Disclosure - Debug Error Messages - Passive/release) 10024 FAIL (Information Disclosure - Sensitive Information in URL - Passive/release) 10025 FAIL (Information Disclosure - Sensitive Information in HTTP Referrer Header - Passive/release) -10026 WARN (HTTP Parameter Override - Passive/beta) -10027 WARN (Information Disclosure - Suspicious Comments - Passive/release) +10026 FAIL (HTTP Parameter Override - Passive/beta) +10027 FAIL (Information Disclosure - Suspicious Comments - Passive/release) +# Debug toolbar contains the word "from" which is a false positive and also +# it isn't installed in production (see word list at https://github.com/zaproxy/zap-extensions/blob/main/addOns/pscanrules/src/main/zapHomeFiles/xml/suspicious-comments.txt) +10027 OUTOFSCOPE http://app:8080/public/debug_toolbar/js/toolbar.js +# USWDS.min.js contains suspicious words "query", "select", "from" in ordinary usage +10027 OUTOFSCOPE http://app:8080/public/js/uswds.min.js 10028 FAIL (Open Redirect - Passive/beta) -10029 WARN (Cookie Poisoning - Passive/beta) -10030 WARN (User Controllable Charset - Passive/beta) -10031 WARN (User Controllable HTML Element Attribute (Potential XSS) - Passive/beta) -10032 WARN (Viewstate - Passive/release) -10033 WARN (Directory Browsing - Passive/beta) -10034 WARN (Heartbleed OpenSSL Vulnerability (Indicative) - Passive/beta) +10029 FAIL (Cookie Poisoning - Passive/beta) +10030 FAIL (User Controllable Charset - Passive/beta) +10031 FAIL (User Controllable HTML Element Attribute (Potential XSS) - Passive/beta) +10032 FAIL (Viewstate - Passive/release) +10033 FAIL (Directory Browsing - Passive/beta) +10034 FAIL (Heartbleed OpenSSL Vulnerability (Indicative) - Passive/beta) 10035 FAIL (Strict-Transport-Security Header - Passive/beta) -10036 WARN (HTTP Server Response Header - Passive/beta) -10037 WARN (Server Leaks Information via "X-Powered-By" HTTP Response Header Field(s) - Passive/release) -10038 WARN (Content Security Policy (CSP) Header Not Set - Passive/beta) -10039 WARN (X-Backend-Server Header Information Leak - Passive/beta) +10036 FAIL (HTTP Server Response Header - Passive/beta) +# With DEBUG=True Django's internal server sends the Server header, but +# it is not an issue in production +10036 OUTOFSCOPE http://app:8080.*$ +10037 FAIL (Server Leaks Information via "X-Powered-By" HTTP Response Header Field(s) - Passive/release) +10038 FAIL (Content Security Policy (CSP) Header Not Set - Passive/beta) +# With DEBUG=True, Django sends a 404 page without the CSP headers. This isn't true on production +# For URLs that Zap gets that aren't present for us, skip this false positive +10038 OUTOFSCOPE http://app:8080/public/img/(favicon|touch-icon).png +10038 OUTOFSCOPE http://app:8080/(robots.txt|sitemap.xml) +10039 FAIL (X-Backend-Server Header Information Leak - Passive/beta) 10040 FAIL (Secure Pages Include Mixed Content - Passive/release) -10041 WARN (HTTP to HTTPS Insecure Transition in Form Post - Passive/beta) -10042 WARN (HTTPS to HTTP Insecure Transition in Form Post - Passive/beta) +10041 FAIL (HTTP to HTTPS Insecure Transition in Form Post - Passive/beta) +10042 FAIL (HTTPS to HTTP Insecure Transition in Form Post - Passive/beta) 10043 FAIL (User Controllable JavaScript Event (XSS) - Passive/beta) -10044 WARN (Big Redirect Detected (Potential Sensitive Information Leak) - Passive/beta) -10045 WARN (Source Code Disclosure - /WEB-INF folder - Active/release) -10047 WARN (HTTPS Content Available via HTTP - Active/beta) +10044 FAIL (Big Redirect Detected (Potential Sensitive Information Leak) - Passive/beta) +10045 FAIL (Source Code Disclosure - /WEB-INF folder - Active/release) +10047 FAIL (HTTPS Content Available via HTTP - Active/beta) 10048 FAIL (Remote Code Execution - Shell Shock - Active/beta) -10050 WARN (Retrieved from Cache - Passive/beta) -10051 WARN (Relative Path Confusion - Active/beta) -10052 WARN (X-ChromeLogger-Data (XCOLD) Header Information Leak - Passive/beta) -10053 WARN (Apache Range Header DoS (CVE-2011-3192) - Active/beta) -10054 WARN (Cookie without SameSite Attribute - Passive/release) -10055 WARN (CSP - Passive/release) -10056 WARN (X-Debug-Token Information Leak - Passive/release) -10057 WARN (Username Hash Found - Passive/release) +10050 FAIL (Retrieved from Cache - Passive/beta) +10051 FAIL (Relative Path Confusion - Active/beta) +10052 FAIL (X-ChromeLogger-Data (XCOLD) Header Information Leak - Passive/beta) +10053 FAIL (Apache Range Header DoS (CVE-2011-3192) - Active/beta) +10054 FAIL (Cookie without SameSite Attribute - Passive/release) +10055 FAIL (CSP - Passive/release) +10056 FAIL (X-Debug-Token Information Leak - Passive/release) +10057 FAIL (Username Hash Found - Passive/release) 10058 FAIL (GET for POST - Active/beta) -10061 WARN (X-AspNet-Version Response Header - Passive/release) +10061 FAIL (X-AspNet-Version Response Header - Passive/release) 10062 FAIL (PII Disclosure - Passive/beta) -10095 IGNORE (Backup File Disclosure - Active/beta) -10096 WARN (Timestamp Disclosure - Passive/release) -10097 WARN (Hash Disclosure - Passive/beta) -10098 WARN (Cross-Domain Misconfiguration - Passive/release) -10104 WARN (User Agent Fuzzer - Active/beta) -10105 WARN (Weak Authentication Method - Passive/release) -10106 IGNORE (HTTP Only Site - Active/beta) -10107 WARN (Httpoxy - Proxy Header Misuse - Active/beta) -10108 WARN (Reverse Tabnabbing - Passive/beta) -10109 WARN (Modern Web Application - Passive/beta) +10095 FAIL (Backup File Disclosure - Active/beta) +10096 FAIL (Timestamp Disclosure - Passive/release) +10097 FAIL (Hash Disclosure - Passive/beta) +10098 FAIL (Cross-Domain Misconfiguration - Passive/release) +10104 FAIL (User Agent Fuzzer - Active/beta) +10105 FAIL (Weak Authentication Method - Passive/release) +10106 FAIL (HTTP Only Site - Active/beta) +10107 FAIL (Httpoxy - Proxy Header Misuse - Active/beta) +10108 FAIL (Reverse Tabnabbing - Passive/beta) +10109 FAIL (Modern Web Application - Passive/beta) +# With DEBUG=True Django's debug toolbar uses links which triggers this rule +# The debug toolbar doesn't run in production +10109 OUTOFSCOPE http://app:8080.* 10202 FAIL (Absence of Anti-CSRF Tokens - Passive/release) -2 WARN (Private IP Disclosure - Passive/release) +2 FAIL (Private IP Disclosure - Passive/release) 20012 FAIL (Anti-CSRF Tokens Check - Active/beta) -20014 WARN (HTTP Parameter Pollution - Active/beta) -20015 WARN (Heartbleed OpenSSL Vulnerability - Active/beta) -20016 WARN (Cross-Domain Misconfiguration - Active/beta) +20014 FAIL (HTTP Parameter Pollution - Active/beta) +20015 FAIL (Heartbleed OpenSSL Vulnerability - Active/beta) +20016 FAIL (Cross-Domain Misconfiguration - Active/beta) 20017 FAIL (Source Code Disclosure - CVE-2012-1823 - Active/beta) 20018 FAIL (Remote Code Execution - CVE-2012-1823 - Active/beta) -20019 WARN (External Redirect - Active/release) -3 WARN (Session ID in URL Rewrite - Passive/release) -30001 WARN (Buffer Overflow - Active/release) -30002 WARN (Format String Error - Active/release) -30003 WARN (Integer Overflow Error - Active/beta) -40003 WARN (CRLF Injection - Active/release) -40008 WARN (Parameter Tampering - Active/release) -40009 WARN (Server Side Include - Active/release) +20019 FAIL (External Redirect - Active/release) +3 FAIL (Session ID in URL Rewrite - Passive/release) +30001 FAIL (Buffer Overflow - Active/release) +30002 FAIL (Format String Error - Active/release) +30003 FAIL (Integer Overflow Error - Active/beta) +40003 FAIL (CRLF Injection - Active/release) +40008 FAIL (Parameter Tampering - Active/release) +40009 FAIL (Server Side Include - Active/release) 40012 FAIL (Cross Site Scripting (Reflected) - Active/release) 40013 FAIL (Session Fixation - Active/beta) 40014 FAIL (Cross Site Scripting (Persistent) - Active/release) @@ -90,32 +106,36 @@ 40025 FAIL (Proxy Disclosure - Active/beta) 40026 FAIL (Cross Site Scripting (DOM Based) - Active/beta) 40027 FAIL (SQL Injection - MsSQL - Active/beta) -40028 WARN (ELMAH Information Leak - Active/release) -40029 WARN (Trace.axd Information Leak - Active/beta) +40028 FAIL (ELMAH Information Leak - Active/release) +40029 FAIL (Trace.axd Information Leak - Active/beta) 40032 FAIL (.htaccess Information Leak - Active/release) 40034 FAIL (.env Information Leak - Active/beta) 40035 FAIL (Hidden File Finder - Active/beta) 41 FAIL (Source Code Disclosure - Git - Active/beta) -42 WARN (Source Code Disclosure - SVN - Active/beta) -43 WARN (Source Code Disclosure - File Inclusion - Active/beta) -50000 WARN (Script Active Scan Rules - Active/release) -50001 WARN (Script Passive Scan Rules - Passive/release) -6 WARN (Path Traversal - Active/release) -7 WARN (Remote File Inclusion - Active/release) -90001 WARN (Insecure JSF ViewState - Passive/release) -90011 WARN (Charset Mismatch - Passive/release) -90017 WARN (XSLT Injection - Active/beta) -90019 WARN (Server Side Code Injection - Active/release) +42 FAIL (Source Code Disclosure - SVN - Active/beta) +43 FAIL (Source Code Disclosure - File Inclusion - Active/beta) +50000 FAIL (Script Active Scan Rules - Active/release) +50001 FAIL (Script Passive Scan Rules - Passive/release) +6 FAIL (Path Traversal - Active/release) +7 FAIL (Remote File Inclusion - Active/release) +90001 FAIL (Insecure JSF ViewState - Passive/release) +90011 FAIL (Charset Mismatch - Passive/release) +90017 FAIL (XSLT Injection - Active/beta) +90019 FAIL (Server Side Code Injection - Active/release) 90020 FAIL (Remote OS Command Injection - Active/release) -90021 WARN (XPath Injection - Active/beta) -90022 WARN (Application Error Disclosure - Passive/release) -90023 WARN (XML External Entity Attack - Active/beta) -90024 WARN (Generic Padding Oracle - Active/beta) -90025 WARN (Expression Language Injection - Active/beta) -90026 WARN (SOAP Action Spoofing - Active/alpha) -90027 IGNORE (Cookie Slack Detector - Active/beta) -90028 WARN (Insecure HTTP Method - Active/beta) -90029 WARN (SOAP XML Injection - Active/alpha) -90030 WARN (WSDL File Detection - Passive/alpha) -90033 WARN (Loosely Scoped Cookie - Passive/release) -90034 WARN (Cloud Metadata Potentially Exposed - Active/beta) +90021 FAIL (XPath Injection - Active/beta) +90022 FAIL (Application Error Disclosure - Passive/release) +90023 FAIL (XML External Entity Attack - Active/beta) +90024 FAIL (Generic Padding Oracle - Active/beta) +90025 FAIL (Expression Language Injection - Active/beta) +90026 FAIL (SOAP Action Spoofing - Active/alpha) +90027 FAIL (Cookie Slack Detector - Active/beta) +90028 FAIL (Insecure HTTP Method - Active/beta) +90029 FAIL (SOAP XML Injection - Active/alpha) +90030 FAIL (WSDL File Detection - Passive/alpha) +90033 FAIL (Loosely Scoped Cookie - Passive/release) +# With DEBUG=True Django's internal server returns a Set-Cookie header that appears +# to trigger this rule even though it has no domain scope. And the cookie header +# isn't sent this way on production +90033 OUTOFSCOPE http://app:8080.*$ +90034 FAIL (Cloud Metadata Potentially Exposed - Active/beta)