mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-11-22 01:36:29 -05:00
Merge pull request #486 from codimd/feature/cookie-policy
This commit is contained in:
commit
3461993ee0
13 changed files with 41 additions and 25 deletions
2
app.js
2
app.js
|
@ -147,7 +147,7 @@ app.use(session({
|
||||||
rolling: true, // reset maxAge on every response
|
rolling: true, // reset maxAge on every response
|
||||||
cookie: {
|
cookie: {
|
||||||
maxAge: config.sessionLife,
|
maxAge: config.sessionLife,
|
||||||
sameSite: 'lax',
|
sameSite: config.cookiePolicy, // be careful: setting a SameSite value of none without https breaks the editor
|
||||||
secure: config.useSSL || config.protocolUseSSL || false
|
secure: config.useSSL || config.protocolUseSSL || false
|
||||||
},
|
},
|
||||||
store: sessionStore
|
store: sessionStore
|
||||||
|
|
4
app.json
4
app.json
|
@ -56,6 +56,10 @@
|
||||||
"description": "set to use ssl protocol for resources path (only applied when domain is set)",
|
"description": "set to use ssl protocol for resources path (only applied when domain is set)",
|
||||||
"required": false
|
"required": false
|
||||||
},
|
},
|
||||||
|
"CMD_COOKIE_POLICY": {
|
||||||
|
"description": "Set whether cookies should be sent cross-origin (SameSite value)",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
"CMD_URL_ADDPORT": {
|
"CMD_URL_ADDPORT": {
|
||||||
"description": "set to add port on callback url (port 80 or 443 won't applied) (only applied when domain is set)",
|
"description": "set to add port on callback url (port 80 or 443 won't applied) (only applied when domain is set)",
|
||||||
"required": false
|
"required": false
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
"addDisqus": true,
|
"addDisqus": true,
|
||||||
"addGoogleAnalytics": true
|
"addGoogleAnalytics": true
|
||||||
},
|
},
|
||||||
|
"cookiePolicy": "strict",
|
||||||
"db": {
|
"db": {
|
||||||
"username": "",
|
"username": "",
|
||||||
"password": "",
|
"password": "",
|
||||||
|
|
|
@ -69,18 +69,19 @@ these are rarely used for various reasons.
|
||||||
| `urlAddPort` | `CMD_URL_ADDPORT` | **`false`** or `true` | set to add port on callback URL (ports `80` or `443` won't be applied) (only applied when domain is set) |
|
| `urlAddPort` | `CMD_URL_ADDPORT` | **`false`** or `true` | set to add port on callback URL (ports `80` or `443` won't be applied) (only applied when domain is set) |
|
||||||
| `allowOrigin` | `CMD_ALLOW_ORIGIN` | **`['localhost']`**, `['codimd.org']`, `[localhost, codimd.org]` | domain name whitelist (use comma to separate) |
|
| `allowOrigin` | `CMD_ALLOW_ORIGIN` | **`['localhost']`**, `['codimd.org']`, `[localhost, codimd.org]` | domain name whitelist (use comma to separate) |
|
||||||
|
|
||||||
## CSP and HSTS
|
## Web security aspects
|
||||||
|
|
||||||
| config file | environment | **default** and example value | description |
|
| 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) |
|
| `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_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_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_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) |
|
| | `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`. |
|
| `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_ENABLE` | **`true`** or `false` | whether to enable Content Security Policy (directives cannot be configured with environment variables) |
|
||||||
| | `CMD_CSP_REPORTURI` | **`undefined`**, `https://<someid>.report-uri.com/r/d/csp/enforce` | Allows to add a URL for CSP reports in case of violations |
|
| | `CMD_CSP_REPORTURI` | **`undefined`**, `https://<someid>.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
|
## Privacy and External Requests
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ module.exports = {
|
||||||
upgradeInsecureRequests: 'auto',
|
upgradeInsecureRequests: 'auto',
|
||||||
reportURI: undefined
|
reportURI: undefined
|
||||||
},
|
},
|
||||||
|
cookiePolicy: 'lax',
|
||||||
protocolUseSSL: false,
|
protocolUseSSL: false,
|
||||||
useCDN: false,
|
useCDN: false,
|
||||||
allowAnonymous: true,
|
allowAnonymous: true,
|
||||||
|
|
|
@ -22,6 +22,7 @@ module.exports = {
|
||||||
enable: toBooleanConfig(process.env.CMD_CSP_ENABLE),
|
enable: toBooleanConfig(process.env.CMD_CSP_ENABLE),
|
||||||
reportURI: process.env.CMD_CSP_REPORTURI
|
reportURI: process.env.CMD_CSP_REPORTURI
|
||||||
},
|
},
|
||||||
|
cookiePolicy: process.env.CMD_COOKIE_POLICY,
|
||||||
protocolUseSSL: toBooleanConfig(process.env.CMD_PROTOCOL_USESSL),
|
protocolUseSSL: toBooleanConfig(process.env.CMD_PROTOCOL_USESSL),
|
||||||
allowOrigin: toArrayConfig(process.env.CMD_ALLOW_ORIGIN),
|
allowOrigin: toArrayConfig(process.env.CMD_ALLOW_ORIGIN),
|
||||||
useCDN: toBooleanConfig(process.env.CMD_USECDN),
|
useCDN: toBooleanConfig(process.env.CMD_USECDN),
|
||||||
|
|
|
@ -51,6 +51,11 @@ if (['debug', 'verbose', 'info', 'warn', 'error'].includes(config.loglevel)) {
|
||||||
logger.error('Selected loglevel %s doesn\'t exist, using default level \'debug\'. Available options: debug, verbose, info, warn, error', config.loglevel)
|
logger.error('Selected loglevel %s doesn\'t exist, using default level \'debug\'. Available options: debug, verbose, info, warn, error', config.loglevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!['strict', 'lax', 'none'].includes(config.cookiePolicy)) {
|
||||||
|
logger.error('Cookie SameSite policy %s does not exist. Falling back to lax. Available values are: strict, lax, none.', config.cookiePolicy)
|
||||||
|
config.cookiePolicy = 'lax'
|
||||||
|
}
|
||||||
|
|
||||||
// load LDAP CA
|
// load LDAP CA
|
||||||
if (config.ldap.tlsca) {
|
if (config.ldap.tlsca) {
|
||||||
let ca = config.ldap.tlsca.split(',')
|
let ca = config.ldap.tlsca.split(',')
|
||||||
|
|
|
@ -97,7 +97,8 @@ statusRouter.get('/config', function (req, res) {
|
||||||
version: config.fullversion,
|
version: config.fullversion,
|
||||||
DROPBOX_APP_KEY: config.dropbox.appKey,
|
DROPBOX_APP_KEY: config.dropbox.appKey,
|
||||||
allowedUploadMimeTypes: config.allowedUploadMimeTypes,
|
allowedUploadMimeTypes: config.allowedUploadMimeTypes,
|
||||||
linkifyHeaderStyle: config.linkifyHeaderStyle
|
linkifyHeaderStyle: config.linkifyHeaderStyle,
|
||||||
|
cookiePolicy: config.cookiePolicy
|
||||||
}
|
}
|
||||||
res.set({
|
res.set({
|
||||||
'Cache-Control': 'private', // only cache by client
|
'Cache-Control': 'private', // only cache by client
|
||||||
|
|
|
@ -1599,7 +1599,7 @@ function toggleNightMode () {
|
||||||
} else {
|
} else {
|
||||||
Cookies.set('nightMode', !isActive, {
|
Cookies.set('nightMode', !isActive, {
|
||||||
expires: 365,
|
expires: 365,
|
||||||
sameSite: 'strict'
|
sameSite: window.cookiePolicy
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,3 +8,5 @@ window.allowedUploadMimeTypes = <%- JSON.stringify(allowedUploadMimeTypes) %>
|
||||||
window.linkifyHeaderStyle = '<%- linkifyHeaderStyle %>'
|
window.linkifyHeaderStyle = '<%- linkifyHeaderStyle %>'
|
||||||
|
|
||||||
window.DROPBOX_APP_KEY = '<%- DROPBOX_APP_KEY %>'
|
window.DROPBOX_APP_KEY = '<%- DROPBOX_APP_KEY %>'
|
||||||
|
|
||||||
|
window.cookiePolicy = '<%- cookiePolicy %>'
|
||||||
|
|
|
@ -20,12 +20,12 @@ export function resetCheckAuth () {
|
||||||
export function setLoginState (bool, id) {
|
export function setLoginState (bool, id) {
|
||||||
Cookies.set('loginstate', bool, {
|
Cookies.set('loginstate', bool, {
|
||||||
expires: 365,
|
expires: 365,
|
||||||
sameSite: 'strict'
|
sameSite: window.cookiePolicy
|
||||||
})
|
})
|
||||||
if (id) {
|
if (id) {
|
||||||
Cookies.set('userid', id, {
|
Cookies.set('userid', id, {
|
||||||
expires: 365,
|
expires: 365,
|
||||||
sameSite: 'strict'
|
sameSite: window.cookiePolicy
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Cookies.remove('userid')
|
Cookies.remove('userid')
|
||||||
|
|
|
@ -304,13 +304,13 @@ export default class Editor {
|
||||||
if (this.editor.getOption('indentWithTabs')) {
|
if (this.editor.getOption('indentWithTabs')) {
|
||||||
Cookies.set('indent_type', 'tab', {
|
Cookies.set('indent_type', 'tab', {
|
||||||
expires: 365,
|
expires: 365,
|
||||||
sameSite: 'strict'
|
sameSite: window.cookiePolicy
|
||||||
})
|
})
|
||||||
type.text('Tab Size:')
|
type.text('Tab Size:')
|
||||||
} else {
|
} else {
|
||||||
Cookies.set('indent_type', 'space', {
|
Cookies.set('indent_type', 'space', {
|
||||||
expires: 365,
|
expires: 365,
|
||||||
sameSite: 'strict'
|
sameSite: window.cookiePolicy
|
||||||
})
|
})
|
||||||
type.text('Spaces:')
|
type.text('Spaces:')
|
||||||
}
|
}
|
||||||
|
@ -322,12 +322,12 @@ export default class Editor {
|
||||||
if (this.editor.getOption('indentWithTabs')) {
|
if (this.editor.getOption('indentWithTabs')) {
|
||||||
Cookies.set('tab_size', unit, {
|
Cookies.set('tab_size', unit, {
|
||||||
expires: 365,
|
expires: 365,
|
||||||
sameSite: 'strict'
|
sameSite: window.cookiePolicy
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Cookies.set('space_units', unit, {
|
Cookies.set('space_units', unit, {
|
||||||
expires: 365,
|
expires: 365,
|
||||||
sameSite: 'strict'
|
sameSite: window.cookiePolicy
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
widthLabel.text(unit)
|
widthLabel.text(unit)
|
||||||
|
@ -396,7 +396,7 @@ export default class Editor {
|
||||||
var keymap = this.editor.getOption('keyMap')
|
var keymap = this.editor.getOption('keyMap')
|
||||||
Cookies.set('keymap', keymap, {
|
Cookies.set('keymap', keymap, {
|
||||||
expires: 365,
|
expires: 365,
|
||||||
sameSite: 'strict'
|
sameSite: window.cookiePolicy
|
||||||
})
|
})
|
||||||
label.text(keymap)
|
label.text(keymap)
|
||||||
this.restoreOverrideEditorKeymap()
|
this.restoreOverrideEditorKeymap()
|
||||||
|
@ -445,7 +445,7 @@ export default class Editor {
|
||||||
this.editor.setOption('theme', theme)
|
this.editor.setOption('theme', theme)
|
||||||
Cookies.set('theme', theme, {
|
Cookies.set('theme', theme, {
|
||||||
expires: 365,
|
expires: 365,
|
||||||
sameSite: 'strict'
|
sameSite: window.cookiePolicy
|
||||||
})
|
})
|
||||||
|
|
||||||
checkTheme()
|
checkTheme()
|
||||||
|
@ -491,7 +491,7 @@ export default class Editor {
|
||||||
}
|
}
|
||||||
Cookies.set('spellcheck', mode === 'spell-checker', {
|
Cookies.set('spellcheck', mode === 'spell-checker', {
|
||||||
expires: 365,
|
expires: 365,
|
||||||
sameSite: 'strict'
|
sameSite: window.cookiePolicy
|
||||||
})
|
})
|
||||||
|
|
||||||
checkSpellcheck()
|
checkSpellcheck()
|
||||||
|
@ -537,7 +537,7 @@ export default class Editor {
|
||||||
if (overrideBrowserKeymap.is(':checked')) {
|
if (overrideBrowserKeymap.is(':checked')) {
|
||||||
Cookies.set('preferences-override-browser-keymap', true, {
|
Cookies.set('preferences-override-browser-keymap', true, {
|
||||||
expires: 365,
|
expires: 365,
|
||||||
sameSite: 'strict'
|
sameSite: window.cookiePolicy
|
||||||
})
|
})
|
||||||
this.restoreOverrideEditorKeymap()
|
this.restoreOverrideEditorKeymap()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -31,7 +31,7 @@ if (localeSelector.length > 0) {
|
||||||
localeSelector.change(function () {
|
localeSelector.change(function () {
|
||||||
Cookies.set('locale', $(this).val(), {
|
Cookies.set('locale', $(this).val(), {
|
||||||
expires: 365,
|
expires: 365,
|
||||||
sameSite: 'strict'
|
sameSite: window.cookiePolicy
|
||||||
})
|
})
|
||||||
window.location.reload()
|
window.location.reload()
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue