mastodon / mastodon

Your self-hosted, globally interconnected microblogging community
https://joinmastodon.org
GNU Affero General Public License v3.0
47.24k stars 7k forks source link

Allow customization of CSP to allow third-party fonts #9349

Open jaredcwhite opened 6 years ago

jaredcwhite commented 6 years ago

Pitch

After the recent CSP header updates, the Google font I pulled in to customize my instance stopped working. I had this snippet of code in the "Custom CSS" field under the admin's "Site Settings":

@import url("https://fonts.googleapis.com/css?family=Fira+Sans:400,400i,700,700i");

body {
 font-family: 'Fira Sans', sans-serif;
}

I had to manually edit config/initializers/content_security_policy.rb and add the Google domain to the style_src directive and another domain for font_src.

It would be great if I could simply edit a configuration file or change something in the site admin to facilitate this instead.

Motivation

Changing files at the Rails app level isn't ideal — now I'll have to remember to save that change and discard it temporarily upon future upgrades, then reapply.

Thanks for your consideration! (P.S. I'm a Rails developer myself, so if you could recommend a simple course of action for this sort of thing, I'd be happy to submit a PR.)

nightpool commented 6 years ago

Changing files at the Rails app level isn't ideal — now I'll have to remember to save that change and discard it temporarily upon future upgrades, then reapply.

Or you could just commit the change, and then git will happily take care of merging every time you want to upgrade, helpfully informing you of upstream changes to the file. People use version control systems for a reason.

I do agree that this presents a little bit of a conflict with the custom css section though. We could mitigate this by using strict-dynamic, or maybe by preprocessing a list of trusted hosts from the custom CSS style when it's saved (but this would miss transitive dependencies and so wouldn't solve your font-source issue)

Gargron commented 6 years ago

Could you download the fonts from Google and put them in the fonts directory instead? I don't think your users will appreciate loading from Google.

ggtea commented 6 years ago

Instance admin can add 'proxy_hide_header Content-Security-Policy;' to nginx configuration to ignore upstream CSP and use their own CSP. So, admin can avoid CSP easily. no problem. Non-admin user who used to use custom CSS to modify Mastodon UI also faces same problem and they can't avoid CSP easily. I think this is the problem.

Download and place Google web fonts seems really tired task... because Google split web fonts into many files for minimize download size. https://fonts.googleapis.com/css?family=Fira+Sans:400,400i,700,700i has 28 url(〜)s and https://fonts.googleapis.com/css?family=Noto+Sans+JP has 120 url(〜)s.

nightpool commented 6 years ago

@ggtea no non-admin users should be customizing CSS, so i don't think that's a problem.

ClearlyClaire commented 6 years ago

@ggtea rewriting the CSP on the reverse proxy is not entirely advisable, as different controllers have slightly different headers

@nightpool there's a distinction here between admin in the sense of Mastodon, and admin as having admin rights on the host itself

Using strict-dynamic would be very good, but it would also break pghero and sidekiq monitor, unless we exempt them from it, which seems to be a mess with how Rails handles CSP.

nightpool commented 6 years ago

@ThibG issues that arise solely due to a lack of configurability on the part of third party hosting providers are not valid mastodon issues

On Thu, Nov 29, 2018, 6:42 PM ThibG notifications@github.com wrote:

@ggtea https://github.com/ggtea rewriting the CSP on the reverse proxy is not entirely advisable, as different controllers have slightly different headers

@nightpool https://github.com/nightpool there's a distinction here between admin in the sense of Mastodon, and admin as having admin rights on the host itself

Using strict-dynamic would be very good, but it would also break pghero and sidekiq monitor, unless we exempt them from it, which seems to be a mess with how Rails handles CSP.

— You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub https://github.com/tootsuite/mastodon/issues/9349#issuecomment-443035620, or mute the thread https://github.com/notifications/unsubscribe-auth/AAORVy7wfZKEYT2elw2PqybZbCXT5DVFks5u0HDOgaJpZM4Yx9xR .

ClearlyClaire commented 5 years ago

@nightpool tbh I think it's slightly narrow-minded. Since Mastodon sets the CSP itself (which I think is a good thing) and allows customization from the admin interface, I think it makes sense for it to also whitelist some things in the CSP.

nightpool commented 5 years ago

@ThibG see original post

I do agree that this presents a little bit of a conflict with the custom css section though.

jokeyrhyme commented 5 years ago

There's probably a finite set of popular font hosts, maybe just add them all to the default CSP policy? Opens the door to new fonts without complicating configuration by adding yet more options...

raphaeleidus commented 5 years ago

I would advise against providing a GUI interface to muck with security settings. There are some reasonable attack vectors where if an instance admin visited the wrong website, without them knowing their instance could and up with it's CSP disabled and open it's users up to a host of risk.

I also want to advise against serving fonts directly from Google as well. Google uses this to track your users without their knowledge. Rehost the files on your instance and reference them directly instead. No mucking with CSP and no privacy invasion from Google.

I would advise instead if the desire is to really make this easily configurable, mastadon adds a separate CSP settings file that is not tracked by git csp_settings.conf.sample that admins copy b and rename and mastadon automatically finds if it is present and modified the CSP as defined. Thoughts on this approach??

Again I would actually advise against modifying at all as I don't see a use case where you would need it.

decentral1se commented 2 years ago

Could you download the fonts from Google and put them in the fonts directory instead?

Ah, this would be handy. Does anyone know which folder that is exactly on the file system? I'm a bit confused:

> find . -name "*font*"
./public/packs/media/fonts
./public/packs/media/fonts/roboto/roboto-medium-webfont-c0d084caf29abb0ed6cc87e92d886d61.svg
./public/packs/media/fonts/roboto/roboto-bold-webfont-5ea71553d6e57da5b5cee78d8480db12.svg
./public/packs/media/fonts/roboto/roboto-regular-webfont-e6505d5d85943244ec91d5e3002791f2.woff2
./public/packs/media/fonts/roboto/roboto-bold-webfont-099d7f6e4b0fd1955bf58d33f84cbddf.ttf
./public/packs/media/fonts/roboto/roboto-bold-webfont-c8eca5c3d7f0e3203f2150ef668b11d7.woff
./public/packs/media/fonts/roboto/roboto-regular-webfont-8ede4fa233d6c99fb3653a767922b22b.woff
./public/packs/media/fonts/roboto/roboto-italic-webfont-8f90649d463aec7793d71b786b5b3b06.svg
./public/packs/media/fonts/roboto/roboto-italic-webfont-dcb8144b63145c7e349a27ebbe24f875.woff2
./public/packs/media/fonts/roboto/roboto-regular-webfont-a8da5f98faeafb21714583a6e373c397.svg
./public/packs/media/fonts/roboto/roboto-medium-webfont-3ed000c35f7afb8bd4ad7f46da85abbf.woff2
./public/packs/media/fonts/roboto/roboto-regular-webfont-00831949e731c8201e1966faf97da0d2.ttf
./public/packs/media/fonts/roboto/roboto-italic-webfont-5c39c5913ec17aaca7e59635381b9b62.woff
./public/packs/media/fonts/roboto/roboto-bold-webfont-2c18fe4b97519d62a0d6aad8ada1004f.woff2
./public/packs/media/fonts/roboto/roboto-medium-webfont-3a01847aadd53eb13f47e0227e8aca9b.woff
./public/packs/media/fonts/roboto/roboto-medium-webfont-131f629d199b0a47d72d8489fda5823a.ttf
./public/packs/media/fonts/roboto/roboto-italic-webfont-73eaf3921695d82f2daba6bc02ffa602.ttf
./public/packs/media/fonts/roboto-mono/robotomono-regular-webfont-de79497258b00697d7449a8d933a2d77.woff
./public/packs/media/fonts/roboto-mono/robotomono-regular-webfont-7fb73b77e9674adf3bb4e256d12f5c24.ttf
./public/packs/media/fonts/roboto-mono/robotomono-regular-webfont-ccc9601c8b2933f9a4b9246665afb352.woff2
./public/packs/media/fonts/roboto-mono/robotomono-regular-webfont-fe0d118334cccfd145435b2c48cd06e4.svg
./public/packs/media/fonts/fontawesome-webfont-20fd1704.woff2
./public/packs/media/fonts/fontawesome-webfont-c1e38fd9.svg
./public/packs/media/fonts/fontawesome-webfont-8b43027f.eot
./public/packs/media/fonts/fontawesome-webfont-f691f37e.woff
./public/packs/media/fonts/fontawesome-webfont-1e59d233.ttf
./node_modules/csso/node_modules/css-tree/lib/syntax/atrule/font-face.js
./node_modules/csso/lib/replace/property/font-weight.js
./node_modules/csso/lib/replace/property/font.js
./node_modules/css-font-style-keywords
./node_modules/caniuse-lite/data/features/font-loading.js
./node_modules/caniuse-lite/data/features/font-family-system-ui.js
./node_modules/caniuse-lite/data/features/font-variant-numeric.js
./node_modules/caniuse-lite/data/features/font-smooth.js
./node_modules/caniuse-lite/data/features/css-font-stretch.js
./node_modules/caniuse-lite/data/features/font-variant-alternates.js
./node_modules/caniuse-lite/data/features/css-font-rendering-controls.js
./node_modules/caniuse-lite/data/features/font-unicode-range.js
./node_modules/caniuse-lite/data/features/font-metrics-overrides.js
./node_modules/caniuse-lite/data/features/extended-system-fonts.js
./node_modules/caniuse-lite/data/features/font-size-adjust.js
./node_modules/caniuse-lite/data/features/variable-fonts.js
./node_modules/caniuse-lite/data/features/font-kerning.js
./node_modules/caniuse-lite/data/features/font-variant-east-asian.js
./node_modules/caniuse-lite/data/features/fontface.js
./node_modules/caniuse-lite/data/features/font-feature.js
./node_modules/caniuse-lite/data/features/svg-fonts.js
./node_modules/core-js/library/fn/string/fontcolor.js
./node_modules/core-js/library/fn/string/virtual/fontcolor.js
./node_modules/core-js/library/fn/string/virtual/fontsize.js
./node_modules/core-js/library/fn/string/fontsize.js
./node_modules/core-js/library/modules/es6.string.fontcolor.js
./node_modules/core-js/library/modules/es6.string.fontsize.js
./node_modules/core-js/fn/string/fontcolor.js
./node_modules/core-js/fn/string/virtual/fontcolor.js
./node_modules/core-js/fn/string/virtual/fontsize.js
./node_modules/core-js/fn/string/fontsize.js
./node_modules/core-js/modules/es6.string.fontcolor.js
./node_modules/core-js/modules/es6.string.fontsize.js
./node_modules/postcss-minify-font-values
./node_modules/postcss-minify-font-values/dist/lib/minify-font.js
./node_modules/css-font-stretch-keywords
./node_modules/font-awesome
./node_modules/font-awesome/less/font-awesome.less
./node_modules/font-awesome/css/font-awesome.css.map
./node_modules/font-awesome/css/font-awesome.css
./node_modules/font-awesome/css/font-awesome.min.css
./node_modules/font-awesome/fonts
./node_modules/font-awesome/fonts/fontawesome-webfont.woff
./node_modules/font-awesome/fonts/fontawesome-webfont.svg
./node_modules/font-awesome/fonts/fontawesome-webfont.woff2
./node_modules/font-awesome/fonts/fontawesome-webfont.ttf
./node_modules/font-awesome/fonts/fontawesome-webfont.eot
./node_modules/font-awesome/scss/font-awesome.scss
./node_modules/css-tree/lib/syntax/atrule/font-face.js
./node_modules/twitter-text/node_modules/core-js/library/fn/string/fontcolor.js
./node_modules/twitter-text/node_modules/core-js/library/fn/string/virtual/fontcolor.js
./node_modules/twitter-text/node_modules/core-js/library/fn/string/virtual/fontsize.js
./node_modules/twitter-text/node_modules/core-js/library/fn/string/fontsize.js
./node_modules/twitter-text/node_modules/core-js/library/modules/es6.string.fontcolor.js
./node_modules/twitter-text/node_modules/core-js/library/modules/es6.string.fontsize.js
./node_modules/twitter-text/node_modules/core-js/fn/string/fontcolor.js
./node_modules/twitter-text/node_modules/core-js/fn/string/virtual/fontcolor.js
./node_modules/twitter-text/node_modules/core-js/fn/string/virtual/fontsize.js
./node_modules/twitter-text/node_modules/core-js/fn/string/fontsize.js
./node_modules/twitter-text/node_modules/core-js/modules/es6.string.fontcolor.js
./node_modules/twitter-text/node_modules/core-js/modules/es6.string.fontsize.js
./node_modules/css-system-font-keywords
./node_modules/css-font-size-keywords
./node_modules/css-font-weight-keywords
./node_modules/parse-css-font
./node_modules/offline-plugin/lib/loaders/fonts-css.js
./vendor/bundle/ruby/2.7.0/gems/mime-types-data-3.2020.0512/types/font.yaml
./app/javascript/styles/fonts
./app/javascript/fonts
./app/javascript/fonts/roboto/roboto-medium-webfont.woff2
./app/javascript/fonts/roboto/roboto-medium-webfont.ttf
./app/javascript/fonts/roboto/roboto-bold-webfont.ttf
./app/javascript/fonts/roboto/roboto-regular-webfont.svg
./app/javascript/fonts/roboto/roboto-medium-webfont.woff
./app/javascript/fonts/roboto/roboto-italic-webfont.svg
./app/javascript/fonts/roboto/roboto-regular-webfont.woff2
./app/javascript/fonts/roboto/roboto-regular-webfont.woff
./app/javascript/fonts/roboto/roboto-bold-webfont.woff2
./app/javascript/fonts/roboto/roboto-regular-webfont.ttf
./app/javascript/fonts/roboto/roboto-medium-webfont.svg
./app/javascript/fonts/roboto/roboto-italic-webfont.woff2
./app/javascript/fonts/roboto/roboto-bold-webfont.svg
./app/javascript/fonts/roboto/roboto-italic-webfont.ttf
./app/javascript/fonts/roboto/roboto-italic-webfont.woff
./app/javascript/fonts/roboto/roboto-bold-webfont.woff
./app/javascript/fonts/roboto-mono/robotomono-regular-webfont.svg
./app/javascript/fonts/roboto-mono/robotomono-regular-webfont.woff
./app/javascript/fonts/roboto-mono/robotomono-regular-webfont.woff2
./app/javascript/fonts/roboto-mono/robotomono-regular-webfont.ttf
offbyone commented 2 years ago

Also, if we're recommending downloading fonts, it would be useful to document how to customize those both for git installations and for docker-based ones.

Justinzobel commented 1 year ago

I've just updated to 4.1.0 and was going through my task of adding our metaheader that shows all of our sites above Mastodon in our network.

However content_security_policy.rb doesn't seem to work any more. I also found this new ruby gem called rack attack and it is used for CORS settings but I couldn't figure out how to add our main site's address to allow script and media requests to it.