From 51f26be75959ad498a257e3ff4cad36567f78894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20Conradi=20=C3=98sthus?= Date: Thu, 1 Oct 2020 21:47:40 +0200 Subject: [PATCH] fix: add secureHeaders option for HSTS --- docs/getting-started.md | 14 ++++++++------ lib/app.js | 4 ++-- lib/middleware/{helmet.js => secure-headers.js} | 9 +++++---- lib/middleware/session.js | 1 + lib/options.js | 2 +- 5 files changed, 17 insertions(+), 13 deletions(-) rename lib/middleware/{helmet.js => secure-headers.js} (79%) diff --git a/docs/getting-started.md b/docs/getting-started.md index 6fb7691fb6..45c8ea9279 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -42,13 +42,14 @@ unleash ``` Available unleash options include: + - **db** - The database configuration object taking the following properties: - - *user* - the database username (`DATABASE_USERNAME`) - - *password* - the database password (`DATABASE_PASSWORD`) - - *host* - the database hostname (`DATABASE_HOST`) - - *port* - the datbase port defaults to 5432 (`DATABASE_PORT`) - - *database* - the database name to be used (`DATABASE_NAME`) - - *ssl* - an object describing ssl options, see https://node-postgres.com/features/ssl (`DATABASE_SSL`, as a stringified json object) + - _user_ - the database username (`DATABASE_USERNAME`) + - _password_ - the database password (`DATABASE_PASSWORD`) + - _host_ - the database hostname (`DATABASE_HOST`) + - _port_ - the datbase port defaults to 5432 (`DATABASE_PORT`) + - _database_ - the database name to be used (`DATABASE_NAME`) + - _ssl_ - an object describing ssl options, see https://node-postgres.com/features/ssl (`DATABASE_SSL`, as a stringified json object) - **databaseUrl** - the postgres database url to connect to. Only used if _db_ object is not specified. Should include username/password. This value may also be set via the `DATABASE_URL` environment variable. Alternatively, if you would like to read the database url from a file, you may set the `DATABASE_URL_FILE` environment variable with the full file path. The contents of the file must be the database url exactly. - **databaseSchema** - the postgres database schema to use. Defaults to 'public'. - **port** - which port the unleash-server should bind to. If port is omitted or is 0, the operating system will assign an arbitrary unused port. Will be ignored if pipe is specified. This value may also be set via the `HTTP_PORT` environment variable @@ -66,6 +67,7 @@ Available unleash options include: - **getLogger** (function) - Used to register a [custom log provider](#How do I configure the log output). - **eventHook** (`function(event, data)`) - If provided, this function will be invoked whenever a feature is mutated. The possible values for `event` are `'feature-created'`, `'feature-updated'`, `'feature-archived'`, `'feature-revived'`. The `data` argument contains information about the mutation. Its fields are `type` (string) - the event type (same as `event`); `createdBy` (string) - the user who performed the mutation; `data` - the contents of the change. The contents in `data` differs based on the event type; For `'feature-archived'` and `'feature-revived'`, the only field will be `name` - the name of the feature. For `'feature-created'` and `'feature-updated'` the data follows a schema defined in the code [here](https://github.com/Unleash/unleash/blob/master/lib/routes/admin-api/feature-schema.js#L38-L59). See an example [here](./guides/feautre-updates-to-slack.md). - **baseUriPath** (string) - use to register a base path for all routes on the application. For example `/my/unleash/base` (note the starting /). Defaults to `/`. Can also be configured through the environment variable `BASE_URI_PATH`. +- **secureHeaders** (boolean) - use this to enable security headers (HSTS, CSP, etc) when serving Unleash from HTTPS. Can also be configured through the environment variable `SECURE_HEADERS`. #### Disabling Auto-Start diff --git a/lib/app.js b/lib/app.js index 3fbcbf4fc8..6952fd5f22 100644 --- a/lib/app.js +++ b/lib/app.js @@ -13,7 +13,7 @@ const responseTime = require('./middleware/response-time'); const requestLogger = require('./middleware/request-logger'); const simpleAuthentication = require('./middleware/simple-authentication'); const noAuthentication = require('./middleware/no-authentication'); -const helmet = require('./middleware/helmet'); +const secureHeaders = require('./middleware/secure-headers'); module.exports = function(config) { const app = express(); @@ -35,7 +35,7 @@ module.exports = function(config) { app.use(unleashSession(config)); app.use(responseTime(config)); app.use(requestLogger(config)); - app.use(helmet(config)); + app.use(secureHeaders(config)); if (config.publicFolder) { app.use(favicon(path.join(config.publicFolder, 'favicon.ico'))); diff --git a/lib/middleware/helmet.js b/lib/middleware/secure-headers.js similarity index 79% rename from lib/middleware/helmet.js rename to lib/middleware/secure-headers.js index 5b54f4d34e..fef768db70 100644 --- a/lib/middleware/helmet.js +++ b/lib/middleware/secure-headers.js @@ -1,7 +1,7 @@ const helmet = require('helmet'); module.exports = function(config) { - if (config.enableHelmet) { + if (config.secureHeaders) { return helmet({ hsts: { maxAge: 63072000, @@ -10,12 +10,11 @@ module.exports = function(config) { }, contentSecurityPolicy: { directives: { - defaultSrc: [ + defaultSrc: ["'self'"], + fontSrc: [ "'self'", 'fonts.googleapis.com', 'fonts.gstatic.com', - 'data:', - 'gravatar.com', ], styleSrc: [ "'self'", @@ -24,6 +23,8 @@ module.exports = function(config) { 'fonts.gstatic.com', 'data:', ], + scriptSrc: ["'self'"], + imgSrc: ["'self'", 'data:', 'gravatar.com'], }, }, }); diff --git a/lib/middleware/session.js b/lib/middleware/session.js index 34cf50d097..6949f47e16 100644 --- a/lib/middleware/session.js +++ b/lib/middleware/session.js @@ -7,6 +7,7 @@ module.exports = function(config) { name: 'unleash-session', keys: [config.secret], maxAge: config.sessionAge, + secure: !!config.secureHeaders, path: config.baseUriPath === '' ? '/' : config.baseUriPath, }); }; diff --git a/lib/options.js b/lib/options.js index d96a028c72..c1a55f556b 100644 --- a/lib/options.js +++ b/lib/options.js @@ -56,7 +56,7 @@ function defaultOptions() { keepAliveTimeout: 60 * 1000, headersTimeout: 61 * 1000, version, - enableHelmet: process.env.ENABLE_HELMET || false, + secureHeaders: process.env.SECURE_HEADERS || false, }; }