function addMiddleware(server) {
  if (process.env.NODE_ENV === 'production') {
    // server.use(morgan('combined'))
    server.use(compression())
    server.use(express.static(PUBLIC_DIR, { maxAge: 31536000000 }))
  }
  // } else {
  //   server.use(morgan('dev'))
  // }

  server.use(express.static(path.join(APP_PATH, 'static')))
  server.use(bodyParser.json())
  server.use(hpp())
  server.use(helmet.contentSecurityPolicy({
    defaultSrc: [ "'self'" ],
    scriptSrc: [ "'self'" ],
    styleSrc: [ "'self'" ],
    imgSrc: [ "'self'" ],
    connectSrc: [ "'self'", 'ws:' ],
    fontSrc: [ "'self'" ],
    objectSrc: [ "'none'" ],
    mediaSrc: [ "'none'" ],
    frameSrc: [ "'none'" ]
  }))
  server.use(helmet.xssFilter())
  server.use(helmet.frameguard('deny'))
  server.use(helmet.ieNoOpen())
  server.use(helmet.noSniff())
}
export function csp({ _config = config, noScriptStyles, _log = log } = {}) {
  const cspConfig =
    _config.get('CSP') !== 'false' ? deepcopy(_config.get('CSP')) : false;

  if (cspConfig) {
    if (noScriptStyles) {
      if (!_config.get('isDevelopment')) {
        const hash = crypto
          .createHash('sha256')
          .update(noScriptStyles)
          .digest('base64');

        const cspValue = `'sha256-${hash}'`;
        if (
          cspConfig.directives &&
          !cspConfig.directives.styleSrc.includes(cspValue)
        ) {
          cspConfig.directives.styleSrc.push(cspValue);
        }
      } else {
        _log.debug(oneLine`CSP style-src hash has been omitted to allow
          "unsafe-inline" in development`);
      }
    }

    return helmet.contentSecurityPolicy(cspConfig);
  }

  return (req, res, next) => {
    _log.warn('CSP has been disabled from the config');
    next();
  };
}
Example #3
0
const setupHelmet = app => {
  // Protect against some well known web vulnerabilities
  // by setting HTTP headers appropriately.
  app.use(helmet());

  // Helmet content security policy (CSP) to allow only assets from same domain.
  app.use(helmet.contentSecurityPolicy({
    directives: {
      fontSrc: ['\'self\' data:'],
      scriptSrc: ['\'self\'', '\'unsafe-inline\'', 'www.google-analytics.com', 'hmctspiwik.useconnect.co.uk', 'www.googletagmanager.com'],
      connectSrc: ['\'self\''],
      mediaSrc: ['\'self\''],
      frameSrc: ['\'none\''],
      imgSrc: ['\'self\'', 'www.google-analytics.com', 'hmctspiwik.useconnect.co.uk']
    }
  }));

  const maxAge = config.ssl.hpkp.maxAge;
  const sha256s = [ config.ssl.hpkp.sha256s, config.ssl.hpkp.sha256sBackup ];

  // Helmet HTTP public key pinning
  app.use(helmet.hpkp({ maxAge, sha256s }));

  // Helmet referrer policy
  app.use(helmet.referrerPolicy({ policy: 'origin' }));
};
Example #4
0
module.exports = function (config) {
  const cspMiddleware = helmet.contentSecurityPolicy(config.rules);

  return htmlOnly((req, res, next) => {
    if (isCspRequired(req)) {
      cspMiddleware(req, res, next);
    } else {
      next();
    }
  });
};
Example #5
0
      super.run(force).then(() => {
        const app = express();
        const router = new Router();
        const port = config.port;

        app.set('views', './private');
        app.set('view engine', 'html');
        app.engine('html', hogan);
        app.use(helmet());
        app.use(compression());
        app.use(bodyParser.json());
        app.use(bodyParser.urlencoded({ extended: true }));
        app.use(express.static('./public', { maxAge: 31557600000 }));
        if(!envs.__PROD__){
          app.use(helmet.noCache());
        }else{
          app.use(helmet.hsts({
            force: true
          , maxAge: 2592000000
          , includeSubDomains: true
          }));
          app.use(helmet.contentSecurityPolicy({
            defaultSrc: [`'self'`]
          , fontSrc: [`'self'`]
          , imgSrc: [`'self'`, 'data:']
          , scriptSrc: [
              `'self'`
            , `'unsafe-inline'`
            , `'unsafe-eval'`
            , 'http://*.facebook.com/'
            , 'https://*.facebook.com/'
            , 'https://*.google-analytics.com'
            , 'http://*.google-analytics.com'
          ]
          , styleSrc: [
              `self'`
            , `'unsafe-inline'`
            , 'http://*.facebook.com/'
            , 'https://*.facebook.com/'
            , 'https://*.google-analytics.com'
            , 'http://*.google-analytics.com'
          ]
          }));
        }

        app.use('/', router);

        app.listen(port, (err) => {
          if(err){ return reject(err); }
          console.log(`Express is listening at ${port}`);
          return resolve();
        });
      }, reject);
module.exports = function() {

	var app = express();
    
	app.use(bodyParser.urlencoded({ extended: true }));
	app.use(bodyParser.json());
    app.use(helmet());
    
    /*SEGURANÇA*/
    app.disable('x-powered-by');
    
    app.use(helmet.contentSecurityPolicy({
        // Specify directives as normal. 
        directives: {
            defaultSrc: ["'self'", 'default.com'],
            scriptSrc: ["'self'", "'unsafe-inline'"],
            styleSrc: ['style.com'],
            imgSrc: ['img.com', 'data:'],
            sandbox: ['allow-forms', 'allow-scripts'],
            reportUri: '/report-violation',
            objectSrc: [] // An empty array allows nothing through 
        },
        
        // Set to true if you only want browsers to report errors, not block them 
        reportOnly: false,
        
        // Set to true if you want to blindly set all headers: Content-Security-Policy, 
        // X-WebKit-CSP, and X-Content-Security-Policy. 
        setAllHeaders: false,
        
        // Set to true if you want to disable CSP on Android where it can be buggy. 
        disableAndroid: false,
        
        // Set to false if you want to completely disable any user-agent sniffing. 
        // This may make the headers less compatible but it will be much faster. 
        // This defaults to `true`. 
        browserSniff: true
    }));
        
    app.use(helmet.xssFilter())
    
	load('routes', {cwd: 'app'})
		.then('infra')
		.into(app);

	return app;
}
function addMiddleware(server) {
  server.use(express.static(path.join(APP_PATH, 'static')))
  server.use(bodyParser.json())
  server.use(hpp())
  server.use(helmet.contentSecurityPolicy({
    defaultSrc: [ "'self'" ],
    scriptSrc: [ "'self'" ],
    styleSrc: [ "'self'" ],
    imgSrc: [ "'self'" ],
    connectSrc: [ "'self'", 'ws:' ],
    fontSrc: [ "'self'" ],
    objectSrc: [ "'none'" ],
    mediaSrc: [ "'none'" ],
    frameSrc: [ "'none'" ]
  }))
  server.use(helmet.xssFilter())
  server.use(helmet.frameguard('deny'))
  server.use(helmet.ieNoOpen())
  server.use(helmet.noSniff())
}
Example #8
0
function bootstrap(options) {

  let config = getConfig(options);

  const app = express();
  const userMiddleware = express.Router();

  app.use(helmet());

  if (config.csp !== false && !config.csp.disabled) {
    app.use(helmet.contentSecurityPolicy({
      directives: getContentSecurityPolicy(config)
    }));
  }

  // shallow health check
  app.get('/healthz/ping', require('express-healthcheck')());

  if (!config || !config.routes || !config.routes.length) {
    throw new Error('Must be called with a list of routes');
  }

  config.routes.forEach(route => {
    if (!route.steps && !route.pages) {
      throw new Error('Each app must have steps and/or pages');
    }
  });

  config.logger = logger(config);
  app.use(churchill(config.logger));

  if (config.middleware) {
    config.middleware.forEach(middleware => app.use(middleware));
  }

  serveStatic(app, config);
  settings(app, config);
  sessionStore(app, config);

  app.use(translate({
    resources: config.theme.translations,
    path: path.resolve(config.root, config.translations) + '/__lng__/__ns__.json'
  }));
  app.use(mixins());
  app.use(markdown(config.markdown));

  if (config.getCookies === true) {
    deprecate(
      '`getCookies` option is deprecated and may be removed in future versions.',
      'Use `pages` to define static cookies page.'
    );
    app.get('/cookies', (req, res) => {
      res.render('cookies', req.translate('cookies'));
    });
  }
  if (config.getTerms === true) {
    deprecate(
      '`getTerms` option is deprecated and may be removed in future versions.',
      'Use `pages` to define static terms and conditions page.'
    );
    app.get('/terms-and-conditions', (req, res) => {
      res.render('terms', req.translate('terms'));
    });
  }

  app.use(userMiddleware);
  app.use(hofMiddleware.cookies());
  loadRoutes(app, config);
  applyErrorMiddlewares(app, config);

  const instance = {

    use() {
      userMiddleware.use.apply(userMiddleware, arguments);
      return instance;
    },

    server: null,

    start: (startConfig) => {
      startConfig = getConfig(config, startConfig);

      const protocol = startConfig.protocol === 'http' ? http : https;

      instance.server = protocol.createServer(app);

      return new Promise((resolve, reject) => {
        instance.server.listen(startConfig.port, startConfig.host, err => {
          if (err) {
            reject(new Error('Unable to connect to server'));
          }
          resolve(instance);
        });
      });
    },

    stop() {
      return new Promise((resolve, reject) => instance.server.close(err => {
        if (err) {
          reject(new Error('Unable to stop server'));
        }
        resolve(instance);
      }));
    }
  };

  if (config.start !== false) {
    instance.start(config);
  }

  return instance;

}
Example #9
0
app.use(helmet.frameguard());
app.use(helmet.hidePoweredBy());
app.use(helmet.ieNoOpen());
app.use(helmet.noSniff());
app.use(helmet.xssFilter());
app.use(helmet.hsts({
    maxAge: 31536000,
    includeSubdomains: true,
    force: httpsEnabled,
    preload: true
}));
app.use(helmet.contentSecurityPolicy({
    defaultSrc: ['\'none\''],
    connectSrc: ['*'],
    scriptSrc: ['\'self\'', '\'unsafe-eval\''],
    styleSrc: ['\'self\'', 'fonts.googleapis.com', '\'unsafe-inline\''],
    fontSrc: ['\'self\'', 'fonts.gstatic.com'],
    mediaSrc: ['\'self\''],
    objectSrc: ['\'self\''],
    imgSrc: ['*']
}));

var bundles = {};
app.use(require('connect-assets')({
    paths: [
        'media/js',
        'media/less'
    ],
    helperContext: bundles,
    build: settings.env === 'production',
    fingerprinting: settings.env === 'production',
    servePath: 'media/dist'
Example #10
0
var express = require('express');
var helmet = require('helmet');
var app = express();

app.use(helmet.contentSecurityPolicy());
app.use(express.static("public"));

var server = app.listen(3000, function () {

  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);

});
const isDeveloping = process.env.NODE_ENV == 'development'
const port = process.env.PORT || 5000
const server = global.server = express()

// Security
server.disable('x-powered-by')
server.set('port', port)
server.use(bodyParser.urlencoded({ extended: false }))
server.use(bodyParser.json())
server.use(hpp())
server.use(helmet.contentSecurityPolicy({
  defaultSrc: ["'self'"],
  scriptSrc: ["'self'"],
  styleSrc: ["'self'"],
  imgSrc: ["'self'"],
  connectSrc: ["'self'", 'ws:'],
  fontSrc: ["'self'"],
  objectSrc: ["'none'"],
  mediaSrc: ["'none'"],
  frameSrc: ["'none'"]
}))
server.use(helmet.xssFilter())
server.use(helmet.frameguard('deny'))
server.use(helmet.ieNoOpen())
server.use(helmet.noSniff())
server.use(cookieParser())
server.use(compression())

// API
server.use('/api/v0/posts', require('./api/posts'))
server.use('/api/v0/post', require('./api/post'))
Example #12
0
mongoose.connect(settings.database.uri, function(err) {
    if (err) {
        throw err;
    }

    //
    // express.oi Setup
    //
    if (httpsEnabled) {
        app = express().https({
            key: fs.readFileSync(settings.https.key),
            cert: fs.readFileSync(settings.https.cert),
            passphrase: settings.https.passphrase
        }).io();
    } else {
        app = express().http().io();
    }

    if (settings.env === 'production') {
        app.set('env', settings.env);
        app.set('json spaces', undefined);
        app.enable('view cache');
    }

    // Session
    var sessionStore = new MongoStore({
        mongooseConnection: mongoose.connection
    });

    // Session
    var session = {
        key: 'connect.sid',
        secret: settings.secrets.cookie,
        store: sessionStore,
        cookie: { secure: httpsEnabled },
        resave: false,
        saveUninitialized: true
    };

    // Set compression before any routes
    app.use(compression({ threshold: 512 }));

    app.use(cookieParser());
    app.io.session(session);

    auth.setup(app, session, core);

    // Security protections
    app.use(helmet.frameguard());
    app.use(helmet.hidePoweredBy());
    app.use(helmet.ieNoOpen());
    app.use(helmet.noSniff());
    app.use(helmet.xssFilter());
    app.use(helmet.hsts({
        maxAge: 31536000,
        includeSubdomains: true,
        force: httpsEnabled,
        preload: true
    }));
    app.use(helmet.contentSecurityPolicy({
        defaultSrc: ['\'none\''],
        connectSrc: ['*'],
        scriptSrc: ['\'self\'', '\'unsafe-eval\''],
        styleSrc: ['\'self\'', 'fonts.googleapis.com', '\'unsafe-inline\''],
        fontSrc: ['\'self\'', 'fonts.gstatic.com'],
        mediaSrc: ['\'self\''],
        objectSrc: ['\'self\''],
        imgSrc: ['* data:']
    }));

    var bundles = {};
    app.use(require('connect-assets')({
        paths: [
            'media/js',
            'media/less'
        ],
        helperContext: bundles,
        build: settings.env === 'production',
        fingerprinting: settings.env === 'production',
        servePath: 'media/dist'
    }));

    // Public
    app.use('/media', express.static(__dirname + '/media', {
        maxAge: '364d'
    }));

    // Templates
    var nun = nunjucks.configure('templates', {
        autoescape: true,
        express: app,
        tags: {
            blockStart: '<%',
            blockEnd: '%>',
            variableStart: '<$',
            variableEnd: '$>',
            commentStart: '<#',
            commentEnd: '#>'
        }
    });

    function wrapBundler(func) {
        // This method ensures all assets paths start with "./"
        // Making them relative, and not absolute
        return function() {
            return func.apply(func, arguments)
                       .replace(/href="\//g, 'href="./')
                       .replace(/src="\//g, 'src="./');
        };
    }

    nun.addFilter('js', wrapBundler(bundles.js));
    nun.addFilter('css', wrapBundler(bundles.css));
    nun.addGlobal('text_search', false);

    // i18n
    i18n.configure({
        directory: path.resolve(__dirname, './locales'),
        locales: settings.i18n.locales || settings.i18n.locale,
        defaultLocale: settings.i18n.locale
    });
    app.use(i18n.init);

    // HTTP Middlewares
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({
        extended: true
    }));

    // IE header
    app.use(function(req, res, next) {
        res.setHeader('X-UA-Compatible', 'IE=Edge,chrome=1');
        next();
    });

    //
    // Controllers
    //
    _.each(controllers, function(controller) {
        controller.apply({
            app: app,
            core: core,
            settings: settings,
            middlewares: middlewares,
            models: models,
            controllers: controllers
        });
    });

    //
    // Go Time
    //

    if (!mongoose.mongo || !mongoose.mongo.Admin) {
        // MongoDB API has changed, assume text search is enabled
        nun.addGlobal('text_search', true);
        return;
    }

    var admin = new mongoose.mongo.Admin(mongoose.connection.db);
    admin.buildInfo(function (err, info) {
        if (err || !info) {
            return;
        }

        var version = info.version.split('.');
        if (version.length < 2) {
            return;
        }

        if(version[0] < 2) {
            return;
        }

        if(version[0] === '2' && version[1] < 6) {
            return;
        }

        nun.addGlobal('text_search', true);
    });

    var port = httpsEnabled && settings.https.port ||
               httpEnabled && settings.http.port;

    var host = httpsEnabled && settings.https.host ||
               httpEnabled && settings.http.host || '0.0.0.0';

    if (httpsEnabled && httpEnabled) {
        // Create an HTTP -> HTTPS redirect server
        var redirectServer = express();
        redirectServer.get('*', function(req, res) {
            var urlPort = port === 80 ? '' : ':' + port;
            res.redirect('https://' + req.hostname + urlPort + req.path);
        });
        http.createServer(redirectServer)
            .listen(settings.http.port || 5000, host);
    }

    app.listen(port, host);

    //
    // XMPP
    //
    if (settings.xmpp.enable) {
        var xmpp = require('./app/xmpp/index');
        xmpp(core);
    }

    var art = fs.readFileSync('./app/misc/art.txt', 'utf8');
    console.log('\n' + art + '\n\n' + 'Release ' + psjon.version.yellow + '\n');
});
Example #13
0
// configure app to handle CORS requests
app.use(function(req, res, next) {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
  res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization');
  next();
});

app.use(helmet());

app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'"],
		styleSrc: ["'self'", 'https://netdna.bootstrapcdn.com','https://ajax.googleapis.com','https://fonts.googleapis.com',"'unsafe-inline'"],
		fontSrc: ['https://netdna.bootstrapcdn.com','https://fonts.gstatic.com'],
		imgSrc: ["'self'", 'data:'],
		connectSrc: ["'self'", 'https://www.googleapis.com'],
    scriptSrc: ["'self'"],
  }
}))

require('./app/config/passport')(passport); // pass passport for configuration

// log all requests to the console 
app.use(morgan('dev'));

// connect to database (hosted on mongolab)
mongoose.Promise = global.Promise;
mongoose.connect(db); 

// set static files location
module.exports = helmet.contentSecurityPolicy({
  directives: {
    reportUri: `${BASE_PATH}api/v1/csp`, // report all policy violations to our reporting uri
    defaultSrc: ["'none'"], // by default, do not allow anything at all
    scriptSrc: [
      "'self'",
      'https://ajax.googleapis.com', // for jquery
      staticSrc, // for any static files loaded from a cdn
      nonceSrc,
    ],
    styleSrc: [
      "'self'",
      'https://maxcdn.bootstrapcdn.com', // for bootstrap css
      'https://fonts.googleapis.com', // for google fonts
      'https://code.getmdl.io', // for mdl css
      staticSrc, // for any static files loaded from a cdn
      nonceSrc,
    ],
    connectSrc: ["'self'", websocketSrc],
    fontSrc: [
      "'self'",
      'https://maxcdn.bootstrapcdn.com', // for font-awesome
      'https://fonts.gstatic.com', // for google fonts
      staticSrc, // for any static files loaded from a cdn
      nonceSrc,
    ],
    imgSrc: [
      "'self'",
      staticSrc, // for any static files loaded from a cdn
      nonceSrc,
    ],
  },
  browserSniff: false,
  // Allow the configuration to disable strict enforcement of CSP.
  reportOnly: !ENABLE_STRICT_CSP,
});
Example #15
0
module.exports = function(settings, callback) {
  var https = require('https');
  var http = require('http');
  var fs = require('fs');
  var path = require('path');
  var express = require('express');
  var helmet = require('helmet')
  var bodyParser = require('body-parser');
  var logger = require('./lib/log/logger');
  var HttpStatus = require('http-status-codes');
  
  var validateResult = settings.validate();
  if (validateResult.valid === false) {
      logger.error("Invalid configuration: " + validateResult.message);
      throw new Error('settings.json is invalid');
  }
  var serviceBrokerUtil = require('./lib/utils/serviceBrokerUtils')(settings.serviceOffering.serviceBroker);
  var oauth = require('./lib/oauth/oauth')(settings);
  var models = require('./lib/models')(settings.db, callback);
  
  
  var port = settings.port;
  var publicPort = settings.publicPort;
  
  var options = {};
    
  if(settings.tls){
    if(!fs.existsSync(settings.tls.keyFile)){
        logger.error("Invalid TLS key path: " + settings.tls.keyFile);
        throw new Error("Invalid TLS key path: " + settings.tls.keyFile);
    }
    if(!fs.existsSync(settings.tls.certFile)){
        logger.error("Invalid TLS certificate path: " + settings.tls.certFile);
        throw new Error("Invalid TLS certificate path: " + settings.tls.certFile);
    }
    if(!fs.existsSync(settings.tls.caCertFile)){
        logger.error("Invalid TLS ca certificate path: " + settings.tls.caCertFile);
        throw new Error("Invalid TLS ca certificate path: " + settings.tls.caCertFile);
    }

    options = {
        key: fs.readFileSync(settings.tls.keyFile),
        cert: fs.readFileSync(settings.tls.certFile),
        ca: fs.readFileSync(settings.tls.caCertFile)
    }
  }

  var publicOptions = {};
    
  if(settings.publicTls){
    if(!fs.existsSync(settings.publicTls.keyFile)){
        logger.error("Invalid public TLS key path: " + settings.publicTls.keyFile);
        throw new Error("Invalid public TLS key path: " + settings.publicTls.keyFile);
    }
    if(!fs.existsSync(settings.publicTls.certFile)){
        logger.error("Invalid public TLS certificate path: " + settings.publicTls.certFile);
        throw new Error("Invalid public TLS certificate path: " + settings.publicTls.certFile);
    }
    if(!fs.existsSync(settings.publicTls.caCertFile)){
        logger.error("Invalid public TLS ca certificate path: " + settings.publicTls.caCertFile);
        throw new Error("Invalid public TLS ca certificate path: " + settings.publicTls.caCertFile);
    }

    publicOptions = {
        key: fs.readFileSync(settings.publicTls.keyFile),
        cert: fs.readFileSync(settings.publicTls.certFile),
        ca: fs.readFileSync(settings.publicTls.caCertFile)
    }
  }
  var checkBinding = function(req, res, next){
    if (settings.serviceOffering.enabled) {
      serviceBrokerUtil.checkBinding(req.params,function(error,result){
        if(error){
          res.status(HttpStatus.INTERNAL_SERVER_ERROR).send({});
        }else{
          if(result.statusCode == HttpStatus.OK){
            next();
          }else if(result.statusCode == HttpStatus.NOT_FOUND){
            res.status(HttpStatus.FORBIDDEN).send({"error": "The application is not bound to Auto-Scaling service"});
          }else{
            res.status(HttpStatus.INTERNAL_SERVER_ERROR).send({});
          }
        }
      });
    } else {
      next();
    }
  }
  var app = express();
  app.use(helmet())
  app.use(helmet.contentSecurityPolicy({
    directives: {
      defaultSrc : ['\'self\'' ],
      scriptSrc : [ '\'self\''],
    },
    browserSniff: false
  }))
  app.use(helmet.noCache())
  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({ extended: false }));
  app.use('/health', require('express-healthcheck')());
  var policies = require('./lib/routes/policies')(settings, models);
  var scalingHistories = require('./lib/routes/scalingHistories')(settings);
  var metrics = require('./lib/routes/metrics')(settings);
  var aggregatedMetrics = require('./lib/routes/aggregated_metrics')(settings);

  app.use('/v1/apps',policies);
  app.use(function(err, req, res, next) {
    var errorResponse = {};
    if (err) {
      errorResponse = {
        'error': err,
      };
    }
    res.status(HttpStatus.BAD_REQUEST).json(errorResponse);
  });

  var publicApp = express();
  publicApp.use(helmet())
  publicApp.use(helmet.contentSecurityPolicy({
    directives: {
      defaultSrc : ['\'self\'' ],
      scriptSrc : [ '\'self\''],
    },
    browserSniff: false
  }))
  publicApp.use(helmet.noCache())
  publicApp.use(bodyParser.json());
  publicApp.use(bodyParser.urlencoded({ extended: false }));
  publicApp.use('/v1/apps/:app_id/*',function(req, res, next){
    oauth.checkUserAuthorization(req,function(error,isSpaceDeveloper){
      if(error){
        if(error.statusCode == HttpStatus.UNAUTHORIZED){
          res.status(HttpStatus.UNAUTHORIZED).send({});
        }else{
          res.status(HttpStatus.INTERNAL_SERVER_ERROR).send({});
        }
      }else{
        if(isSpaceDeveloper){
          next();
        }else{
          res.status(HttpStatus.UNAUTHORIZED).send({});
        }
      }
    });
  });
  publicApp.use('/health', require('express-healthcheck')());
  var info = require('./lib/routes/info')(settings);

  publicApp.use('/v1/apps/:app_id/policy', checkBinding);
  publicApp.use('/v1', info);
  publicApp.use('/v1/apps',policies);
  publicApp.use('/v1/apps',scalingHistories);
  publicApp.use('/v1/apps',metrics);
  publicApp.use('/v1/apps',aggregatedMetrics);
  publicApp.use(function(err, req, res, next) {
    var errorResponse = {};
    if (err) {
      errorResponse = {
        'error': err,
      };
    }
    res.status(HttpStatus.BAD_REQUEST).json(errorResponse);
  });

  var server;
  if(settings.tls){
    server = https.createServer(options, app).listen(port || 3002, function() {
        logger.info('Autoscaler API server started in secure mode',{'port':server.address().port} );    
    });
  }else{
    server = http.createServer(app).listen(port || 3002, function() {
        logger.info('Autoscaler API server started',{'port':server.address().port} );    
    });
  }
  
  var publicServer;
  if(settings.publicTls){
    publicServer = https.createServer(publicOptions, publicApp).listen(publicPort || 3003, function() {
        logger.info('Autoscaler public API server started in secure mode',{'port':publicServer.address().port} );    
    });
  }else{
    publicServer = http.createServer(publicApp).listen(publicPort || 3003, function() {
        logger.info('Autoscaler public API server started',{'port':publicServer.address().port} );    
    });
  }


  var gracefulShutdown = function(signal) {
    logger.info("Received " + signal + " signal, shutting down gracefully...");
    server.close(function() {
      logger.info('Everything is cleanly shutdown for internal API server');
      publicServer.close(function() {
        logger.info('Everything is cleanly shutdown for public API server');
        process.exit();
      });
    });
    
  }

  //listen for SIGUSR2 signal e.g. user-defined signal
  process.on ('SIGUSR2', function(){
    gracefulShutdown('SIGUSR2')
  });

  return {"internalServer": server, "publicServer": publicServer};
}
Example #16
0
app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: [
      'www.youtube.com',
      'https://public.etherpad-mozilla.org'
    ],
    scriptSrc: [
      '\'self\'',
      '\'unsafe-inline\'',
      '\'unsafe-eval\'',
      'data:',
      'www.google-analytics.com',
      'cdn.optimizely.com',
      'https://www.google.com',
      'https://s.ytimg.com',
      'https://www.mozilla.org'
    ],
    fontSrc: [
      '\'self\'',
      'fonts.googleapis.com',
      'fonts.gstatic.com'
    ],
    styleSrc: [
      '\'self\'',
      '\'unsafe-inline\'',
      'https://www.google.com',
      'fonts.googleapis.com',
      'https://api.tiles.mapbox.com',
      'https://s.ytimg.com'
    ],
    imgSrc: [
      '\'self\'',
      '\'unsafe-inline\'',
      'twemoji.maxcdn.com',
      'https://upload.wikimedia.org',
      '*.tiles.mapbox.com',
      'www.google-analytics.com',
      '*.log.optimizely.com'
    ],
    connectSrc: [
      '\'self\'',
      'https://www.google.com',
      '*.tiles.mapbox.com',
      '*.log.optimizely.com',
      '*.mywebmaker.org',
      '*.makes.org',
      'bitly.mofoprod.net',
      process.env.TEACH_API_URL || 'https://teach-api.herokuapp.com',
      url.parse(process.env.NEWSLETTER_MAILINGLIST_URL || 'https://basket-dev.allizom.org').hostname
    ]
  },
  reportOnly: false,
  browserSniff: false
}));
Example #17
0
// Add referrer policy to improve privacy
app.use(
  helmet.referrerPolicy({
    policy: 'same-origin'
  })
)

// Generate a random nonce per request, for CSP with inline scripts
app.use(csp.addNonceToLocals)

// use Content-Security-Policy to limit XSS, dangerous plugins, etc.
// https://helmetjs.github.io/docs/csp/
if (config.csp.enable) {
  app.use(helmet.contentSecurityPolicy({
    directives: csp.computeDirectives()
  }))
} else {
  logger.info('Content-Security-Policy is disabled. This may be a security risk.')
}

i18n.configure({
  locales: ['en', 'zh-CN', 'zh-TW', 'fr', 'de', 'ja', 'es', 'ca', 'el', 'pt', 'it', 'tr', 'ru', 'nl', 'hr', 'pl', 'uk', 'hi', 'sv', 'eo', 'da', 'ko'],
  cookie: 'locale',
  directory: path.join(__dirname, '/locales'),
  updateFiles: config.updateI18nFiles
})

app.use(cookieParser())

app.use(i18n.init)
Example #18
0
Security.prototype = {
  csp(directiveList) {
    directiveList = directiveList || {};
    Object.keys(defaultCSPDirectives).forEach(function(directive) {
      let domainsToAdd = directiveList[directive];
      let defaultDomains = defaultCSPDirectives[directive];

      if(domainsToAdd && defaultDomains.indexOf("*") !== -1) {
        directiveList[directive] = domainsToAdd;
      } else {
        directiveList[directive] = defaultDomains.concat((domainsToAdd || []));
      }
    });

    this.server.use(helmet.contentSecurityPolicy({
      directives: directiveList
    }));

    return this;
  },
  ssl() {
    this.server.use(helmet.hsts({ maxAge: ONE_YEAR }));
    this.server.enable("trust proxy");

    return this;
  },
  xss() {
    this.server.use(helmet.xssFilter());
    return this;
  },
  mimeSniff() {
Example #19
0
app.use(nonceMiddleware, helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'none'"],
    baseUri: ['https://docs.helpscout.net'],
    scriptSrc: [
      "'self'",
      "'strict-dynamic'",
      (req, res) => {
        return `'nonce-${res.locals.nonce}'`;
      },
      'https://beacon-v2.helpscout.net',
      'https://d12wqas9hcki3z.cloudfront.net',
      'https://d33v4339jhl8k0.cloudfront.net',
    ],
    styleSrc: [
      "'self'",
      'blob:',
      "'unsafe-inline'",
      'https://fonts.googleapis.com',
      'https://beacon-v2.helpscout.net',
      'https://djtflbt20bdde.cloudfront.net',
    ],
    imgSrc: [
      "'self'",
      'data:',
      'https://d33v4339jhl8k0.cloudfront.net',
      'https://*.gravatar.com',
    ],
    fontSrc: ["'self'", 'data:', 'https://fonts.gstatic.com'],
    reportUri: '/event/csp-report/violation',
    objectSrc: ['blob:', 'https://beacon-v2.helpscout.net'],
    workerSrc: ["'self'", 'blob:'],
    childSrc: ["'self'", 'blob:', 'https://docs.google.com'],
    frameSrc: ['https://beacon-v2.helpscout.net', 'https://docs.google.com'],
    connectSrc: [].concat([
      process.env.API_HOST,
      'https://api.github.com/repos/tidepool-org/chrome-uploader/releases',
      'https://beaconapi.helpscout.net',
      'https://chatapi.helpscout.net',
      'https://d3hb14vkzrxvla.cloudfront.net',
      'wss\://*.pusher.com',
      '*.sumologic.com',
      'sentry.io',
    ]),
  },
  reportOnly: false,
}));
Example #20
0
var routes = require('./routes/index');

var app = express();

app.disable('x-powered-by');

//Security settings
app.use(helmet.xssFilter());
app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'"],
    scriptSrc: ["'self'","'unsafe-inline'",'https://maxcdn.bootstrapcdn.com'],
    styleSrc: ["'self'","'unsafe-inline'",'https://maxcdn.bootstrapcdn.com'],
    imgSrc: ["'self'"],
    fontSrc: ['https://maxcdn.bootstrapcdn.com'],
    connectSrc: [],
  },

  reportOnly:false,
  setAllHeaders: false,
  disableAndroid: false

}));

app.set('trust proxy', 1) // trust first proxy
app.use( session({
   secret : 's3Cur3',
   name : 'sessionId',
  })
);
Example #21
0
function baseServer(routes, createStore, { appInstanceName = appName } = {}) {
  const app = new Express();
  app.disable('x-powered-by');

  app.use(logRequests);

  // Set HSTS, note: helmet uses ms not seconds.
  app.use(helmet.hsts({ maxAge: 31536000000, force: true }));

  // Sets X-Frame-Options
  app.use(helmet.frameguard(config.get('frameGuard')));

  // Sets x-content-type-options:"nosniff"
  app.use(helmet.noSniff());

  // Sets x-xss-protection:"1; mode=block"
  app.use(helmet.xssFilter());

  // CSP configuration.
  app.use(helmet.contentSecurityPolicy(config.get('CSP')));

  if (config.get('enableNodeStatics')) {
    app.use(Express.static(path.join(config.get('basePath'), 'dist')));
  }

  // Return version information as json
  app.get('/__version__', (req, res) => {
    fs.stat(version, (err) => {
      if (err) {
        res.sendStatus(415);
      } else {
        res.setHeader('Content-Type', 'application/json');
        fs.createReadStream(version).pipe(res);
      }
    });
  });

  // Return 200 for csp reports - this will need to be overridden when deployed.
  app.post('/__cspreport__', (req, res) => res.status(200).end('ok'));

  // Redirect from / for the search app it's a 302 to prevent caching.
  if (appInstanceName === 'search') {
    app.get('/', (req, res) => res.redirect(302, '/search'));
  }

  if (appInstanceName === 'disco' && isDevelopment) {
    app.get('/', (req, res) =>
      res.redirect(302, '/en-US/firefox/discovery/pane/48.0/Darwin/normal'));
  }

  // Handle application and lang redirections.
  if (config.get('enablePrefixMiddleware')) {
    app.use(prefixMiddleWare);
  }

  app.use((req, res) => {
    if (isDevelopment) {
      log.info('Clearing require cache for webpack isomorphic tools. [Development Mode]');

      // clear require() cache if in development mode
      webpackIsomorphicTools.refresh();
    }

    match({ routes, location: req.url }, (err, redirectLocation, renderProps) => {
      cookie.plugToRequest(req, res);

      if (err) {
        log.error({ err, req });
        return showErrorPage(res, 500);
      }

      if (!renderProps) {
        return showErrorPage(res, 404);
      }

      const store = createStore();
      const token = cookie.load(config.get('cookieName'));
      if (token) {
        store.dispatch(setJWT(token));
      }
      // Get SRI for deployed services only.
      const sriData = (isDeployed) ? JSON.parse(
        fs.readFileSync(path.join(config.get('basePath'), 'dist/sri.json'))
      ) : {};

      // Check the lang supplied by res.locals.lang for validity
      // or fall-back to the default.
      const lang = isValidLang(res.locals.lang) ? res.locals.lang : config.get('defaultLang');
      const dir = getDirection(lang);
      const locale = langToLocale(lang);
      store.dispatch(setLang(lang));

      function hydrateOnClient(props = {}) {
        const pageProps = {
          appName: appInstanceName,
          assets: webpackIsomorphicTools.assets(),
          htmlLang: lang,
          htmlDir: dir,
          includeSri: isDeployed,
          sriData,
          store,
          trackingEnabled: convertBoolean(config.get('trackingEnabled')),
          ...props,
        };

        const HTML = ReactDOM.renderToString(
          <ServerHtml {...pageProps} />);
        res.send(`<!DOCTYPE html>\n${HTML}`);
      }

      // Set disableSSR to true to debug
      // client-side-only render.
      if (config.get('disableSSR') === true) {
        return Promise.resolve(hydrateOnClient());
      }

      return loadOnServer({ ...renderProps, store })
        .then(() => {
          // eslint-disable-next-line global-require
          let jedData = {};
          try {
            if (locale !== langToLocale(config.get('defaultLang'))) {
              // eslint-disable-next-line global-require, import/no-dynamic-require
              jedData = require(`json!../../locale/${locale}/${appInstanceName}.json`);
            }
          } catch (e) {
            log.info(`Locale JSON not found or required for locale: "${locale}"`);
            log.info(`Falling back to default lang: "${config.get('defaultLang')}".`);
          }
          const i18n = new Jed(jedData);
          const InitialComponent = (
            <I18nProvider i18n={i18n}>
              <Provider store={store} key="provider">
                <ReduxAsyncConnect {...renderProps} />
              </Provider>
            </I18nProvider>
          );

          const asyncConnectLoadState = store.getState().reduxAsyncConnect.loadState || {};

          // Create a list of any apiErrors detected.
          const apiErrors = Object.keys(asyncConnectLoadState)
            .map((item) => asyncConnectLoadState[item].error)
            .filter((item) => item);

          if (apiErrors.length === 1) {
            // If we have a single API error reflect that in the page's response.
            const apiStatus = apiErrors[0].response.status;
            return showErrorPage(res, apiStatus);
          } else if (apiErrors.length > 1) {
            // Otherwise we have multiple api errors it should be logged
            // and throw a 500.
            log.error(apiErrors);
            return showErrorPage(res, 500);
          }

          return hydrateOnClient({ component: InitialComponent });
        })
        .catch((error) => {
          log.error({ err: error });
          return showErrorPage(res, 500);
        });
    });
  });

  // eslint-disable-next-line no-unused-vars
  app.use((err, req, res, next) => {
    log.error({ err });
    return showErrorPage(500);
  });

  return app;
}
Example #22
0
// app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(helmet());
app.use(helmet.hidePoweredBy());
app.use(helmet.frameguard("allow-from", process.env["WEB_HOSTNAME"] || ("http://localhost:8080") ));
app.use(helmet.contentSecurityPolicy({
  defaultSrc: ["'self'"],
  scriptSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'", "*.jsdelivr.net", "jsconsole.com"],
  styleSrc: ["'self'", "'unsafe-inline'", "*.jsdelivr.net"],
  imgSrc: ["'self'", "*.jsdelivr.net"],
  connectSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'", "ws://*"],
  fontSrc: ["fonts.google.com"],
  objectSrc: ["'self'"],
  mediaSrc: ["'self'"],
  frameSrc: ["'self'"],
  //sandbox: ["allow-forms", "allow-scripts", "allow-same-origin"],
  reportUri: '/report-violation',
  //reportOnly: true, // set to true if you only want to report errors
  //setAllHeaders: false, // set to true if you want to set all headers
  //disableAndroid: false, // set to true if you want to disable Android (browsers can vary and be buggy)
  //safari5: false // set to true if you want to force buggy CSP in Safari 5
}));
app.use(function(req, res, next) {
  res.setHeader("Access-Control-Allow-Origin", "*");

  // Request methods you wish to allow
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

  // Request headers you wish to allow
Example #23
0
const express = require("express");
const helmet = require("helmet");
const errorHandler_1 = require("./middlewares/errorHandler");
const notFoundHandler_1 = require("./middlewares/notFoundHandler");
const mongooseConnectionOptions_1 = require("../mongooseConnectionOptions");
const debug = createDebug('sskts-webhook:app');
const app = express();
app.use(middlewares.basicAuth({
    name: process.env.BASIC_AUTH_NAME,
    pass: process.env.BASIC_AUTH_PASS
}));
app.use(cors()); // enable All CORS Requests
app.use(helmet());
app.use(helmet.contentSecurityPolicy({
    directives: {
        defaultSrc: ['\'self\'']
        // styleSrc: ['\'unsafe-inline\'']
    }
}));
app.use(helmet.referrerPolicy({ policy: 'no-referrer' }));
const SIXTY_DAYS_IN_SECONDS = 5184000;
app.use(helmet.hsts({
    maxAge: SIXTY_DAYS_IN_SECONDS,
    includeSubdomains: false
}));
// view engine setup
// app.set('views', `${__dirname}/views`);
// app.set('view engine', 'ejs');
app.use(bodyParser.json());
// The extended option allows to choose between parsing the URL-encoded data
// with the querystring library (when false) or the qs library (when true).
app.use(bodyParser.urlencoded({ extended: true }));
Example #24
0
}));
app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'"],
    baseUri: ["'self'"],
    childSrc: ["'none'"],
    connectSrc: ["'self'"],
    fontSrc: ["'none'"],
    formAction: ["'self'"],
    frameAncestors: ["'none'"],
    imgSrc: ['data:', '*'],
    mediaSrc: ["'none'"],
    objectSrc: ["'none'"],
    scriptSrc: ["'self'", function (req, res) {
      if (typeof res !== "undefined" && typeof res.locals !== "undefined") {
        res.locals.nonce = uuid.v4();
        return "'nonce-" + res.locals.nonce + "'";
      } else {
        return null;
      }
    }],
    styleSrc: ["'self'"],
    //  sandbox: ['allow-forms', 'allow-scripts'],
    //  reportUri: config.opt.base_url + '/csp_reports'
  },
  reportOnly: false,
  setAllHeaders: false,
  disableAndroid: false,
  browserSniff: true
}));
app.use(helmet.referrerPolicy({
Example #25
0
export default function csp() {
  return helmet.contentSecurityPolicy({
    directives: {
      defaultSrc: trusted.concat([
        '*.optimizely.com',
        'https://*.cloudflare.com',
        '*.cloudflare.com'
      ]),
      scriptSrc: [
        "'unsafe-eval'",
        "'unsafe-inline'",
        '*.google-analytics.com',
        '*.gstatic.com',
        'https://*.cloudflare.com',
        '*.cloudflare.com',
        'https://*.gitter.im',
        'https://*.cdnjs.com',
        '*.cdnjs.com',
        'https://*.jsdelivr.com',
        '*.jsdelivr.com',
        '*.twimg.com',
        'https://*.twimg.com',
        '*.youtube.com',
        '*.ytimg.com'
      ].concat(trusted),
      styleSrc: [
        "'unsafe-inline'",
        '*.gstatic.com',
        '*.googleapis.com',
        '*.bootstrapcdn.com',
        'https://*.bootstrapcdn.com',
        '*.cloudflare.com',
        'https://*.cloudflare.com'
      ].concat(trusted),
      fontSrc: [
        '*.cloudflare.com',
        'https://*.cloudflare.com',
        '*.bootstrapcdn.com',
        '*.googleapis.com',
        '*.gstatic.com',
        'https://*.bootstrapcdn.com'
      ].concat(trusted),
      imgSrc: [
        // allow all input since we have user submitted images for
        // public profile
        '*',
        'data:'
      ],
      mediaSrc: [
        '*.bitly.com',
        '*.amazonaws.com',
        '*.twitter.com'
      ].concat(trusted),
      frameSrc: [
        '*.gitter.im',
        '*.gitter.im https:',
        '*.youtube.com',
        '*.twitter.com',
        '*.ghbtns.com',
        '*.freecatphotoapp.com',
        'freecodecamp.github.io'
      ].concat(trusted)
    },
    // set to true if you only want to report errors
    reportOnly: false,
    // set to true if you want to set all headers
    setAllHeaders: false,
    // set to true if you want to force buggy CSP in Safari 5
    safari5: false
  });
}
Example #26
0
function create(env, ctx) {
    var app = express();
    var appInfo = env.name + ' ' + env.version;
    app.set('title', appInfo);
    app.enable('trust proxy'); // Allows req.secure test on heroku https connections.
    var insecureUseHttp = env.insecureUseHttp;
    var secureHstsHeader = env.secureHstsHeader;
    console.info('Security settings: INSECURE_USE_HTTP=',insecureUseHttp,', SECURE_HSTS_HEADER=',secureHstsHeader);
    if (!insecureUseHttp) {
        app.use((req, res, next) => {
        if (req.header('x-forwarded-proto') !== 'https')
            res.redirect(`https://${req.header('host')}${req.url}`);
        else
            next()
        })
        if (secureHstsHeader) { // Add HSTS (HTTP Strict Transport Security) header
          const helmet = require('helmet');
          var includeSubDomainsValue = env.secureHstsHeaderIncludeSubdomains;
          var preloadValue = env.secureHstsHeaderPreload;
          app.use(helmet({
            hsts: {
              maxAge: 31536000,
              includeSubDomains: includeSubDomainsValue,
              preload: preloadValue
            }
          }))
          if (env.secureCsp) {
            app.use(helmet.contentSecurityPolicy({ //TODO make NS work without 'unsafe-inline'
              directives: {
                defaultSrc: ["'self'"],
                styleSrc: ["'self'", 'https://fonts.googleapis.com/',"'unsafe-inline'"],
                scriptSrc: ["'self'", "'unsafe-inline'"],
                fontSrc: [ "'self'", 'https://fonts.gstatic.com/']
              }
            }));
          }
        }
     }

    app.set('view engine', 'ejs');
    // this allows you to render .html files as templates in addition to .ejs
    app.engine('html', require('ejs').renderFile);
    app.engine('appcache', require('ejs').renderFile);
    app.set("views", path.join(__dirname, "views/"));

    app.locals.cachebuster = fs.readFileSync(process.cwd() + '/tmp/cacheBusterToken').toString().trim();

    if (ctx.bootErrors && ctx.bootErrors.length > 0) {
        app.get('*', require('./lib/server/booterror')(ctx));
        return app;
    }

    if (env.settings.isEnabled('cors')) {
        var allowOrigin = _get(env, 'extendedSettings.cors.allowOrigin') || '*';
        console.info('Enabled CORS, allow-origin:', allowOrigin);
        app.use(function allowCrossDomain(req, res, next) {
            res.header('Access-Control-Allow-Origin', allowOrigin);
            res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
            res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');

            // intercept OPTIONS method
            if ('OPTIONS' === req.method) {
                res.send(200);
            } else {
                next();
            }
        });
    }

    ///////////////////////////////////////////////////
    // api and json object variables
    ///////////////////////////////////////////////////
    var api = require('./lib/api/')(env, ctx);
    var ddata = require('./lib/data/endpoints')(env, ctx);

    app.use(compression({
        filter: function shouldCompress(req, res) {
            //TODO: return false here if we find a condition where we don't want to compress
            // fallback to standard filter function
            return compression.filter(req, res);
        }
    }));

    app.get("/", (req, res) => {
        res.render("index.html", {
            locals: app.locals
        });
    });

    var appPages = {
        "/clock-color.html":"clock-color.html",
        "/admin":"adminindex.html",
        "/profile":"profileindex.html",
        "/food":"foodindex.html",
        "/bgclock.html":"bgclock.html",
        "/weatherbg.html":"weatherbg.html",
        "/report":"reportindex.html",
        "/translations":"translationsindex.html",
        "/clock.html":"clock.html"
    };

	Object.keys(appPages).forEach(function(page) {
	        app.get(page, (req, res) => {
            res.render(appPages[page], {
                locals: app.locals
            });
        });
	});

    app.get("/appcache/*", (req, res) => {
        res.render("nightscout.appcache", {
            locals: app.locals
        });
    });

    app.use('/api/v1', bodyParser({
        limit: 1048576 * 50
    }), api);

    app.use('/api/v2/properties', ctx.properties);
    app.use('/api/v2/authorization', ctx.authorization.endpoints);
    app.use('/api/v2/ddata', ddata);

    // pebble data
    app.get('/pebble', ctx.pebble);

    // expose swagger.json
    app.get('/swagger.json', function(req, res) {
        res.sendFile(__dirname + '/swagger.json');
    });

/*
    if (env.settings.isEnabled('dumps')) {
        var heapdump = require('heapdump');
        app.get('/api/v2/dumps/start', function(req, res) {
            var path = new Date().toISOString() + '.heapsnapshot';
            path = path.replace(/:/g, '-');
            console.info('writing dump to', path);
            heapdump.writeSnapshot(path);
            res.send('wrote dump to ' + path);
        });
    }
*/

    //app.get('/package.json', software);

    // Allow static resources to be cached for week
    var maxAge = 7 * 24 * 60 * 60 * 1000;

    if (process.env.NODE_ENV === 'development') {
        maxAge = 10;
        console.log('Development environment detected, setting static file cache age to 10 seconds');

        app.get('/nightscout.appcache', function(req, res) {
            res.sendStatus(404);
        });
    }

    //TODO: JC - changed cache to 1 hour from 30d ays to bypass cache hell until we have a real solution
    var staticFiles = express.static(env.static_files, {
        maxAge: maxAge
    });

    // serve the static content
    app.use(staticFiles);

    const swaggerUiAssetPath = require("swagger-ui-dist").getAbsoluteFSPath();
    var swaggerFiles = express.static(swaggerUiAssetPath, {
        maxAge: maxAge
    });

    // serve the static content
    app.use('/swagger-ui-dist', swaggerFiles);

    var tmpFiles = express.static('tmp', {
        maxAge: maxAge
    });

    // serve the static content
    app.use(tmpFiles);

    if (process.env.NODE_ENV !== 'development') {

        console.log('Production environment detected, enabling Minify');

        var minify = require('express-minify');
        var myCssmin = require('cssmin');

        app.use(minify({
            js_match: /\.js/,
            css_match: /\.css/,
            sass_match: /scss/,
            less_match: /less/,
            stylus_match: /stylus/,
            coffee_match: /coffeescript/,
            json_match: /json/,
            cssmin: myCssmin,
            cache: __dirname + '/tmp',
            onerror: undefined,
        }));

    }

    // if this is dev environment, package scripts on the fly
    // if production, rely on postinstall script to run packaging for us

    if (process.env.NODE_ENV === 'development') {

        var webpack = require("webpack");
        var webpack_conf = require('./webpack.config');

        webpack(webpack_conf, function(err, stats) {

            var json = stats.toJson() // => webpack --json

            var options = {
                noColor: true
            };

            console.log(prettyjson.render(json.errors, options));
            console.log(prettyjson.render(json.assets, options));

        });
    }

    // Handle errors with express's errorhandler, to display more readable error messages.
    var errorhandler = require('errorhandler');
    //if (process.env.NODE_ENV === 'development') {
    app.use(errorhandler());
    //}
    return app;
}
Example #27
0
app.use(session({ // in case of 'deprecation error' - http://goo.gl/vgcFih
  name: 'aaroncordova.xyz', // Needed if multiple apps running on same host.
  resave: false, // Forces cookie to be resaved back to the session store even if no changes.
  saveUninitialized: true, // Forces a session that is "uninitialized" to be saved to the store.
  secret: process.env.secret, // The secret used to sign the session ID cookie.
  cookie: { maxAge: 3600000 }, // Default = `null` - closing browser removes cookie & session.
  store: store
}));

// app.disable('x-powered-by'); // Already handled by `helmet`.

// https://goo.gl/fPQ9DN
app.use(helmet.contentSecurityPolicy({
  directives: {
    // Whitelist domains for scripts & styles.
    defaultSrc: ["'self'", 'www.google-analytics.com'],
    styleSrc: ["'self'"]
  }
}));


///////////////////////
// CUSTOM MIDDLEWARE //
///////////////////////

function adminCheck(req, res, next) {
  if(req.session.admin) {
    next();
  } else {
    res.status(403).send('Dispatching the FBI surveillance van...');
  }
Example #28
0
  csp(directiveList) {
    directiveList = directiveList || {};
    Object.keys(defaultCSPDirectives).forEach(function(directive) {
      let domainsToAdd = directiveList[directive];
      let defaultDomains = defaultCSPDirectives[directive];

      if (domainsToAdd && defaultDomains.indexOf("*") !== -1) {
        directiveList[directive] = domainsToAdd;
      } else {
        directiveList[directive] = defaultDomains.concat(domainsToAdd || []);
      }
    });

    this.server.use(
      helmet.contentSecurityPolicy({
        directives: directiveList
      })
    );

    return this;
  },
  ssl() {
    this.server.use(helmet.hsts({ maxAge: ONE_YEAR }));
    this.server.enable("trust proxy");

    return this;
  },
  xss() {
    this.server.use(helmet.xssFilter());
    return this;
  },
Example #29
0
app.use(helmet.contentSecurityPolicy({
    defaultSrc: trusted,
    scriptSrc: ['*.optimizely.com'].concat(trusted),
    'connect-src': [
      'ws://*.rafflecopter.com',
      'wss://*.rafflecopter.com',
      'https://*.rafflecopter.com',
      'ws://www.freecodecamp.com',
      'ws://localhost:3001/',
      'http://localhost:3001',
      'http://www.freecodecamp.com'
    ],
    styleSrc: trusted,
    imgSrc: [
      '*.evernote.com',
      '*.amazonaws.com',
      'data:',
      '*.licdn.com',
      '*.gravatar.com',
      '*.youtube.com'
    ].concat(trusted),
    fontSrc: ['*.googleapis.com'].concat(trusted),
    mediaSrc: [
      '*.amazonaws.com',
      '*.twitter.com'
    ],
    frameSrc: [
      '*.gitter.im',
      '*.vimeo.com',
      '*.twitter.com',
      '*.rafflecopter.com'
    ],
    reportOnly: false, // set to true if you only want to report errors
    setAllHeaders: false, // set to true if you want to set all headers
    safari5: false // set to true if you want to force buggy CSP in Safari 5
}));
Example #30
0
function baseServer(routes, createStore, { appInstanceName = appName } = {}) {
  const app = new Express();
  app.disable('x-powered-by');

  app.use(logRequests);

  // Set HTTP Strict Transport Security headers
  app.use(helmet.hsts({
    force: true,
    includeSubDomains: false,
    maxAge: 31536000, // seconds
  }));

  // Sets X-Frame-Options
  app.use(helmet.frameguard(config.get('frameGuard')));

  // Sets x-content-type-options:"nosniff"
  app.use(helmet.noSniff());

  // Sets x-xss-protection:"1; mode=block"
  app.use(helmet.xssFilter());

  // CSP configuration.
  const csp = config.get('CSP');
  const noScriptStyles = getNoScriptStyles({ appName: appInstanceName });
  if (csp) {
    if (noScriptStyles) {
      const hash = crypto.createHash('sha256').update(noScriptStyles).digest('base64');
      const cspValue = `'sha256-${hash}'`;
      if (!csp.directives.styleSrc.includes(cspValue)) {
        csp.directives.styleSrc.push(cspValue);
      }
    }
    app.use(helmet.contentSecurityPolicy(csp));
  } else {
    log.warn('CSP has been disabled from the config');
  }

  if (config.get('enableNodeStatics')) {
    app.use(Express.static(path.join(config.get('basePath'), 'dist')));
  }

  // Return version information as json
  app.get('/__version__', (req, res) => {
    fs.stat(version, (err) => {
      if (err) {
        res.sendStatus(415);
      } else {
        res.setHeader('Content-Type', 'application/json');
        fs.createReadStream(version).pipe(res);
      }
    });
  });

  // Return 200 for csp reports - this will need to be overridden when deployed.
  app.post('/__cspreport__', (req, res) => res.status(200).end('ok'));

  // Redirect from / for the search app it's a 302 to prevent caching.
  if (appInstanceName === 'search') {
    app.get('/', (req, res) => res.redirect(302, '/search'));
  }

  if (appInstanceName === 'disco' && isDevelopment) {
    app.get('/', (req, res) =>
      res.redirect(302, '/en-US/firefox/discovery/pane/48.0/Darwin/normal'));
  }

  // Handle application and lang redirections.
  if (config.get('enablePrefixMiddleware')) {
    app.use(prefixMiddleWare);
  }

  app.use((req, res) => {
    if (isDevelopment) {
      log.info(oneLine`Clearing require cache for webpack isomorphic tools.
        [Development Mode]`);

      // clear require() cache if in development mode
      webpackIsomorphicTools.refresh();
    }

    match({ location: req.url, routes }, (
      err, redirectLocation, renderProps
    ) => {
      cookie.plugToRequest(req, res);

      if (err) {
        log.error({ err, req });
        return showErrorPage(res, 500);
      }

      if (!renderProps) {
        return showErrorPage(res, 404);
      }

      const store = createStore();
      const token = cookie.load(config.get('cookieName'));
      if (token) {
        store.dispatch(setJwt(token));
      }
      // Get SRI for deployed services only.
      const sriData = (isDeployed) ? JSON.parse(
        fs.readFileSync(path.join(config.get('basePath'), 'dist/sri.json'))
      ) : {};

      // Check the lang supplied by res.locals.lang for validity
      // or fall-back to the default.
      const lang = isValidLang(res.locals.lang) ?
        res.locals.lang : config.get('defaultLang');
      const dir = getDirection(lang);
      const locale = langToLocale(lang);
      store.dispatch(setLang(lang));
      if (res.locals.clientApp) {
        store.dispatch(setClientApp(res.locals.clientApp));
      } else {
        log.warn(`No clientApp for this URL: ${req.url}`);
      }

      function hydrateOnClient(props = {}) {
        const pageProps = {
          appName: appInstanceName,
          assets: webpackIsomorphicTools.assets(),
          htmlLang: lang,
          htmlDir: dir,
          includeSri: isDeployed,
          noScriptStyles,
          sriData,
          store,
          trackingEnabled: convertBoolean(config.get('trackingEnabled')),
          ...props,
        };

        const HTML = ReactDOM.renderToString(
          <ServerHtml {...pageProps} />);
        res.send(`<!DOCTYPE html>\n${HTML}`);
      }

      // Set disableSSR to true to debug
      // client-side-only render.
      if (config.get('disableSSR') === true) {
        return Promise.resolve(hydrateOnClient());
      }

      return loadOnServer({ ...renderProps, store })
        .then(() => {
          // eslint-disable-next-line global-require
          let i18nData = {};
          try {
            if (locale !== langToLocale(config.get('defaultLang'))) {
              // eslint-disable-next-line global-require, import/no-dynamic-require
              i18nData = require(
                `../../locale/${locale}/${appInstanceName}.js`);
            }
          } catch (e) {
            log.info(
              `Locale JSON not found or required for locale: "${locale}"`);
            log.info(
              `Falling back to default lang: "${config.get('defaultLang')}".`);
          }
          const i18n = makeI18n(i18nData, lang);

          const InitialComponent = (
            <I18nProvider i18n={i18n}>
              <Provider store={store} key="provider">
                <ReduxAsyncConnect {...renderProps} />
              </Provider>
            </I18nProvider>
          );

          const asyncConnectLoadState = store.getState().reduxAsyncConnect.loadState || {};
          const reduxResult = getReduxConnectError(asyncConnectLoadState);
          if (reduxResult.status) {
            return showErrorPage(res, reduxResult.status);
          }

          return hydrateOnClient({ component: InitialComponent });
        })
        .catch((error) => {
          log.error({ err: error });
          return showErrorPage(res, 500);
        });
    });
  });

  // eslint-disable-next-line no-unused-vars
  app.use((err, req, res, next) => {
    log.error({ err });
    return showErrorPage(res, 500);
  });

  return app;
}