From 8891d75baa1e77e8a6fe2228c56ba0fb12416aa6 Mon Sep 17 00:00:00 2001 From: Philip Molares Date: Wed, 10 Jun 2026 21:00:43 +0200 Subject: [PATCH] feat(rate-limit): add more config options Allow the admin to specify the rate-limits for user signup / login Allow the admin to specify if Cloudflare specific rate-limit functionality should be used or not Signed-off-by: Philip Molares --- docs/content/configuration.md | 40 +++++++++++++++++---------------- lib/config/default.js | 2 ++ lib/config/environment.js | 2 ++ lib/web/middleware/rateLimit.js | 7 ++++-- public/docs/release-notes.md | 2 ++ 5 files changed, 32 insertions(+), 21 deletions(-) diff --git a/docs/content/configuration.md b/docs/content/configuration.md index 74a1dc1b..c858baea 100644 --- a/docs/content/configuration.md +++ b/docs/content/configuration.md @@ -88,25 +88,27 @@ 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 `false`) | -| | `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. | -| `csp.allowFraming` | `CMD_CSP_ALLOW_FRAMING` | **`true`** or `false` | Disable to disallow embedding of the instance via iframe. We **strongly recommend disabling** this option, as it increases the attack surface of XSS attacks. | -| `csp.allowPDFEmbed` | `CMD_CSP_ALLOW_PDF_EMBED` | **`true`** or `false` | Disable to disallow embedding PDFs. We recommend disabling this option, as it increases the attack surface of XSS attacks. | -| `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. | -| `rateLimitNewNotes` | `CMD_RATE_LIMIT_NEW_NOTES` | **`20`**, `0` or any positive number | Sets the maximum amount of new note creations per 5-minute window per user. Can be disabled by setting to `0`. | +| 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 `false`) | +| | `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. | +| `csp.allowFraming` | `CMD_CSP_ALLOW_FRAMING` | **`true`** or `false` | Disable to disallow embedding of the instance via iframe. We **strongly recommend disabling** this option, as it increases the attack surface of XSS attacks. | +| `csp.allowPDFEmbed` | `CMD_CSP_ALLOW_PDF_EMBED` | **`true`** or `false` | Disable to disallow embedding PDFs. We recommend disabling this option, as it increases the attack surface of XSS attacks. | +| `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. | +| `rateLimitNewNotes` | `CMD_RATE_LIMIT_NEW_NOTES` | **`20`**, `0` or any positive number | Sets the maximum amount of new note creations per 5-minute window per user. Can be disabled by setting to `0`. | +| `rateLimitUser` | `CMD_RATE_LIMIT_USER` | **`10`**, `0` or any positive number | Sets the maximum amount of user auth interactions (login, signup) per 5-minute window per user. Can be disabled by setting to `0`. | +| `rateLimitUsingCloudflare` | `CMD_RATE_LIMIT_USING_CLOUDFLARE` | **`false`** or `true` | Activate specialy cloudflare ip handling. If you use cloudflare for your instance you want this to be true. | ## Privacy and External Requests diff --git a/lib/config/default.js b/lib/config/default.js index 19346db4..3703c10a 100644 --- a/lib/config/default.js +++ b/lib/config/default.js @@ -30,6 +30,8 @@ module.exports = { allowPDFEmbed: true }, rateLimitNewNotes: 20, + rateLimitUser: 10, + rateLimitUsingCloudflare: false, cookiePolicy: 'lax', protocolUseSSL: false, // permissions diff --git a/lib/config/environment.js b/lib/config/environment.js index 393928b5..891b30e3 100644 --- a/lib/config/environment.js +++ b/lib/config/environment.js @@ -27,6 +27,8 @@ module.exports = { allowPDFEmbed: toBooleanConfig(process.env.CMD_CSP_ALLOW_PDF_EMBED) }, rateLimitNewNotes: toIntegerConfig(process.env.CMD_RATE_LIMIT_NEW_NOTES), + rateLimitUser: toIntegerConfig(process.env.CMD_RATE_LIMIT_USER), + rateLimitUsingCloudflare: toBooleanConfig(process.env.CMD_RATE_LIMIT_USING_CLOUDFLARE), cookiePolicy: process.env.CMD_COOKIE_POLICY, protocolUseSSL: toBooleanConfig(process.env.CMD_PROTOCOL_USESSL), allowOrigin: toArrayConfig(process.env.CMD_ALLOW_ORIGIN), diff --git a/lib/web/middleware/rateLimit.js b/lib/web/middleware/rateLimit.js index 88df79ba..2e049816 100644 --- a/lib/web/middleware/rateLimit.js +++ b/lib/web/middleware/rateLimit.js @@ -8,13 +8,16 @@ const determineKey = (req) => { if (req.user) { return req.user.id } - return ipKeyGenerator(req.header('cf-connecting-ip') || req.ip) + if (config.rateLimitUsingCloudflare) { + return ipKeyGenerator(req.header('cf-connecting-ip') || req.ip) + } + return ipKeyGenerator(req.ip) } // limits requests to user endpoints (login, signup) to 10 requests per 5 minutes const userEndpoints = rateLimit({ windowMs: 5 * 60 * 1000, - limit: 10, + limit: config.rateLimitUser, keyGenerator: determineKey, handler: (req, res) => errors.errorTooManyRequests(res) }) diff --git a/public/docs/release-notes.md b/public/docs/release-notes.md index 9451b0b4..e49ac73f 100644 --- a/public/docs/release-notes.md +++ b/public/docs/release-notes.md @@ -6,6 +6,8 @@ - Added a warning page when clicking external links - Improve the config.json.example file, which is used by `bin/setup` +- Allow configuration of login / signup rate-limits +- Allow configuration of Cloudflare usage in regards rate-limits ## 1.10.8 2026-04-15