Skip to content

Commit

Permalink
Edits
Browse files Browse the repository at this point in the history
  • Loading branch information
sbreker committed Oct 26, 2023
1 parent a926839 commit 953b8e2
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 56 deletions.
5 changes: 5 additions & 0 deletions admin-manual/customization/config-files.rst
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,11 @@ such as:
are co-tenanted on the same server.
* ``treeview_items_per-page_max``: Increase the maximum allowed value for the
full-width :term:`treeview` paging limit - see: :ref:`fwt-items-per-page`
* ``response_header``: The CSP `repsonse_header` setting is used to set the CSP
header type and can have one of two values: `Content-Security-Policy` or
`Content-Security-Policy-Report-Only`
* ``directives``: The CSP `directives` setting contains the CSP policy that will
be sent in the CSP header.

.. image:: images/app-yml-settings.*
:align: center
Expand Down
156 changes: 100 additions & 56 deletions admin-manual/security/csp-headers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,8 @@ safer and more secure.
Server ->> Browser: HTTP Response
note over Browser: Verify reponse sources<br/>against values in CSP directive<br />rejecting any that do not match

Default Implementation for the Bootstrap 5 Dominion Theme
---------------------------------------------------------

The ``Content-Security-Policy`` header encompasses one or more
directives. Multiple directives get delineated with a semicolon (``;``).

The ``default-src`` directive doesn't inherently account for iframes. Hence,
the ``frame-ancestors`` directive can specify that the use of
elements such as ``<frame>``, ``<iframe>``, ``<object>``, ``<embed>``, and the likes
will only be permitted when sourced from the same origin:

Updating AtoM's CSP configuration
---------------------------------
AtoM's CSP configuration
------------------------

Here's the default configuration you'll find in AtoM's `app.yml` file:

Expand All @@ -84,50 +73,94 @@ Here's the default configuration you'll find in AtoM's `app.yml` file:
response_header: Content-Security-Policy
directives: "default-src 'self'; font-src 'self'; img-src 'self' https://www.gravatar.com/avatar/ blob:; script-src 'self' 'nonce'; style-src 'self' 'nonce'; worker-src 'self' blob:; frame-ancestors 'self';"
##TODO: This can exist in a few places depending on how you start AtoM. If you run it from Docker
The CSP `repsonse_header` setting is used to set the CSP header type and can have one of
two values:
- `Content-Security-Policy`:
This setting will enforce the defined policy. When set, the browser will block any
resources (scripts, images, stylesheets, etc.) that violate the policy directives.

- `Content-Security-Policy-Report-Only`:
This header works similarly to the `Content-Security-Policy` but does not block any
resources allowing developers to test and monitor potential violations without
affecting the functionality of the web page. This is useful for testing a new policy or
changes to an existing policy without risking breakage. Violations will be reported to
the browser's console.

The CSP `directives` setting contains the CSP policy that will be sent in the CSP header.
The value for the `directives` setting above is the default when the Dominion theme is
in use. Multiple directives get delineated with a semicolon (``;``).

.. IMPORTANT::
The value `'nonce'` in the above example is a placeholder and will be replaced
with a generated unique value when AtoM generates the page response.

Updating these settings will require restarting **php-fpm**.

CSP headers will only be applied to responses if a Bootstrap 5 based theme is in use.

Strategy for Working with Your Custom Theme
-------------------------------------------
CSP headers can be deactivated by deleting the CSP section from the `app.yml` file.

Implementing CSP Headers With Your Custom Theme
-----------------------------------------------

1. Begin with a Basic CSP Header Directive.

If your custom theme is derived from AtoM's Dominion Bootstrap 5 theme, begin
with the baseline CSP directive from AtoM 2.8's `app.yml``:

.. code-block:: plaintext
.. code-block:: plaintext
Content-Security-Policy-Report-Only: default-src 'self'; font-src 'self'; img-src 'self' https://www.gravatar.com/avatar/ blob:; script-src 'self' 'nonce'; style-src 'self' 'nonce'; worker-src 'self' blob:; frame-ancestors 'self';
For those who have crafted a custom theme, but haven't used AtoM's default Bootstrap 5
Dominion theme as a foundation, it's recommended to start with a more restrictive
`content-security-policy` header:
In app.yml this would look like:
.. code-block:: yaml
.. code-block:: plaintext
# Content Security Policy (CSP) header configuration. CSP settings apply
# only when a B5 theme is active, else these settings are bypassed.
csp:
response_header: Content-Security-Policy-Report-Only
directives: "default-src 'self'; font-src 'self'; img-src 'self' https://www.gravatar.com/avatar/ blob:; script-src 'self' 'nonce'; style-src 'self' 'nonce'; worker-src 'self' blob:; frame-ancestors 'self';"
For those who have crafted a custom theme, but haven't used AtoM's default Bootstrap 5
Dominion theme as a foundation, it's recommended to start with a more restrictive
`content-security-policy` header:

.. code-block:: plaintext
Content-Security-Policy-Report-Only: default-src 'self'; font-src 'self'; img-src 'self'; script-src 'self'; style-src 'self'; frame-ancestors 'self';
This example references the `Content-Security-Policy-Report-Only` header -
this header will log violations in Chrome's Developer Tools but will not
prevent a script from loading and running. This is helpful when developing a
policy so that the pages and all scripts still load properly - this ensures
all violations will be seen in the console log. When the policy definition is
ready to go live this CSP header type can be changed to
`Content-Security-Policy` to activate enforcement.

- default-src: if resources aren't mentioned in other sections, this policy is applied.
- font-src: stipulates which fonts can be loaded.
- img-src: stipulates which images can be loaded.
- script-src: stipulates which scripts can be loaded.
- style-src: stipulates which styles or CSS can be loaded.
- frame-ancestors 'self': determines which domains can embed the page as a frame.
In app.yml this would look like:
2. Monitor in the browser watching for CSP violations.
.. code-block:: yaml
The line number can be obtained from the error as shown in Chrome's dev tools console.
# Content Security Policy (CSP) header configuration. CSP settings apply
# only when a B5 theme is active, else these settings are bypassed.
csp:
response_header: Content-Security-Policy-Report-Only
directives: "default-src 'self'; font-src 'self'; img-src 'self'; script-src 'self'; style-src 'self'; frame-ancestors 'self';"
This example references the `Content-Security-Policy-Report-Only` header -
this header will log violations in Chrome's Developer Tools but will not
prevent a script from loading and running. This is helpful when developing a
policy so that the pages and all scripts still load properly - this ensures
all violations will be seen in the console log. When the policy definition is
ready to go live this CSP header type can be changed to
`Content-Security-Policy` to activate enforcement.

- default-src: if resources aren't mentioned in other sections, this policy is applied.
- font-src: stipulates which fonts can be loaded.
- img-src: stipulates which images can be loaded.
- script-src: stipulates which scripts can be loaded.
- style-src: stipulates which styles or CSS can be loaded.
- frame-ancestors 'self': determines which domains can embed the page as a frame.

Specifying `self` ensures that only trusted resources from the *same origin* are loaded
and executed.

TODO: Add pic here!
2. Monitor in the browser watching for CSP violations.

![Example: CSP warnings in the console in red when editing and authority record](../atom-b5-auth-csp-errors.png)
The line number can be obtained from the error as shown in Chrome's dev tools console.

3. Look for and fix any violations by adding nonce to inline script, style, etc.

Expand All @@ -137,44 +170,53 @@ TODO: Add pic here!
of the CSP policy by changing the header from
`Content-Security-Policy-Report-Only` to `Content-Security-Policy`.


Allowing Inline Sources
-----------------------

If your application has inline scripts there are 4 choices:

- Use 'unsafe-inline'.
1. Use 'unsafe-inline'.

This deactivates inline script validation. We don't really want to use
this.
Allowing 'unsafe-inline' in a CSP directive permits inline scripts or styles from
any source to run. While it offers design flexibility, it's discouraged due to
heightened risk of cross-site scripting (XSS) attacks. This setting can expose web
applications to malicious script injections, undermining CSP's security benefits
and so should be avoided.

- Add the hash of the script to the CSP directive.
2. Add the hash of the script to the CSP directive.

A hash of the inline script is provided in Chrome's dev tools and this hash
can be added to the CSP header to validate the script, but this method is
fragile, as the hash value will change if the script is updated, requiring
the CSP directive to need updating. Also if there are a lot of violations,
there will be a lot of hashes to add, creating a very messy CSP directive.
This method is fragile and should be avoided.
Adding a script's hash to the CSP directive allows for specific inline scripts
to execute based on their hashed content. While this method ensures only the
approved script runs, it's fragile because any change to the script's content
requires recalculating and updating its hash in the CSP. This can be cumbersome
and error-prone, especially with frequent script modifications.

- For a given request generate a random nonce value to be returned in the CSP
In addition, if there are a large number of violations, there could mean a lot of
hashes to add, creating a very messy CSP directive.

3. For a given request generate a random nonce value to be returned in the CSP
header directive and on each inline script, style etc tag.

Each inline script or style has to be flagged as 'ok' with a random nonce
value that is uniquely generated for a specific request/response pair. This
nonce must be included in the Header directive, and in each inline script
Each inline script or style has to be flagged as 'ok' with a nonce (a random
token) value that is uniquely generated for a specific request/response pair.
This nonce must be included in the Header directive, and in each inline script
(or style, font, img source) tag. If your application has lots of inline
scripts, styles and whatnot this could be a lot of work, but it will be
more robust than using script hashes.

```
Content-Security-Policy-Report-Only: default-src 'self'; font-src 'self'; img-src 'self' https://www.gravatar.com/avatar/; script-src 'self'; style-src 'self' 'nonce-abcd1234567890'; frame-ancestors 'self';
Content-Security_policy-Report-Only: default-src 'self'; font-src 'self'; img-src 'self' https://www.gravatar.com/avatar/ blob:; script-src 'self' 'nonce-abcd1234567890'; style-src 'self' 'nonce-abcd1234567890'; worker-src 'self' blob:; frame-ancestors 'self';
```

- Remove the inline asset! Refactor the code to move the inline asset to the
4. Remove the inline asset! Refactor the code to move the inline asset to the
script and style bundle. If it's an inline style can it be replaced with a
Bootstrap 5 equivalent?

Work completed to make the Dominion theme compatible with CSP headers can be viewed
in this `AtoM CSP commit`_. This commit provides examples of how to refer to the nonce
value generated by AtoM from your theme templates, and examples of refactoring code to
remove inline styles in favour of Bootstrap 5 equivalents.

Allowing External Sources
-------------------------

Expand Down Expand Up @@ -206,3 +248,5 @@ for this:

* :ref:`maintenance-web-analytics`
* :ref:`maps-api-key`

.. _`AtoM CSP commit`: https://github.com/artefactual/atom/commit/d796a1f7252aa6ce6c4ef611fac91939584df00b

0 comments on commit 953b8e2

Please sign in to comment.