From 52231f688dd086f6a8ccfe08b88deaae6d93bfd2 Mon Sep 17 00:00:00 2001 From: David Mehren Date: Mon, 7 Jun 2021 20:06:44 +0200 Subject: [PATCH 1/4] Disable GA and Disqus in default CSP Signed-off-by: David Mehren --- lib/config/default.js | 4 ++-- test/csp.js | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/config/default.js b/lib/config/default.js index ed812f45..c1f3f973 100644 --- a/lib/config/default.js +++ b/lib/config/default.js @@ -22,8 +22,8 @@ module.exports = { directives: { }, addDefaults: true, - addDisqus: true, - addGoogleAnalytics: true, + addDisqus: false, + addGoogleAnalytics: false, upgradeInsecureRequests: 'auto', reportURI: undefined }, diff --git a/test/csp.js b/test/csp.js index 70598156..15412022 100644 --- a/test/csp.js +++ b/test/csp.js @@ -68,6 +68,15 @@ describe('Content security policies', function () { assert(!csp.computeDirectives().scriptSrc.includes('https://www.google-analytics.com')) }) + it('Enable Google Analytics', function () { + const testconfig = defaultConfig + testconfig.csp.addGoogleAnalytics = true + mock('../lib/config', testconfig) + csp = mock.reRequire('../lib/csp') + + assert(csp.computeDirectives().scriptSrc.includes('https://www.google-analytics.com')) + }) + it('Disable Disqus', function () { const testconfig = defaultConfig testconfig.csp.addDisqus = false @@ -81,6 +90,19 @@ describe('Content security policies', function () { assert(!csp.computeDirectives().fontSrc.includes('https://*.disquscdn.com')) }) + it('Enable Disqus', function () { + const testconfig = defaultConfig + testconfig.csp.addDisqus = true + mock('../lib/config', testconfig) + csp = mock.reRequire('../lib/csp') + + assert(csp.computeDirectives().scriptSrc.includes('https://disqus.com')) + assert(csp.computeDirectives().scriptSrc.includes('https://*.disqus.com')) + assert(csp.computeDirectives().scriptSrc.includes('https://*.disquscdn.com')) + assert(csp.computeDirectives().styleSrc.includes('https://*.disquscdn.com')) + assert(csp.computeDirectives().fontSrc.includes('https://*.disquscdn.com')) + }) + it('Include dropbox if configured', function () { const testconfig = defaultConfig testconfig.dropbox.appKey = 'hedgedoc' From 0c6482abc538804ad4c0bbe9331c584927f74600 Mon Sep 17 00:00:00 2001 From: David Mehren Date: Mon, 7 Jun 2021 20:07:00 +0200 Subject: [PATCH 2/4] Add release notes for CSP changes Signed-off-by: David Mehren --- public/docs/release-notes.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/public/docs/release-notes.md b/public/docs/release-notes.md index 1d957b72..b942aa83 100644 --- a/public/docs/release-notes.md +++ b/public/docs/release-notes.md @@ -1,4 +1,12 @@ # Release Notes +## 1.9.0 UNRELEASED +### Security Fixes +- This release removes Google Analytics and Disqus domains from our default Content Security Policy, because + they were repeatedly used to exploit security vulnerabilities. + If you want to continue using Google Analytics or Disqus, you can re-enable them in the config. + See [the docs](https://docs.hedgedoc.org/configuration/#web-security-aspects) for details. + + ## 1.8.2 2021-05-11 This release fixes two security issues. We recommend upgrading as soon as possible. From 7283ccd5e8425c4812a8cb5f28420764a95708d8 Mon Sep 17 00:00:00 2001 From: David Mehren Date: Mon, 7 Jun 2021 22:20:36 +0200 Subject: [PATCH 3/4] Allow configuring Disqus & GA CSP with env vars Signed-off-by: David Mehren --- lib/config/environment.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/config/environment.js b/lib/config/environment.js index e03bac8a..de4bd873 100644 --- a/lib/config/environment.js +++ b/lib/config/environment.js @@ -20,7 +20,9 @@ module.exports = { }, csp: { enable: toBooleanConfig(process.env.CMD_CSP_ENABLE), - reportURI: process.env.CMD_CSP_REPORTURI + reportURI: process.env.CMD_CSP_REPORTURI, + addDisqus: toBooleanConfig(process.env.CMD_CSP_ADD_DISQUS), + addGoogleAnalytics: toBooleanConfig(process.env.CMD_CSP_ADD_GOOGLE_ANALYTICS) }, cookiePolicy: process.env.CMD_COOKIE_POLICY, protocolUseSSL: toBooleanConfig(process.env.CMD_PROTOCOL_USESSL), From 5e771c2f651604b9fe1d403632a0033a49185bae Mon Sep 17 00:00:00 2001 From: David Mehren Date: Mon, 7 Jun 2021 22:22:47 +0200 Subject: [PATCH 4/4] Update Content Security Policy docs Signed-off-by: David Mehren --- docs/content/configuration.md | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/docs/content/configuration.md b/docs/content/configuration.md index 0b926112..937a9e9c 100644 --- a/docs/content/configuration.md +++ b/docs/content/configuration.md @@ -70,17 +70,22 @@ these are rarely used for various reasons. ## Web security aspects -| config file | environment | **default** and example value | description | -| -------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `hsts` | | `{"enable": true, "maxAgeSeconds": 31536000, "includeSubdomains": true, "preload": true}` | [HSTS](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) options to use with HTTPS (default is the example value, max age is a year) | -| | `CMD_HSTS_ENABLE` | **`true`** or `false` | set to enable [HSTS](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) if HTTPS is also enabled (default is ` true`) | -| | `CMD_HSTS_INCLUDE_SUBDOMAINS` | **`true`** or `false` | set to include subdomains in HSTS (default is `true`) | -| | `CMD_HSTS_MAX_AGE` | **`31536000`**, `60 * 60 * 24 * 365` | max duration in seconds to tell clients to keep HSTS status (default is a year) | -| | `CMD_HSTS_PRELOAD` | **`true`** or `false` | whether to allow preloading of the site's HSTS status (e.g. into browsers) | -| `csp` | | `{"enable": true, "directives": {"scriptSrc": "trustworthy-scripts.example.com"}, "upgradeInsecureRequests": "auto", "addDefaults": true}` | Configures [Content Security Policy](https://helmetjs.github.io/docs/csp/). Directives are passed to Helmet - see [their documentation](https://helmetjs.github.io/docs/csp/) for more information on the format. Some defaults are added to the configured values so that the application doesn't break. To disable this behaviour, set `addDefaults` to `false`. Further, if `usecdn` is on, some CDN locations are allowed too. By default (`auto`), insecure (HTTP) requests are upgraded to HTTPS via CSP if `useSSL` is on. To change this behaviour, set `upgradeInsecureRequests` to either `true` or `false`. | -| | `CMD_CSP_ENABLE` | **`true`** or `false` | whether to enable Content Security Policy (directives cannot be configured with environment variables) | -| | `CMD_CSP_REPORTURI` | **`undefined`**, `https://.report-uri.com/r/d/csp/enforce` | Allows to add a URL for CSP reports in case of violations | -| `cookiePolicy` | `CMD_COOKIE_POLICY` | **`lax`**, `strict` or `none` | Set a SameSite policy whether cookies are send from cross-origin. Be careful: setting a SameSite value of none without https breaks the editor | +| config file | environment | **default** and example value | description | +| ----------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `hsts` | | `{"enable": true, "maxAgeSeconds": 31536000, "includeSubdomains": true, "preload": true}` | [HSTS](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) options to use with HTTPS (default is the example value, max age is a year) | +| | `CMD_HSTS_ENABLE` | **`true`** or `false` | set to enable [HSTS](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) if HTTPS is also enabled (default is ` true`) | +| | `CMD_HSTS_INCLUDE_SUBDOMAINS` | **`true`** or `false` | set to include subdomains in HSTS (default is `true`) | +| | `CMD_HSTS_MAX_AGE` | **`31536000`**, `60 * 60 * 24 * 365` | max duration in seconds to tell clients to keep HSTS status (default is a year) | +| | `CMD_HSTS_PRELOAD` | **`true`** or `false` | whether to allow preloading of the site's HSTS status (e.g. into browsers) | +| `csp` | | `{"enable": true, "addDefaults": true}` | Nested object to configure the Content Security Policy | +| `csp.enable` | `CMD_CSP_ENABLE` | **`true`** or `false` | Whether to apply a `Content-Security-Policy` header to responses. We don't recommend disabling this option, as it significantly reduces the security of the application. | +| `csp.addDefaults` | | **`true`** or `false` | Disable to not include the default CSP. Be careful, this will break the application if the correct directives are not set manually. | +| `csp.directives` | | **no default**, `{"scriptSrc": "trustworthy-scripts.example.com"}` | Custom CSP directives. These are passed to Helmet - see [their documentation](https://helmetjs.github.io/docs/csp/) for more information on the format. | +| `csp.addDisqus` | `CMD_CSP_ADD_DISQUS` | **`false`** or `true` | Enable to allow users to add Disqus comments to their notes or presentations. We don't recommend enabling this option, as it increases the attack surface of XSS attacks. | +| `csp.addGoogleAnalytics` | `CMD_CSP_ADD_GOOGLE_ANALYTICS` | **`false`** or `true` | Enable to allow users to add Google Analytics to their notes. We don't recommend enabling this option, as it increases the attack surface of XSS attacks. | +| `csp.upgradeInsecureRequests` | | **`auto`** or `true` or `false` | By default (`auto`), insecure (HTTP) requests are upgraded to HTTPS via CSP if `useSSL` is on. To change this behaviour, set to either `true` or `false`. | +| `csp.reportUri` | `CMD_CSP_REPORTURI` | **`undefined`**, `https://.report-uri.com/r/d/csp/enforce` | Allows to add a URL for CSP reports in case of violations. | +| `cookiePolicy` | `CMD_COOKIE_POLICY` | **`lax`**, `strict` or `none` | Set a SameSite policy whether cookies are send from cross-origin. Be careful: setting a SameSite value of none without https breaks the editor. | ## Privacy and External Requests