From f6f526c737215fc406f8844c0d91f2f74d56cdb8 Mon Sep 17 00:00:00 2001 From: Xiao Gui <xgui3783@gmail.com> Date: Tue, 20 Aug 2019 16:03:02 +0200 Subject: [PATCH] init commit csp --- deploy/app.js | 5 +++ deploy/csp/index.js | 67 +++++++++++++++++++++++++++++++++++++++ deploy/package.json | 1 + src/index.html | 43 +++++-------------------- src/main-aot.ts | 2 ++ src/main.ts | 3 ++ third_party/testSafari.js | 31 ++++++++++++++++++ webpack.aot.js | 4 +-- webpack.common.js | 2 +- webpack.export.aot.js | 2 +- 10 files changed, 121 insertions(+), 39 deletions(-) create mode 100644 deploy/csp/index.js create mode 100644 third_party/testSafari.js diff --git a/deploy/app.js b/deploy/app.js index f233a07c6..657514945 100644 --- a/deploy/app.js +++ b/deploy/app.js @@ -45,6 +45,11 @@ app.use(session({ store })) +/** + * configure CSP + */ +require('./csp')(app) + /** * configure Auth * async function, but can start server without diff --git a/deploy/csp/index.js b/deploy/csp/index.js new file mode 100644 index 000000000..2a7a7d91e --- /dev/null +++ b/deploy/csp/index.js @@ -0,0 +1,67 @@ +const csp = require('helmet-csp') +const bodyParser = require('body-parser') + +let ALLOWED_DEFAULT_SRC, DATA_SRC + +try { + ALLOWED_DEFAULT_SRC = JSON.parse(process.env.ALLOWED_DEFAULT_SRC || '[]') +} catch (e) { + console.warn(`parsing ALLOWED_DEFAULT_SRC error ${process.env.ALLOWED_DEFAULT_SRC}`, e) + ALLOWED_DEFAULT_SRC = [] +} + +try { + DATA_SRC = JSON.parse(process.env.DATA_SRC || '[]') +} catch (e) { + console.warn(`parsing DATA_SRC error ${process.env.DATA_SRC}`, e) + DATA_SRC = [] +} + +const defaultAllowedSites = [ + "'self'", + '*.apps.hbp.eu', + '*.apps-dev.hbp.eu', + ...ALLOWED_DEFAULT_SRC +] + +const dataSource = [ + "'self'", + '*.humanbrainproject.org', + '*.humanbrainproject.eu', + '*.fz-juelich.de', + ...DATA_SRC +] + +module.exports = (app) => { + app.use(csp({ + directives: { + defaultSrc: [ + ...defaultAllowedSites + ], + styleSrc: [ + ...defaultAllowedSites, + '*.bootstrapcdn.com', + '*.fontawesome.com', + "'unsafe-inline'" // required for angular [style.xxx] bindings + ], + fontSrc: [ '*.fontawesome.com' ], + connectSrc: [ + ...defaultAllowedSites, + ...dataSource + ], + reportUri: '/report-violation' + }, + reportOnly: true + })) + + app.post('/report-violation', bodyParser.json({ + type: ['json', 'application/csp-report'] + }), (req, res) => { + if (req.body) { + console.warn(`CSP Violation: `, req.body) + } else { + console.warn(`CSP Violation: no data received!`) + } + res.status(204).end() + }) +} \ No newline at end of file diff --git a/deploy/package.json b/deploy/package.json index a1d2f4121..2d33823ef 100644 --- a/deploy/package.json +++ b/deploy/package.json @@ -17,6 +17,7 @@ "body-parser": "^1.19.0", "express": "^4.16.4", "express-session": "^1.15.6", + "helmet-csp": "^2.8.0", "jszip": "^3.2.1", "jwt-decode": "^2.2.0", "memorystore": "^1.6.1", diff --git a/src/index.html b/src/index.html index 467e979f0..5daabaa09 100644 --- a/src/index.html +++ b/src/index.html @@ -6,49 +6,22 @@ <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous"> - <link rel = "stylesheet" href = "extra_styles.css"> - <link rel = "stylesheet" href = "plugin_styles.css"> - <link rel = "stylesheet" href = "indigo-pink.css"> + <link rel="stylesheet" href="extra_styles.css"> + <link rel="stylesheet" href="plugin_styles.css"> + <link rel="stylesheet" href="indigo-pink.css"> <title>Interactive Atlas Viewer</title> </head> <body> <atlas-viewer> - <h1 style = "text-align:center;"> - <span class = "homeAnimationDots loadingAnimationDots">•</span> - <span class = "homeAnimationDots loadingAnimationDots">•</span> - <span class = "homeAnimationDots loadingAnimationDots">•</span> + <h1 class="text-center"> + <span class="homeAnimationDots loadingAnimationDots">•</span> + <span class="homeAnimationDots loadingAnimationDots">•</span> + <span class="homeAnimationDots loadingAnimationDots">•</span> </h1> </atlas-viewer> - <script> - /** - * Catching Safari 10 bug: - * - * https://bugs.webkit.org/show_bug.cgi?id=171041 - * - */ - try{ - eval('(()=>{\ - let e = e => {\ - console.log(e);\ - for(let e of [1,2,3]){\ - console.log(e);\ - }\ - }\ - })()') - }catch(e){ - console.log(e) - const warning = 'Your browser cannot display the interactive viewer. Please use either Chrome >= 56 and/or Firefox >= 51' - console.log(warning) - const warningEl = document.createElement('h4') - warningEl.innerHTML = warning - const el = document.getElementsByTagName('atlas-viewer') - if(el.length > 0){ - document.body.removeChild(el[0]) - } - document.body.appendChild(warningEl) - } + <script src="testSafari.js"> </script> </body> </html> diff --git a/src/main-aot.ts b/src/main-aot.ts index 171bd6ce7..deb5b0196 100644 --- a/src/main-aot.ts +++ b/src/main-aot.ts @@ -1,5 +1,7 @@ import 'zone.js' +import 'third_party/testSafari.js' + import { platformBrowserDynamic } from '@angular/platform-browser-dynamic' import { MainModule } from './main.module'; import { enableProdMode } from '@angular/core'; diff --git a/src/main.ts b/src/main.ts index 5eec78190..479dbb344 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,8 @@ import 'zone.js' import 'reflect-metadata' + +import 'third_party/testSafari.js' + import { platformBrowserDynamic } from '@angular/platform-browser-dynamic' import { MainModule } from './main.module'; diff --git a/third_party/testSafari.js b/third_party/testSafari.js new file mode 100644 index 000000000..b56fa557b --- /dev/null +++ b/third_party/testSafari.js @@ -0,0 +1,31 @@ + +/** +* Catching Safari 10 bug: +* +* https://bugs.webkit.org/show_bug.cgi?id=171041 +* +*/ + +(function(){ + try{ + eval('(()=>{\ + let e = e => {\ + console.log(e);\ + for(let e of [1,2,3]){\ + console.log(e);\ + }\ + }\ + })()') + } catch (e) { + console.log(e) + const warning = 'Your browser cannot display the interactive viewer. Please use either Chrome >= 56 and/or Firefox >= 51' + console.log(warning) + const warningEl = document.createElement('h4') + warningEl.innerHTML = warning + const el = document.getElementsByTagName('atlas-viewer') + if(el.length > 0){ + document.body.removeChild(el[0]) + } + document.body.appendChild(warningEl) + } +})() \ No newline at end of file diff --git a/webpack.aot.js b/webpack.aot.js index 0b8ac2211..8c815798d 100644 --- a/webpack.aot.js +++ b/webpack.aot.js @@ -19,7 +19,7 @@ module.exports = merge(staticAssets, { module: { rules: [ { - test : /export_nehuba.*?\.js$|worker\.js/, + test : /third_party.*?\.js$|worker\.js/, use : { loader : 'file-loader', options: { @@ -30,7 +30,7 @@ module.exports = merge(staticAssets, { { test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/, loader: '@ngtools/webpack', - exclude : /export_nehuba|plugin_example/ + exclude : /third_party|plugin_example/ }, { test : /\.(html|css)$/, diff --git a/webpack.common.js b/webpack.common.js index aafad55ef..9f680d8ef 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -10,7 +10,7 @@ module.exports = { exclude : /node_modules|[Ss]pec\.ts$/ }, { - test : /export_nehuba|.*?worker.*?\.js$/, + test : /third_party|.*?worker.*?\.js$/, use : { loader : 'file-loader', options: { diff --git a/webpack.export.aot.js b/webpack.export.aot.js index 8421c23bf..fda5c27b3 100644 --- a/webpack.export.aot.js +++ b/webpack.export.aot.js @@ -18,7 +18,7 @@ module.exports = { test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/, // test : /\.ts$/, loader: '@ngtools/webpack', - exclude : /export_nehuba/ + exclude : /third_party/ }, { test : /\.(html|css)$/, -- GitLab