Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
VENOM sample HTTP security response headers test suites.
name: HTTP security response headers test suites
# TOOLS
# VENOM HOME: https://github.com/ovh/venom
# VENOM RELEASE: https://github.com/ovh/venom/releases
# VENOM ASSERTION KEYWORDS: https://github.com/ovh/venom#assertion
# REF AND RUN
# REF BASE: https://owasp.org/www-project-secure-headers/
# RUN CMD: venom run --var="target_site=https://righettod.eu" venom_security_headers_tests_suite.yml
# venom run --var="target_site=https://righettod.eu" --var="internet_facing=true" venom_security_headers_tests_suite.yml
# venom run --var="target_site=https://righettod.eu" --var="internet_facing=true" --var="logout_url=/logout" venom_security_headers_tests_suite.yml
vars:
target_site: ""
logout_url: ""
internet_facing: false
testcases:
###############################################
## ACTIVE RECOMMENDED HEADERS
###############################################
- name: Strict-Transport-Security
steps:
- type: http
method: GET
url: {{.target_site}}
skip_body: true
#info: Header are {{.result.headers}}
timeout: 20
assertions:
- result.statuscode ShouldEqual 200
- result.headers.strict-transport-security ShouldNotBeNil
- result.headers.strict-transport-security ShouldContainSubstring "includeSubDomains"
- result.headers.strict-transport-security ShouldContainSubstring "max-age="
- result.headers.strict-transport-security ShouldNotContainSubstring "max-age=0"
- result.headers.strict-transport-security ShouldContainSubstring "preload"
- name: X-Frame-Options
steps:
- type: http
method: GET
url: {{.target_site}}
skip_body: true
#info: Header are {{.result.headers}}
timeout: 20
assertions:
- result.statuscode ShouldEqual 200
- result.headers.x-frame-options ShouldNotBeNil
- result.headers.x-frame-options ShouldEqual "deny"
- name: X-Content-Type-Options
steps:
- type: http
method: GET
url: {{.target_site}}
skip_body: true
#info: Header are {{.result.headers}}
timeout: 20
assertions:
- result.statuscode ShouldEqual 200
- result.headers.x-content-type-options ShouldNotBeNil
- result.headers.x-content-type-options ShouldEqual "nosniff"
- name: Content-Security-Policy
steps:
- type: http
method: GET
url: {{.target_site}}
skip_body: true
#info: Header are {{.result.headers}}
timeout: 20
assertions:
- result.statuscode ShouldEqual 200
- result.headers.content-security-policy ShouldNotBeNil
- result.headers.content-security-policy ShouldNotContainSubstring "unsafe"
- name: X-Permitted-Cross-Domain-Policies
steps:
- type: http
method: GET
url: {{.target_site}}
skip_body: true
#info: Header are {{.result.headers}}
timeout: 20
assertions:
- result.statuscode ShouldEqual 200
- result.headers.x-permitted-cross-domain-policies ShouldNotBeNil
- result.headers.x-permitted-cross-domain-policies ShouldEqual "none"
- name: Referrer-Policy
steps:
- type: http
method: GET
url: {{.target_site}}
skip_body: true
#info: Header are {{.result.headers}}
timeout: 20
assertions:
- result.statuscode ShouldEqual 200
- result.headers.referrer-policy ShouldNotBeNil
- result.headers.referrer-policy ShouldEqual "no-referrer"
- name: Clear-Site-Data
steps:
- type: http
method: GET
url: {{.target_site}}/{{.logout_url}}
skip_body: true
#info: Header are {{.result.headers}}
timeout: 20
assertions:
- result.statuscode ShouldEqual 200
- result.headers.clear-site-data ShouldNotBeNil
- result.headers.clear-site-data ShouldContainSubstring "cookies"
- result.headers.clear-site-data ShouldContainSubstring "storage"
- name: Cross-Origin-Embedder-Policy
steps:
- type: http
method: GET
url: {{.target_site}}
skip_body: true
#info: Header are {{.result.headers}}
timeout: 20
assertions:
- result.statuscode ShouldEqual 200
- result.headers.cross-origin-embedder-policy ShouldNotBeNil
- result.headers.cross-origin-embedder-policy ShouldEqual "require-corp"
- name: Cross-Origin-Opener-Policy
steps:
- type: http
method: GET
url: {{.target_site}}
skip_body: true
#info: Header are {{.result.headers}}
timeout: 20
assertions:
- result.statuscode ShouldEqual 200
- result.headers.cross-origin-opener-policy ShouldNotBeNil
- result.headers.cross-origin-opener-policy ShouldEqual "same-origin"
- name: Cross-Origin-Resource-Policy
steps:
- type: http
method: GET
url: {{.target_site}}
skip_body: true
#info: Header are {{.result.headers}}
timeout: 20
assertions:
- result.statuscode ShouldEqual 200
- result.headers.cross-origin-resource-policy ShouldNotBeNil
- result.headers.cross-origin-resource-policy ShouldEqual "same-origin"
- name: Permissions-Policy
steps:
- type: http
method: GET
url: {{.target_site}}
skip_body: true
#info: Header are {{.result.headers}}
timeout: 20
assertions:
- result.statuscode ShouldEqual 200
- result.headers.permissions-policy ShouldNotBeNil
- result.headers.permissions-policy ShouldNotContainSubstring "*"
###############################################
## DEPRECATED OR ALMOST DEPRECATED HEADERS
###############################################
- name: Feature-Policy
steps:
- type: http
method: GET
url: {{.target_site}}
skip_body: true
info: This header was split into Permissions-Policy and Document-Policy and will be considered deprecated once all impacted features are moved off of feature policy.
timeout: 20
assertions:
- result.statuscode ShouldEqual 200
- result.headers.feature-policy ShouldNotBeNil
- result.headers.feature-policy ShouldNotContainSubstring "*"
- name: Public-Key-Pins
steps:
- type: http
method: GET
url: {{.target_site}}
skip_body: true
info: This header has been deprecated by all major browsers and is no longer recommended. Avoid using it, and update existing code if possible!
timeout: 20
assertions:
- result.statuscode ShouldEqual 200
- result.headers.public-key-pins ShouldBeNil
- name: Expect-CT
steps:
- type: http
method: GET
url: {{.target_site}}
skip_body: true
info: This header will likely become obsolete in June 2021. Since May 2018 new certificates are expected to support SCTs by default. Certificates before March 2018 were allowed to have a lifetime of 39 months, those will all be expired in June 2021.
timeout: 20
assertions:
- result.statuscode ShouldEqual 200
- result.headers.expect-ct ShouldNotBeNil
- result.headers.expect-ct ShouldContainSubstring "enforce"
- result.headers.expect-ct ShouldContainSubstring "max-age="
- result.headers.expect-ct ShouldNotContainSubstring "max-age=0"
- name: X-Xss-Protection
steps:
- type: http
method: GET
url: {{.target_site}}
skip_body: true
info: The X-XSS-Protection header has been deprecated by modern browsers and its use can introduce additional security issues on the client side.
timeout: 20
assertions:
- result.statuscode ShouldEqual 200
- result.headers.x-xss-protection ShouldNotBeNil
- result.headers.x-xss-protection ShouldEqual "0"
###############################################
## EXTRA TEST FOR INTERNET EXPOSED APP
## CHECK SECURITYHEADERS.COM RATING
###############################################
- name: SecurityHeaders-Rating
skip:
- internet_facing ShouldEqual true
steps:
- type: http
method: GET
url: https://securityheaders.com/?q={{.target_site}}&hide=on&followRedirects=on
skip_body: true
timeout: 20
assertions:
- result.statuscode ShouldEqual 200
- result.headers.x-grade ShouldNotBeNil
- result.headers.x-grade ShouldEqual "A"
@righettod

This comment has been minimized.

Copy link
Owner Author

@righettod righettod commented Feb 14, 2021

Execution example in case of a non-internet facing application (last test was skipped):

image

Execution example in case of a internet facing application (last test was performed):

image

Live usage example:

asciicast

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment