DISCOURSE_CDN_URL causes content security policy violations?

I don’t know how I’m screwing this up. I can’t see how I’m the only one facing what looks like a bug.

If I define

  DISCOURSE_CDN_URL: https://lcsupport-92e2.kxcdn.com

in the env: stanza in my yml for a fairly standard multisite configuration. All of the CDN urls get rejected by the browser as a CSP error.

content security policy script src claims “Additional whitelisted script sources. The current host and CDN are included by default. See Mitigate XSS Attacks with Content Security Policy.”, but when I define it (or add/remove it to discourse.conf and sv restart unicorn), I get this:

even with content security policy report only set to true, the site still won’t load.

Turning off content_security_policy or adding the CDN URL to content security policy script src seems to be required to get the browser to load the assets.

here is my yml.

1 Like

CDN URLs should be computed and included in the CSP by default. Could you also provide (or try comparing) the actual CSP served in the header and the source of the blocked assets?

6 Likes

Here is the header:

content-security-policy-report-only: base-uri 'none'; object-src 'none'; script-src 'report-sample' 
https://support.literatecomputing.com/logs/ 
https://support.literatecomputing.com/sidekiq/ 
https://support.literatecomputing.com/mini-profiler-resources/ 
https://abedmulti-92e2.kxcdn.com/uploads/assets/ 
https://abedmulti-92e2.kxcdn.com/uploads/brotli_asset/ 
https://support.literatecomputing.com/extra-locales/ 
https://lcsupport-92e2.kxcdn.com/highlight-js/ 
https://lcsupport-92e2.kxcdn.com/javascripts/ 
https://lcsupport-92e2.kxcdn.com/plugins/ 
https://lcsupport-92e2.kxcdn.com/theme-javascripts/ 
https://lcsupport-92e2.kxcdn.com/svg-sprite/ 
https://www.google-analytics.com/analytics.js 
https://tagmanager.google.com/ 
https://www.googletagmanager.com/; worker-src 'self' blob:

Here are the ENV variables inside the container:

root@support-multi:/var/www/discourse# echo $DISCOURSE_S3_UPLOAD_BUCKET 
abed-multi/uploads
root@support-multi:/var/www/discourse# echo $DISCOURSE_S3_CDN_URL 
https://abedmulti-92e2.kxcdn.com/uploads

Here is the CDN URL from discourse.conf:

cdn_url = 'https://lcsupport-92e2.kxcdn.com'

and rails:

[1] pry(main)> GlobalSetting.cdn_url
=> "https://lcsupport-92e2.kxcdn.com"

And here is the URL for one of the assets that won’t load: https://lcsupport-92e2.kxcdn.com/brotli_asset/preload-store-d32dcf974dddcac742f8a7a6aa7fcd686185920b201029d0ecb2b85527ef9034.js

2 Likes

So we have this in the CSP

https://abedmulti-92e2.kxcdn.com/uploads/assets/ 
https://abedmulti-92e2.kxcdn.com/uploads/brotli_asset/
# i.e. DISCOURSE_S3_CDN_URL + /brotli_asset/

But the actual address is

https://lcsupport-92e2.kxcdn.com/brotli_asset/preload-store-d32dcf974dddcac742f8a7a6aa7fcd686185920b201029d0ecb2b85527ef9034.js
# i.e. DISCOURSE_CDN_URL + /brotli_asset/...

The relevant CSP code:

https://github.com/discourse/discourse/blob/49843f327e88538a487d37b5d3c288da15b99908/lib/content_security_policy/default.rb#L23-L42

We prioritize using DISCOURSE_S3_CDN_URL for assets when available. This aligns with the CDN asset URL generation.

@pfaffman Does GlobalSetting.use_s3? return true for your site?

I wonder if we need an additional GlobalSetting.use_s3? check here. Does having GlobalSetting.s3_cdn_url necessarily imply GlobalSetting.use_s3?? I’m a bit hazy with asset genereation / S3 CDN now :sweat_smile: could someone more familiar with it also take a look? Thanks!

7 Likes

Well, I tried setting use_s3 and then rake assets:precompile and there’s no change.

I’ve somewhere else had this issue where there was confusion about whether assets were in s3 or local (or their CDN mirrors).

1 Like