core.securityheaders

This module provides configuration for most of the http security headers. The features currently supported are:

If a feature is not yet supported, you could always set the header directly (e.g. by attaching a request preprocessor). ViUR contains a default configuration for most of these headers where possible, however manual review is mandatory for each project.

The content security policy will prevent inline css and javascript by default, but is configured to allow embedding images from cloud-storage and sign-in with google.

Strict transport security is enabled by default (with a TTL of one year), but without preload or include-subdomains.

X-Frame-Options is limited to the same origin, preventing urls from this project from being embedded in iframes that don’t originate from the same origin.

X-XSS-Protection is enabled.

X-Content-Type-Options is set to nosniff

X-Permitted-Cross-Domain-Policies is set to “none”, denying embedding resources in pdf files and the like

Referrer-Policy is set to strict-origin, preventing leakage of URLs to 3rd-partys.

The Permissions-Policy will only allow auto-play by default (thus access to the camera-api etc. is disabled)

Cross origin isolation is currently disabled by default (as it’s incompatible with many popular services like embedding a map or sign-in with google).

CSP violations used to be reported through the report-uri directive, which carries its url itself. That directive is deprecated since CSP Level 3 and superseded by the Reporting-API: endpoints are declared once in the Reporting-Endpoints header and referenced by name, by the CSP-directive report-to as well as by other headers. Browsers that support it ignore report-uri once both are present, so keeping the old directive around does not keep the reports flowing on its own.

No reporting endpoints are configured by default; see set_reporting_endpoint() on how to receive reports.

ViUR also protects it’s cookies by default (setting httponly, secure and samesite=lax). This can be changed by setting the corresponding class-level variables on class:Session<viur.core.session.Session>.

Attributes

_REPORTING_ENDPOINT_NAME_RE

validReferrerPolicies

Functions

addCspRule(objectType, srcOrDirective[, enforceMode])

This function helps configuring and reporting of content security policy rules and violations.

_rebuildCspHeaderCache()

Rebuilds the internal conf.security.content_security_policy["_headerCache"] dictionary, ie. it constructs

extendCsp([additionalRules, overrideRules])

Adds additional csp rules to the current request. ViUR will emit a default csp-header based on the

set_reporting_endpoint(name, url)

Configure a named endpoint reports are being sent to.

_build_reporting_endpoints_header()

Build the value of the Reporting-Endpoints header.

_validate_reporting_config()

Ensure the reporting configuration as a whole is sane.

_validate_reporting_endpoint(name, url)

Ensure a reporting endpoint can be emitted as Reporting-Endpoints header without breaking it.

enableStrictTransportSecurity([maxAge, ...])

Enables HTTP strict transport security.

setXFrameOptions(action[, uri])

Sets X-Frame-Options to prevent click-jacking attacks.

setXXssProtection(enable)

Sets X-XSS-Protection header. If set, mode will always be block.

setXContentTypeNoSniff(enable)

Sets X-Content-Type-Options if enable is true, otherwise no header is emited.

setXPermittedCrossDomainPolicies(value)

setReferrerPolicy(policy)

_rebuildPermissionHeaderCache()

Rebuilds the internal conf.security.permissions_policy["_headerCache"] string, ie. it constructs

setPermissionPolicyDirective(directive, allowList)

Set the permission policy.

setCrossOriginIsolation(coep, coop, corp)

Configures the cross origin isolation header that ViUR may emit. This is necessary to enable features like

Module Contents

core.securityheaders._REPORTING_ENDPOINT_NAME_RE
core.securityheaders.addCspRule(objectType, srcOrDirective, enforceMode='monitor')

This function helps configuring and reporting of content security policy rules and violations. To enable CSP, call addCspRule() from your projects main file before calling server.setup().

# Example Usage

# Enable CSP for all types and made us the only allowed source
security.addCspRule("default-src","self","enforce")

# Start a new set of rules for stylesheets whitelist us
security.addCspRule("style-src","self","enforce")

# This is currently needed for TextBones!
security.addCspRule("style-src","unsafe-inline","enforce")

If you don’t want these rules to be enforced and just getting a report of violations replace “enforce” with “monitor”. To have violations reported, name an endpoint configured via set_reporting_endpoint():

security.set_reporting_endpoint("csp", "/cspReport")
security.addCspRule("report-to", "csp", "enforce")

and register a function at /cspReport to handle the reports.

The older report-uri directive does the same without a named endpoint, but is deprecated since CSP Level 3. It is still worth adding for browsers that do not support the Reporting-API; those that do ignore it as soon as report-to is present:

security.addCspRule("report-uri", "/cspReport", "enforce")

..note:

Our tests showed that enabling a report-url on production systems has limited use. There are literally
thousands of browser-extensions out there that inject code into the pages displayed. This causes a whole
flood of violations-spam to your report-url.
Parameters:
  • objectType (str) – For which type of objects should this directive be enforced? (script-src, img-src, …)

  • srcOrDirective (str) – Either a domain which should be white-listed or a CSP-Keyword like ‘self’, ‘unsafe-inline’, etc.

  • enforceMode (str) – Should this directive be enforced or just logged?

core.securityheaders._rebuildCspHeaderCache()

Rebuilds the internal conf.security.content_security_policy[“_headerCache”] dictionary, ie. it constructs the Content-Security-Policy-Report-Only and Content-Security-Policy headers based on what has been passed to ‘addRule’ earlier on. Should not be called directly.

core.securityheaders.extendCsp(additionalRules=None, overrideRules=None)

Adds additional csp rules to the current request. ViUR will emit a default csp-header based on the project-wide config. For some requests, it’s needed to extend or override these rules without having to include them in the project config. Each dictionary must be in the same format as the conf.security.content_security_policy. Values in additionalRules will extend the project-specific configuration, while overrideRules will replace them.

..Note: This function will only work on CSP-Rules in “enforce” mode, “monitor” is not suppored

Parameters:
  • additionalRules (dict) – Dictionary with additional csp-rules to emit

  • overrideRules (dict) – Values in this dictionary will override the corresponding default rule

Return type:

None

core.securityheaders.set_reporting_endpoint(name, url)

Configure a named endpoint reports are being sent to.

All endpoints configured this way are emitted as Reporting-Endpoints http-header with each request. Other headers reference an endpoint by its name, i.e. the CSP-directive report-to:

# Example Usage

security.set_reporting_endpoint("csp", "/cspReport")
security.addCspRule("report-to", "csp", "enforce")

The name default is special: the browser uses it for reports whose header cannot name an endpoint on its own, as well as for reports not caused by a header at all (i.e. deprecation reports).

The endpoint receives a POST with the content-type application/reports+json, carrying a list of reports rather than a single one: browsers queue them up and deliver a batch a few seconds later. The deprecated report-uri directive behaves differently, it posts one application/csp-report per violation right away. Reports of a violation also name the precise directive (style-src-elem), where the legacy format falls back to the broader one (style-src).

Note

Reports are only sent from a https origin, and only to a https endpoint. A relative url inherits the scheme of the document, so a development server on plain http receives nothing – not even when the endpoint is given as an absolute https url. Putting a TLS proxy in front of the development server is enough to make reporting work locally.

Note

Browsers supporting report-to ignore report-uri once both directives are present. Keeping the deprecated one around therefore only serves browsers without Reporting-API support; it is no way around the https requirement.

Note

Our tests showed that enabling reporting on production systems has limited use. There are literally thousands of browser-extensions out there that inject code into the pages displayed. This causes a whole flood of violations-spam to your endpoint.

Parameters:
  • name (str) – The name other headers use to reference this endpoint.

  • url (str | None) – The url the reports are sent to. Pass None to remove a previously configured endpoint.

Raises:

ValueError – If either name or url is unsuitable.

Return type:

None

core.securityheaders._build_reporting_endpoints_header()

Build the value of the Reporting-Endpoints header.

Uses what has been passed to set_reporting_endpoint() earlier on. An empty string is returned if no endpoint is configured, in which case the header must be omitted. Should not be called directly.

Return type:

str

core.securityheaders._validate_reporting_config()

Ensure the reporting configuration as a whole is sane.

Every configured endpoint must be emittable and each CSP report-to directive must name one of them. Called on startup, should not be called directly.

Raises:

ValueError – If a configured endpoint is unsuitable.

Return type:

None

core.securityheaders._validate_reporting_endpoint(name, url)

Ensure a reporting endpoint can be emitted as Reporting-Endpoints header without breaking it.

Raises:

ValueError – If either name or url is unsuitable.

Parameters:
  • name (str)

  • url (str)

Return type:

None

core.securityheaders.enableStrictTransportSecurity(maxAge=365 * 24 * 60 * 60, includeSubDomains=False, preload=False)

Enables HTTP strict transport security.

Parameters:
  • maxAge (int) – The time, in seconds, that the browser should remember that this site is only to be accessed using HTTPS.

  • includeSubDomains (bool) – If this parameter is set, this rule applies to all of the site’s subdomains as well.

  • preload (bool) – If set, we’ll issue a hint that preloading would be appreciated.

Return type:

None

core.securityheaders.setXFrameOptions(action, uri=None)

Sets X-Frame-Options to prevent click-jacking attacks. :param action: off | deny | sameorigin | allow-from :param uri: URL to whitelist

Parameters:
  • action (str)

  • uri (Optional[str])

Return type:

None

core.securityheaders.setXXssProtection(enable)

Sets X-XSS-Protection header. If set, mode will always be block. :param enable: Enable the protection or not. Set to None to drop this header

Parameters:

enable (Optional[bool])

Return type:

None

core.securityheaders.setXContentTypeNoSniff(enable)

Sets X-Content-Type-Options if enable is true, otherwise no header is emited. :param enable: Enable emitting this header or not

Parameters:

enable (bool)

Return type:

None

core.securityheaders.setXPermittedCrossDomainPolicies(value)
Parameters:

value (str)

Return type:

None

core.securityheaders.validReferrerPolicies = ['no-referrer', 'no-referrer-when-downgrade', 'origin', 'origin-when-cross-origin',...
core.securityheaders.setReferrerPolicy(policy)
Parameters:

policy (str) – The referrer policy to send

core.securityheaders._rebuildPermissionHeaderCache()

Rebuilds the internal conf.security.permissions_policy[“_headerCache”] string, ie. it constructs the actual header string that’s being emitted to the clients.

Return type:

None

core.securityheaders.setPermissionPolicyDirective(directive, allowList)
Set the permission policy.
param directive:

The directive to set. Must be one of https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy#directives

param allowList:

The list of allowed origins. Use “self” to allow the current domain. Empty list means the feature will be disabled by the browser (it’s not accessible by javascript)

Parameters:
  • directive (str)

  • allowList (Optional[list[str]])

Return type:

None

core.securityheaders.setCrossOriginIsolation(coep, coop, corp)

Configures the cross origin isolation header that ViUR may emit. This is necessary to enable features like SharedArrayBuffer. See https://web.dev/coop-coep for more information.

param coep:

If set True, we’ll emit Cross-Origin-Embedder-Policy: - require-corp

param coop:

The value for the Cross-Origin-Opener-Policy header. Valid values are - same-origin - same-origin-allow-popups - unsafe-none

param corp:

The value for the Cross-Origin-Resource-Policy header. Valid values are - same-site - same-origin - cross-origin

Parameters:
  • coep (bool)

  • coop (str)

  • corp (str)

Return type:

None