Skip to content

Commit

Permalink
Apply December 2022 CSP intentions
Browse files Browse the repository at this point in the history
This removes unsafe-inline from script and data images.

It sets a nonce-generator which will apply to script-src. Having a nonce in a
CSP will cause any unsafe-inline rules to be ignored, so if an app needs them
they will have to both add the directive unsafe-inline to script-src and
also disable the nonce-generator.

I initially planned for this to remove unsafe-inline from style as well,
however I learnt in the latter stages of testing, that there is Govspeak
that uses inline style attributes [1][2] (example page: [3]). I have
ideas on how to fix this but it will take some time, so I'm deferring
this until later.

[1]: https://kramdown.gettalong.org/syntax.html#tables
[2]: https://github.com/alphagov/govspeak/blob/5642fcc4231f215d1c58ad7feb30ca42fb8cfb91/lib/govspeak/html_sanitizer.rb#L72-L73
[3]: https://www.gov.uk/government/statistics/non-association-independent-schools-inspections-and-outcomes-in-england-august-2022/main-findings-non-association-independent-schools-inspections-and-outcomes-in-england-august-2022
  • Loading branch information
kevindew committed Jan 23, 2023
1 parent 13083f8 commit 19b2875
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 13 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Unreleased

* BREAKING: Content Security Policy forbids unsafe-inline script-src and data: image-src. It provides a nonce generator. Apps that can't support this will need to amend their CSP configuration in an initializer.

# 4.13.0

* Flush log writes to stdout immediately so that structured (JSON) logs are not lost on crash or delayed indefinitely.
Expand Down
35 changes: 22 additions & 13 deletions lib/govuk_app_config/govuk_content_security_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,8 @@ def self.build_policy(policy)
policy.default_src :self

# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/img-src
# Note: we purposely don't include data here because it produces a security risk.
policy.img_src :self,
# This allows Base64 encoded images, but is a security
# risk as it can embed third party resources.
# As of December 2022, we intend to remove this prior
# to making the CSP live.
:data,
*GOVUK_DOMAINS,
*GOOGLE_ANALYTICS_DOMAINS, # Tracking pixels
# Speedcurve real user monitoring (RUM) - as per: https://support.speedcurve.com/docs/add-rum-to-your-csp
Expand All @@ -45,25 +41,28 @@ def self.build_policy(policy)
"https://img.youtube.com"

# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src
# Note: we purposely don't include data:, unsfafe-inline or unsafe-eval because
# they are security risks, if you need them for a legacy app please only apply them at
# an app level.
policy.script_src :self,
*GOOGLE_ANALYTICS_DOMAINS,
*GOOGLE_STATIC_DOMAINS,
# Allow YouTube Embeds (Govspeak turns YouTube links into embeds)
"*.ytimg.com",
"www.youtube.com",
"www.youtube-nocookie.com",
# This allows inline scripts and thus is a XSS risk.
# As of December 2022, we intend to work towards removing
# this from apps that don't use jQuery 1.12 (which needs
# this) once we've set up nonces.
:unsafe_inline
"www.youtube-nocookie.com"

# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src
# Note: we purposely don't include data: or unsafe-eval because
# they are security risks, if you need them for a legacy app please only apply them at
# an app level.
policy.style_src :self,
*GOOGLE_STATIC_DOMAINS,
# This allows style="" attributes and style elements.
# As of December 2022, we intend to remove this prior
# to making the CSP live due to the security risks it has.
# As of January 2023 our intentions to remove this were scuppered
# by Govspeak [1] using inline styles on tables. Until that
# is resolved we'll keep unsafe_inline
# [1]: https://github.com/alphagov/govspeak/blob/5642fcc4231f215d1c58ad7feb30ca42fb8cfb91/lib/govspeak/html_sanitizer.rb#L72-L73
:unsafe_inline

# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/font-src
Expand Down Expand Up @@ -91,6 +90,16 @@ def self.build_policy(policy)
def self.configure
Rails.application.config.content_security_policy_report_only = ENV.include?("GOVUK_CSP_REPORT_ONLY")

# Sets a nonce per request that is set in the CSP directives for script_src and
# style_src.
# Note: if an applications needs to set unsafe-inline they will need to unset this nonce too (by setting
# this config option to nil)
Rails.application.config.content_security_policy_nonce_generator = ->(_request) { SecureRandom.base64(16) }

# This only applies the nonce generator to the script-src directive. We need this to
# use unsafe-inline for style-src as a nonce will override it.
Rails.application.config.content_security_policy_nonce_directives = %w[script-src]

policy = Rails.application.config.content_security_policy(&method(:build_policy))

# # allow apps to customise the CSP by passing a block e.g:
Expand Down

0 comments on commit 19b2875

Please sign in to comment.