.. _developers_csp: Content Security Policy (CSP) ============================= Content-Security-Policy is the name of a HTTP response header that modern browsers use to enhance the security of the document (or web page). The ``Content-Security-Policy`` header allows you to restrict how resources such as JavaScript, CSS, or pretty much anything that the browser loads. -- `CSP Quick Reference Guide`_ Open Forms supports (fairly) strict CSP configurations, which happen to be required in environments implementing :ref:`DigiD authentication`. Summarized, the Open Forms CSP protects against Cross Site Scripting (XSS) by blocking unsafe constructs, such inline scripts, use of ``eval`` and inline styles. This section describes the rationale behind the policies in Open Forms when Open Forms serves the end-user forms *and* the considerations for third parties who :ref:`embed ` forms using the SDK. Basic mechanism --------------- The idea behind CSP is that when an end-user visits a page in their browser, the application serving that page sends a HTTP Header describing the security policy. Browser implementations are then responsible for acting according to this policy. This way, the application is able to mark which *resources* are expected/required for the application to work, and the browser blocks anything that is unexpected and potentially dangerous. The goal should always be to define a policy that is as strict as possible. Open Forms CSP -------------- Open Forms itself provides pages for end-user to fill out forms, so CSP is relevant. The policy is built based on: * any resources served by the domain serving the page are allowed (CSS, JS, fonts, images...). These are static assets backed by trusted Open Forms source code. * additionally, we allow assets from the SDK base URL, i.e. the domain where the SDK is hosted. This *may* be different from the Open Forms backend domain and is up to the service provider offering Open Forms. * For images, we also allow the services from `PDOK `_, required for the maps components. * For images, we also allow ``data:`` URIs, used by the map and signature component. To make some aspects that are blocked explicit: * No ``eval`` is allowed. * Inline scripts are blocked. In certain places inline scripts are needed, which operate via the CSP nonce mechanism. * Inline styles are blocked. Open Forms passes the nonce to the SDK for WYSIWYG content which may contain inline styles so that it can be post-processed. More details about this in :ref:`developers_csp_wysiwyg`. * Third party CDNs are blocked. .. _developers_csp_sdk_embedding: Embedding using the SDK ----------------------- The :ref:`SDK ` is developed with care to be usable in strict CSP environments. All source code is bundled into Javascript, CSS and other static assets. Where relevant, external dependencies have been included in the SDK bundle itself - we do not rely on external CDNs (such as the Formio CDN, Google Fonts...). **CSP requirements** * The domain where the SDK is hosted must be included in the ``default-src``, otherwise your application cannot load the Javascript, CSS, fonts or image assets. * The ``img-src`` requires ``https://service.pdok.nl/``, otherwise map components break. * The ``img-src`` requires ``data:``, otherwise map and signature components break. * If Google Tag manager is enabled, the ``img-src`` requires ``www.googletagmanager.com`` to allow the execution of the Tag Manager container code. More information can be found `here`_. .. _here: https://developers.google.com/tag-platform/tag-manager/web/csp#enable_the_container_tag_to_use_csp **CSP and WYSIWYG** Some form design relies on WYSIWYG editors, which results in HTML blobs in API endpoint resources that potentially have inline style (``...``). The SDK uses React's |dangerouslySetInnerHTML|_ for this content. One of the SDK :ref:`embed options ` is the ``CSPNonce``. If embedding pages include this, then the WYSIWYG content will be post-processed to include an inline ``

This is some markup.

It has inline styles.

**How do we keep this secure?** * We explicitly mark WYSIWYG fields as post-processable, rather than applying the post-processing globally. This works with an opt-in mechanism and is easily auditable. * The embedding page controls the value of the nonce. If correctly implemented, attackers can not guess this value. Additionally, the embedding page chooses to pass this value to the SDK initialization. * The SDK code itself must opt-in to use ``dangerouslySetInnerHTML`` and only does so on known WYSIWYG content, making this easily auditable. * The post-processing is limited to detecting inline ``style`` *attributes*. Any inline ``