aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRigel Kent <par@rigelk.eu>2018-12-13 09:49:45 +0100
committerChocobozzz <me@florianbigard.com>2018-12-13 09:49:45 +0100
commit5e755fff9d70a7fd3c4f85bb524f1b774dd85b25 (patch)
tree699a0724de91f4151ec7d67b700f5b7736a78e45
parent9ecac97be024cf2277872986950d7eec85cbc76e (diff)
downloadPeerTube-5e755fff9d70a7fd3c4f85bb524f1b774dd85b25.tar.gz
PeerTube-5e755fff9d70a7fd3c4f85bb524f1b774dd85b25.tar.zst
PeerTube-5e755fff9d70a7fd3c4f85bb524f1b774dd85b25.zip
add Content Security Policy (#1252)
* add Content Security Policy * remove reflect-metadata on production builds to get rid of unsafe-eval * fix baseCSP usage * add SRI to CSP * add blob: to media-src * remove SRI * CSP set to reportOnly * adding data: to connect-src CSP * remove block-all-mixed-content * add report-uri support
-rw-r--r--client/src/environments/environment.ts7
-rw-r--r--client/src/polyfills.ts8
-rw-r--r--config/default.yaml2
-rw-r--r--config/production.yaml.example2
-rw-r--r--server.ts3
-rw-r--r--server/controllers/client.ts3
-rw-r--r--server/initializers/constants.ts1
-rw-r--r--server/middlewares/csp.ts45
-rw-r--r--server/middlewares/dnt.ts2
-rw-r--r--server/middlewares/index.ts2
-rw-r--r--support/docker/production/config/custom-environment-variables.yaml4
11 files changed, 75 insertions, 4 deletions
diff --git a/client/src/environments/environment.ts b/client/src/environments/environment.ts
index 5bb6f4b34..1ea483554 100644
--- a/client/src/environments/environment.ts
+++ b/client/src/environments/environment.ts
@@ -2,6 +2,13 @@
2// `ng build --env=prod` then `environment.prod.ts` will be used instead. 2// `ng build --env=prod` then `environment.prod.ts` will be used instead.
3// The list of which env maps to which file can be found in `.angular-cli.json`. 3// The list of which env maps to which file can be found in `.angular-cli.json`.
4 4
5// Reflect.metadata polyfill is only needed in the JIT/dev mode.
6//
7// In order to load these polyfills early enough (before app code), polyfill.ts imports this file to
8// to change the order in the final bundle.
9import 'core-js/es6/reflect'
10import 'core-js/es7/reflect'
11
5export const environment = { 12export const environment = {
6 production: false, 13 production: false,
7 hmr: false, 14 hmr: false,
diff --git a/client/src/polyfills.ts b/client/src/polyfills.ts
index 5dff18632..368908432 100644
--- a/client/src/polyfills.ts
+++ b/client/src/polyfills.ts
@@ -45,7 +45,13 @@ import 'core-js/es7/object'
45/** IE10 and IE11 requires the following for the Reflect API. */ 45/** IE10 and IE11 requires the following for the Reflect API. */
46 46
47// For Google Bot 47// For Google Bot
48import 'core-js/es6/reflect' 48// import 'core-js/es6/reflect'; // --> dealt with in src/environment.ts
49
50/**
51 * Evergreen browsers require these.
52 */
53// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
54// import 'core-js/es7/reflect' // --> dealt with in src/environment.ts
49 55
50/** 56/**
51 * Required to support Web Animations `@angular/platform-browser/animations`. 57 * Required to support Web Animations `@angular/platform-browser/animations`.
diff --git a/config/default.yaml b/config/default.yaml
index 080638a13..5fdb41250 100644
--- a/config/default.yaml
+++ b/config/default.yaml
@@ -163,6 +163,8 @@ instance:
163 "# If you would like to report a security issue\n# you may report it to:\nContact: https://github.com/Chocobozzz/PeerTube/blob/develop/SECURITY.md\nContact: mailto:" 163 "# If you would like to report a security issue\n# you may report it to:\nContact: https://github.com/Chocobozzz/PeerTube/blob/develop/SECURITY.md\nContact: mailto:"
164 164
165services: 165services:
166 # You can provide a reporting endpoint for Content Security Policy violations
167 csp-logger:
166 # Cards configuration to format video in Twitter 168 # Cards configuration to format video in Twitter
167 twitter: 169 twitter:
168 username: '@Chocobozzz' # Indicates the Twitter account for the website or platform on which the content was published 170 username: '@Chocobozzz' # Indicates the Twitter account for the website or platform on which the content was published
diff --git a/config/production.yaml.example b/config/production.yaml.example
index 770bb97da..c0dbf64b6 100644
--- a/config/production.yaml.example
+++ b/config/production.yaml.example
@@ -177,6 +177,8 @@ instance:
177 "# If you would like to report a security issue\n# you may report it to:\nContact: https://github.com/Chocobozzz/PeerTube/blob/develop/SECURITY.md\nContact: mailto:" 177 "# If you would like to report a security issue\n# you may report it to:\nContact: https://github.com/Chocobozzz/PeerTube/blob/develop/SECURITY.md\nContact: mailto:"
178 178
179services: 179services:
180 # You can provide a reporting endpoint for Content Security Policy violations
181 csp-logger:
180 # Cards configuration to format video in Twitter 182 # Cards configuration to format video in Twitter
181 twitter: 183 twitter:
182 username: '@Chocobozzz' # Indicates the Twitter account for the website or platform on which the content was published 184 username: '@Chocobozzz' # Indicates the Twitter account for the website or platform on which the content was published
diff --git a/server.ts b/server.ts
index 4a2a6ddf5..6dff16f46 100644
--- a/server.ts
+++ b/server.ts
@@ -53,6 +53,9 @@ if (errorMessage !== null) {
53app.set('trust proxy', CONFIG.TRUST_PROXY) 53app.set('trust proxy', CONFIG.TRUST_PROXY)
54 54
55// Security middleware 55// Security middleware
56import { baseCSP } from './server/middlewares'
57
58app.use(baseCSP)
56app.use(helmet({ 59app.use(helmet({
57 frameguard: { 60 frameguard: {
58 action: 'deny' // we only allow it for /videos/embed, see server/controllers/client.ts 61 action: 'deny' // we only allow it for /videos/embed, see server/controllers/client.ts
diff --git a/server/controllers/client.ts b/server/controllers/client.ts
index 73b40cf65..e5bd487f1 100644
--- a/server/controllers/client.ts
+++ b/server/controllers/client.ts
@@ -2,7 +2,7 @@ import * as express from 'express'
2import { join } from 'path' 2import { join } from 'path'
3import { root } from '../helpers/core-utils' 3import { root } from '../helpers/core-utils'
4import { ACCEPT_HEADERS, STATIC_MAX_AGE } from '../initializers' 4import { ACCEPT_HEADERS, STATIC_MAX_AGE } from '../initializers'
5import { asyncMiddleware } from '../middlewares' 5import { asyncMiddleware, embedCSP } from '../middlewares'
6import { buildFileLocale, getCompleteLocale, is18nLocale, LOCALE_FILES } from '../../shared/models/i18n/i18n' 6import { buildFileLocale, getCompleteLocale, is18nLocale, LOCALE_FILES } from '../../shared/models/i18n/i18n'
7import { ClientHtml } from '../lib/client-html' 7import { ClientHtml } from '../lib/client-html'
8import { logger } from '../helpers/logger' 8import { logger } from '../helpers/logger'
@@ -22,6 +22,7 @@ clientsRouter.use('/videos/watch/:id',
22 22
23clientsRouter.use('' + 23clientsRouter.use('' +
24 '/videos/embed', 24 '/videos/embed',
25 embedCSP,
25 (req: express.Request, res: express.Response, next: express.NextFunction) => { 26 (req: express.Request, res: express.Response, next: express.NextFunction) => {
26 res.removeHeader('X-Frame-Options') 27 res.removeHeader('X-Frame-Options')
27 res.sendFile(embedPath) 28 res.sendFile(embedPath)
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts
index ad61bee73..f1a734f48 100644
--- a/server/initializers/constants.ts
+++ b/server/initializers/constants.ts
@@ -290,6 +290,7 @@ const CONFIG = {
290 get SECURITYTXT_CONTACT () { return config.get<string>('admin.email') } 290 get SECURITYTXT_CONTACT () { return config.get<string>('admin.email') }
291 }, 291 },
292 SERVICES: { 292 SERVICES: {
293 get 'CSP-LOGGER' () { return config.get<string>('services.csp-logger') },
293 TWITTER: { 294 TWITTER: {
294 get USERNAME () { return config.get<string>('services.twitter.username') }, 295 get USERNAME () { return config.get<string>('services.twitter.username') },
295 get WHITELISTED () { return config.get<boolean>('services.twitter.whitelisted') } 296 get WHITELISTED () { return config.get<boolean>('services.twitter.whitelisted') }
diff --git a/server/middlewares/csp.ts b/server/middlewares/csp.ts
new file mode 100644
index 000000000..a0ed3710b
--- /dev/null
+++ b/server/middlewares/csp.ts
@@ -0,0 +1,45 @@
1import * as helmet from 'helmet'
2import { CONFIG } from '../initializers/constants'
3
4const baseDirectives = Object.assign({},
5 {
6 defaultSrc: ["'none'"], // by default, not specifying default-src = '*'
7 connectSrc: ['*', 'data:'],
8 mediaSrc: ["'self'", 'https:', 'blob:'],
9 fontSrc: ["'self'", 'data:'],
10 imgSrc: ["'self'", 'data:'],
11 scriptSrc: ["'self' 'unsafe-inline'"],
12 styleSrc: ["'self' 'unsafe-inline'"],
13 // objectSrc: ["'none'"], // only define to allow plugins, else let defaultSrc 'none' block it
14 formAction: ["'self'"],
15 frameAncestors: ["'none'"],
16 baseUri: ["'self'"],
17 pluginTypes: ["'none'"],
18 manifestSrc: ["'self'"],
19 frameSrc: ["'self'"], // instead of deprecated child-src / self because of test-embed
20 workerSrc: ["'self'"], // instead of deprecated child-src
21 upgradeInsecureRequests: true
22 },
23 (CONFIG.SERVICES['CSP-LOGGER'] != null) ? { reportUri: CONFIG.SERVICES['CSP-LOGGER'] } : {}
24)
25
26const baseCSP = helmet.contentSecurityPolicy({
27 directives: baseDirectives,
28 browserSniff: false,
29 reportOnly: true
30})
31
32const embedCSP = helmet.contentSecurityPolicy({
33 directives: Object.assign(baseDirectives, {
34 frameAncestors: ['*']
35 }),
36 browserSniff: false, // assumes a modern browser, but allows CDN in front
37 reportOnly: true
38})
39
40// ---------------------------------------------------------------------------
41
42export {
43 baseCSP,
44 embedCSP
45}
diff --git a/server/middlewares/dnt.ts b/server/middlewares/dnt.ts
index cabad39c6..607def855 100644
--- a/server/middlewares/dnt.ts
+++ b/server/middlewares/dnt.ts
@@ -10,4 +10,4 @@ const advertiseDoNotTrack = (_, res, next) => {
10 10
11export { 11export {
12 advertiseDoNotTrack 12 advertiseDoNotTrack
13 } 13}
diff --git a/server/middlewares/index.ts b/server/middlewares/index.ts
index 0cef26953..b758a8586 100644
--- a/server/middlewares/index.ts
+++ b/server/middlewares/index.ts
@@ -6,3 +6,5 @@ export * from './pagination'
6export * from './servers' 6export * from './servers'
7export * from './sort' 7export * from './sort'
8export * from './user-right' 8export * from './user-right'
9export * from './dnt'
10export * from './csp'
diff --git a/support/docker/production/config/custom-environment-variables.yaml b/support/docker/production/config/custom-environment-variables.yaml
index cfc30632c..550f1ad80 100644
--- a/support/docker/production/config/custom-environment-variables.yaml
+++ b/support/docker/production/config/custom-environment-variables.yaml
@@ -101,9 +101,11 @@ transcoding:
101 1080: 101 1080:
102 __name: "PEERTUBE_TRANSCODING_1080P" 102 __name: "PEERTUBE_TRANSCODING_1080P"
103 __format: "json" 103 __format: "json"
104
105 104
106instance: 105instance:
107 name: "PEERTUBE_INSTANCE_NAME" 106 name: "PEERTUBE_INSTANCE_NAME"
108 description: "PEERTUBE_INSTANCE_DESCRIPTION" 107 description: "PEERTUBE_INSTANCE_DESCRIPTION"
109 terms: "PEERTUBE_INSTANCE_TERMS" 108 terms: "PEERTUBE_INSTANCE_TERMS"
109
110services:
111 csp-logger: "PEERTUBE_SERVICES_CSPLOGGER"