mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #18088 from overleaf/ab-session-secret-rotation
[web/realtime/history-v1] Support session secret rotation GitOrigin-RevId: 3c2fa27b1b3e0a8e0c9d1af2e616ce873d54aedf
This commit is contained in:
parent
a4816d6e75
commit
344b4d0fa0
11 changed files with 41 additions and 70 deletions
60
package-lock.json
generated
60
package-lock.json
generated
|
@ -18079,6 +18079,7 @@
|
||||||
"version": "2.8.5",
|
"version": "2.8.5",
|
||||||
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||||
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
||||||
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"object-assign": "^4",
|
"object-assign": "^4",
|
||||||
"vary": "^1"
|
"vary": "^1"
|
||||||
|
@ -42416,8 +42417,6 @@
|
||||||
"check-types": "^11.1.2",
|
"check-types": "^11.1.2",
|
||||||
"command-line-args": "^3.0.3",
|
"command-line-args": "^3.0.3",
|
||||||
"config": "^1.19.0",
|
"config": "^1.19.0",
|
||||||
"cookie-parser": "~1.4.5",
|
|
||||||
"cors": "^2.8.5",
|
|
||||||
"express": "^4.19.2",
|
"express": "^4.19.2",
|
||||||
"fs-extra": "^9.0.1",
|
"fs-extra": "^9.0.1",
|
||||||
"generic-pool": "^2.1.1",
|
"generic-pool": "^2.1.1",
|
||||||
|
@ -43962,7 +43961,7 @@
|
||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
"bunyan": "^1.8.15",
|
"bunyan": "^1.8.15",
|
||||||
"connect-redis": "^6.1.3",
|
"connect-redis": "^6.1.3",
|
||||||
"cookie-parser": "^1.4.5",
|
"cookie-parser": "^1.4.6",
|
||||||
"express": "^4.19.2",
|
"express": "^4.19.2",
|
||||||
"express-session": "^1.17.1",
|
"express-session": "^1.17.1",
|
||||||
"joi": "^17.12.0",
|
"joi": "^17.12.0",
|
||||||
|
@ -44457,7 +44456,7 @@
|
||||||
"content-disposition": "^0.5.0",
|
"content-disposition": "^0.5.0",
|
||||||
"contentful": "^10.8.5",
|
"contentful": "^10.8.5",
|
||||||
"cookie": "^0.2.3",
|
"cookie": "^0.2.3",
|
||||||
"cookie-parser": "1.3.5",
|
"cookie-parser": "1.4.6",
|
||||||
"core-js": "^3.30.2",
|
"core-js": "^3.30.2",
|
||||||
"crc-32": "^1.2.2",
|
"crc-32": "^1.2.2",
|
||||||
"csurf": "^1.11.0",
|
"csurf": "^1.11.0",
|
||||||
|
@ -45466,31 +45465,6 @@
|
||||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"services/web/node_modules/cookie-parser": {
|
|
||||||
"version": "1.3.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.3.5.tgz",
|
|
||||||
"integrity": "sha1-nXVVcPtdF4kHcSJ6AjFNm+fPg1Y=",
|
|
||||||
"dependencies": {
|
|
||||||
"cookie": "0.1.3",
|
|
||||||
"cookie-signature": "1.0.6"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"services/web/node_modules/cookie-parser/node_modules/cookie": {
|
|
||||||
"version": "0.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.3.tgz",
|
|
||||||
"integrity": "sha1-5zSlwUF/zkctWu+Cw4HKu2TRpDU=",
|
|
||||||
"engines": {
|
|
||||||
"node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"services/web/node_modules/cookie-signature": {
|
|
||||||
"version": "1.0.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
|
||||||
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
|
||||||
},
|
|
||||||
"services/web/node_modules/csv": {
|
"services/web/node_modules/csv": {
|
||||||
"version": "6.2.5",
|
"version": "6.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/csv/-/csv-6.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/csv/-/csv-6.2.5.tgz",
|
||||||
|
@ -52554,7 +52528,7 @@
|
||||||
"chai": "^4.3.6",
|
"chai": "^4.3.6",
|
||||||
"chai-as-promised": "^7.1.1",
|
"chai-as-promised": "^7.1.1",
|
||||||
"connect-redis": "^6.1.3",
|
"connect-redis": "^6.1.3",
|
||||||
"cookie-parser": "^1.4.5",
|
"cookie-parser": "^1.4.6",
|
||||||
"cookie-signature": "^1.1.0",
|
"cookie-signature": "^1.1.0",
|
||||||
"express": "^4.19.2",
|
"express": "^4.19.2",
|
||||||
"express-session": "^1.17.1",
|
"express-session": "^1.17.1",
|
||||||
|
@ -53060,7 +53034,7 @@
|
||||||
"content-disposition": "^0.5.0",
|
"content-disposition": "^0.5.0",
|
||||||
"contentful": "^10.8.5",
|
"contentful": "^10.8.5",
|
||||||
"cookie": "^0.2.3",
|
"cookie": "^0.2.3",
|
||||||
"cookie-parser": "1.3.5",
|
"cookie-parser": "1.4.6",
|
||||||
"copy-webpack-plugin": "^11.0.0",
|
"copy-webpack-plugin": "^11.0.0",
|
||||||
"core-js": "^3.30.2",
|
"core-js": "^3.30.2",
|
||||||
"crc-32": "^1.2.2",
|
"crc-32": "^1.2.2",
|
||||||
|
@ -53732,27 +53706,6 @@
|
||||||
"supports-color": "^7.1.0"
|
"supports-color": "^7.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cookie-parser": {
|
|
||||||
"version": "1.3.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.3.5.tgz",
|
|
||||||
"integrity": "sha1-nXVVcPtdF4kHcSJ6AjFNm+fPg1Y=",
|
|
||||||
"requires": {
|
|
||||||
"cookie": "0.1.3",
|
|
||||||
"cookie-signature": "1.0.6"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"cookie": {
|
|
||||||
"version": "0.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.3.tgz",
|
|
||||||
"integrity": "sha1-5zSlwUF/zkctWu+Cw4HKu2TRpDU="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"cookie-signature": {
|
|
||||||
"version": "1.0.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
|
||||||
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
|
||||||
},
|
|
||||||
"csv": {
|
"csv": {
|
||||||
"version": "6.2.5",
|
"version": "6.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/csv/-/csv-6.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/csv/-/csv-6.2.5.tgz",
|
||||||
|
@ -61672,6 +61625,7 @@
|
||||||
"version": "2.8.5",
|
"version": "2.8.5",
|
||||||
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||||
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
||||||
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"object-assign": "^4",
|
"object-assign": "^4",
|
||||||
"vary": "^1"
|
"vary": "^1"
|
||||||
|
@ -72400,8 +72354,6 @@
|
||||||
"check-types": "^11.1.2",
|
"check-types": "^11.1.2",
|
||||||
"command-line-args": "^3.0.3",
|
"command-line-args": "^3.0.3",
|
||||||
"config": "^1.19.0",
|
"config": "^1.19.0",
|
||||||
"cookie-parser": "~1.4.5",
|
|
||||||
"cors": "^2.8.5",
|
|
||||||
"express": "^4.19.2",
|
"express": "^4.19.2",
|
||||||
"fs-extra": "^9.0.1",
|
"fs-extra": "^9.0.1",
|
||||||
"generic-pool": "^2.1.1",
|
"generic-pool": "^2.1.1",
|
||||||
|
|
|
@ -9,12 +9,10 @@ const config = require('config')
|
||||||
const Events = require('events')
|
const Events = require('events')
|
||||||
const BPromise = require('bluebird')
|
const BPromise = require('bluebird')
|
||||||
const express = require('express')
|
const express = require('express')
|
||||||
const cors = require('cors')
|
|
||||||
const helmet = require('helmet')
|
const helmet = require('helmet')
|
||||||
const HTTPStatus = require('http-status')
|
const HTTPStatus = require('http-status')
|
||||||
const logger = require('@overleaf/logger')
|
const logger = require('@overleaf/logger')
|
||||||
const Metrics = require('@overleaf/metrics')
|
const Metrics = require('@overleaf/metrics')
|
||||||
const cookieParser = require('cookie-parser')
|
|
||||||
const bodyParser = require('body-parser')
|
const bodyParser = require('body-parser')
|
||||||
const swaggerTools = require('swagger-tools')
|
const swaggerTools = require('swagger-tools')
|
||||||
const swaggerDoc = require('./api/swagger')
|
const swaggerDoc = require('./api/swagger')
|
||||||
|
@ -42,8 +40,6 @@ app.use(
|
||||||
extended: false,
|
extended: false,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
app.use(cookieParser())
|
|
||||||
app.use(cors())
|
|
||||||
|
|
||||||
security.setupSSL(app)
|
security.setupSSL(app)
|
||||||
security.setupBasicHttpAuthForSwaggerDocs(app)
|
security.setupBasicHttpAuthForSwaggerDocs(app)
|
||||||
|
|
|
@ -21,8 +21,6 @@
|
||||||
"check-types": "^11.1.2",
|
"check-types": "^11.1.2",
|
||||||
"command-line-args": "^3.0.3",
|
"command-line-args": "^3.0.3",
|
||||||
"config": "^1.19.0",
|
"config": "^1.19.0",
|
||||||
"cookie-parser": "~1.4.5",
|
|
||||||
"cors": "^2.8.5",
|
|
||||||
"express": "^4.19.2",
|
"express": "^4.19.2",
|
||||||
"fs-extra": "^9.0.1",
|
"fs-extra": "^9.0.1",
|
||||||
"generic-pool": "^2.1.1",
|
"generic-pool": "^2.1.1",
|
||||||
|
|
|
@ -56,7 +56,17 @@ const io = require('socket.io').listen(server, {
|
||||||
|
|
||||||
// Bind to sessions
|
// Bind to sessions
|
||||||
const sessionStore = new RedisStore({ client: sessionRedisClient })
|
const sessionStore = new RedisStore({ client: sessionRedisClient })
|
||||||
const cookieParser = CookieParser(Settings.security.sessionSecret)
|
|
||||||
|
if (!Settings.security.sessionSecret) {
|
||||||
|
throw new Error('No SESSION_SECRET provided.')
|
||||||
|
}
|
||||||
|
|
||||||
|
const sessionSecrets = [
|
||||||
|
Settings.security.sessionSecret,
|
||||||
|
Settings.security.sessionSecretUpcoming,
|
||||||
|
Settings.security.sessionSecretFallback,
|
||||||
|
].filter(Boolean)
|
||||||
|
const cookieParser = CookieParser(sessionSecrets)
|
||||||
|
|
||||||
const sessionSockets = new SessionSockets(
|
const sessionSockets = new SessionSockets(
|
||||||
io,
|
io,
|
||||||
|
|
|
@ -105,7 +105,9 @@ const settings = {
|
||||||
},
|
},
|
||||||
|
|
||||||
security: {
|
security: {
|
||||||
sessionSecret: process.env.SESSION_SECRET || 'secret-please-change',
|
sessionSecret: process.env.SESSION_SECRET,
|
||||||
|
sessionSecretUpcoming: process.env.SESSION_SECRET_UPCOMING,
|
||||||
|
sessionSecretFallback: process.env.SESSION_SECRET_FALLBACK,
|
||||||
},
|
},
|
||||||
|
|
||||||
cookieName: process.env.COOKIE_NAME || 'overleaf.sid',
|
cookieName: process.env.COOKIE_NAME || 'overleaf.sid',
|
||||||
|
|
|
@ -2,4 +2,9 @@ module.exports = {
|
||||||
errors: {
|
errors: {
|
||||||
catchUncaughtErrors: false,
|
catchUncaughtErrors: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
security: {
|
||||||
|
sessionSecret: 'static-secret-for-tests',
|
||||||
|
sessionSecretFallback: 'static-secret-fallback-for-tests',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
"bunyan": "^1.8.15",
|
"bunyan": "^1.8.15",
|
||||||
"connect-redis": "^6.1.3",
|
"connect-redis": "^6.1.3",
|
||||||
"cookie-parser": "^1.4.5",
|
"cookie-parser": "^1.4.6",
|
||||||
"express": "^4.19.2",
|
"express": "^4.19.2",
|
||||||
"express-session": "^1.17.1",
|
"express-session": "^1.17.1",
|
||||||
"joi": "^17.12.0",
|
"joi": "^17.12.0",
|
||||||
|
|
|
@ -155,10 +155,16 @@ if (Settings.useHttpPermissionsPolicy) {
|
||||||
RedirectManager.apply(webRouter)
|
RedirectManager.apply(webRouter)
|
||||||
|
|
||||||
if (!Settings.security.sessionSecret) {
|
if (!Settings.security.sessionSecret) {
|
||||||
throw new Error('Session secret is not set - refusing to start server')
|
throw new Error('No SESSION_SECRET provided.')
|
||||||
}
|
}
|
||||||
|
|
||||||
webRouter.use(cookieParser(Settings.security.sessionSecret))
|
const sessionSecrets = [
|
||||||
|
Settings.security.sessionSecret,
|
||||||
|
Settings.security.sessionSecretUpcoming,
|
||||||
|
Settings.security.sessionSecretFallback,
|
||||||
|
].filter(Boolean)
|
||||||
|
|
||||||
|
webRouter.use(cookieParser(sessionSecrets))
|
||||||
SessionAutostartMiddleware.applyInitialMiddleware(webRouter)
|
SessionAutostartMiddleware.applyInitialMiddleware(webRouter)
|
||||||
Modules.registerMiddleware(webRouter, 'sessionMiddleware', {
|
Modules.registerMiddleware(webRouter, 'sessionMiddleware', {
|
||||||
store: sessionStore,
|
store: sessionStore,
|
||||||
|
@ -167,7 +173,7 @@ webRouter.use(
|
||||||
session({
|
session({
|
||||||
resave: false,
|
resave: false,
|
||||||
saveUninitialized: false,
|
saveUninitialized: false,
|
||||||
secret: Settings.security.sessionSecret,
|
secret: sessionSecrets,
|
||||||
proxy: Settings.behindProxy,
|
proxy: Settings.behindProxy,
|
||||||
cookie: {
|
cookie: {
|
||||||
domain: Settings.cookieDomain,
|
domain: Settings.cookieDomain,
|
||||||
|
|
|
@ -43,8 +43,6 @@ if (httpAuthUser && httpAuthPass) {
|
||||||
httpAuthUsers[httpAuthUser] = httpAuthPass
|
httpAuthUsers[httpAuthUser] = httpAuthPass
|
||||||
}
|
}
|
||||||
|
|
||||||
const sessionSecret = process.env.SESSION_SECRET
|
|
||||||
|
|
||||||
const intFromEnv = function (name, defaultValue) {
|
const intFromEnv = function (name, defaultValue) {
|
||||||
if (
|
if (
|
||||||
[null, undefined].includes(defaultValue) ||
|
[null, undefined].includes(defaultValue) ||
|
||||||
|
@ -386,7 +384,9 @@ module.exports = {
|
||||||
// Security
|
// Security
|
||||||
// --------
|
// --------
|
||||||
security: {
|
security: {
|
||||||
sessionSecret,
|
sessionSecret: process.env.SESSION_SECRET,
|
||||||
|
sessionSecretUpcoming: process.env.SESSION_SECRET_UPCOMING,
|
||||||
|
sessionSecretFallback: process.env.SESSION_SECRET_FALLBACK,
|
||||||
bcryptRounds: parseInt(process.env.BCRYPT_ROUNDS, 10) || 12,
|
bcryptRounds: parseInt(process.env.BCRYPT_ROUNDS, 10) || 12,
|
||||||
}, // number of rounds used to hash user passwords (raised to power 2)
|
}, // number of rounds used to hash user passwords (raised to power 2)
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,7 @@
|
||||||
"content-disposition": "^0.5.0",
|
"content-disposition": "^0.5.0",
|
||||||
"contentful": "^10.8.5",
|
"contentful": "^10.8.5",
|
||||||
"cookie": "^0.2.3",
|
"cookie": "^0.2.3",
|
||||||
"cookie-parser": "1.3.5",
|
"cookie-parser": "1.4.6",
|
||||||
"core-js": "^3.30.2",
|
"core-js": "^3.30.2",
|
||||||
"crc-32": "^1.2.2",
|
"crc-32": "^1.2.2",
|
||||||
"csurf": "^1.11.0",
|
"csurf": "^1.11.0",
|
||||||
|
|
|
@ -17,6 +17,8 @@ module.exports = {
|
||||||
secureCookie: false,
|
secureCookie: false,
|
||||||
security: {
|
security: {
|
||||||
sessionSecret: 'static-secret-for-tests',
|
sessionSecret: 'static-secret-for-tests',
|
||||||
|
sessionSecretUpcoming: 'static-secret-upcoming-for-tests',
|
||||||
|
sessionSecretFallback: 'static-secret-fallback-for-tests',
|
||||||
},
|
},
|
||||||
adminDomains: process.env.ADMIN_DOMAINS
|
adminDomains: process.env.ADMIN_DOMAINS
|
||||||
? JSON.parse(process.env.ADMIN_DOMAINS)
|
? JSON.parse(process.env.ADMIN_DOMAINS)
|
||||||
|
|
Loading…
Reference in a new issue