httpheaders now adds to existing headers, set a header to null to force remove it.

This commit is contained in:
Ylian Saint-Hilaire 2022-03-01 11:18:42 -08:00
parent cbf831a92b
commit 8b33208b17
4 changed files with 38 additions and 26 deletions

View File

@ -679,7 +679,7 @@ function CreateMeshCentralServer(config, args) {
obj.args = args = config2.settings; obj.args = args = config2.settings;
// Lower case all keys in the config file // Lower case all keys in the config file
obj.common.objKeysToLower(config2, ['ldapoptions', 'defaultuserwebstate', 'forceduserwebstate']); obj.common.objKeysToLower(config2, ['ldapoptions', 'defaultuserwebstate', 'forceduserwebstate', 'httpheaders']);
// Grad some of the values from the original config.json file if present. // Grad some of the values from the original config.json file if present.
if ((config.settings.vault != null) && (config2.settings != null)) { config2.settings.vault = config.settings.vault; } if ((config.settings.vault != null) && (config2.settings != null)) { config2.settings.vault = config.settings.vault; }
@ -1168,7 +1168,7 @@ function CreateMeshCentralServer(config, args) {
for (i in args) { config2.settings[i] = args[i]; } for (i in args) { config2.settings[i] = args[i]; }
// Lower case all keys in the config file // Lower case all keys in the config file
common.objKeysToLower(config2, ['ldapoptions', 'defaultuserwebstate', 'forceduserwebstate']); common.objKeysToLower(config2, ['ldapoptions', 'defaultuserwebstate', 'forceduserwebstate', 'httpheaders']);
// Grad some of the values from the original config.json file if present. // Grad some of the values from the original config.json file if present.
config2['mysql'] = config['mysql']; config2['mysql'] = config['mysql'];
@ -3279,7 +3279,7 @@ function getConfig(createSampleConfig) {
// Lower case all keys in the config file // Lower case all keys in the config file
try { try {
require('./common.js').objKeysToLower(config, ['ldapoptions', 'defaultuserwebstate', 'forceduserwebstate']); require('./common.js').objKeysToLower(config, ['ldapoptions', 'defaultuserwebstate', 'forceduserwebstate', 'httpheaders']);
} catch (ex) { } catch (ex) {
console.log('CRITICAL ERROR: Unable to access the file \"./common.js\".\r\nCheck folder & file permissions.'); console.log('CRITICAL ERROR: Unable to access the file \"./common.js\".\r\nCheck folder & file permissions.');
process.exit(); process.exit();

View File

@ -36,6 +36,8 @@
"sample-config-advanced.json" "sample-config-advanced.json"
], ],
"dependencies": { "dependencies": {
"@yetzt/nedb": "^1.8.0",
"archiver": "^4.0.2",
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
"cbor": "~5.2.0", "cbor": "~5.2.0",
"compression": "^1.7.4", "compression": "^1.7.4",
@ -43,13 +45,25 @@
"express": "^4.17.0", "express": "^4.17.0",
"express-handlebars": "^5.3.5", "express-handlebars": "^5.3.5",
"express-ws": "^4.0.0", "express-ws": "^4.0.0",
"html-minifier": "^4.0.0",
"image-size": "^1.0.1",
"ipcheck": "^0.1.0", "ipcheck": "^0.1.0",
"jsdom": "^19.0.0",
"loadavg-windows": "^1.1.1",
"minify-js": "^0.0.4",
"minimist": "^1.2.5", "minimist": "^1.2.5",
"multiparty": "^4.2.1", "multiparty": "^4.2.1",
"@yetzt/nedb": "^1.8.0",
"node-forge": "^1.0.0", "node-forge": "^1.0.0",
"node-rdpjs-2": "^0.3.5",
"node-windows": "^0.1.4",
"otplib": "^10.2.3",
"pg": "^8.7.1",
"pgtools": "^0.3.2",
"ssh2": "^1.6.0",
"web-push": "^3.4.5",
"ws": "^5.2.3", "ws": "^5.2.3",
"yauzl": "^2.10.0" "yauzl": "^2.10.0",
"yubikeyotp": "^0.2.0"
}, },
"engines": { "engines": {
"node": ">=10.0.0" "node": ">=10.0.0"

File diff suppressed because one or more lines are too long

View File

@ -5739,28 +5739,26 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
// Skip the rest is this is an agent connection // Skip the rest is this is an agent connection
if ((req.url.indexOf('/meshrelay.ashx/.websocket') >= 0) || (req.url.indexOf('/agent.ashx/.websocket') >= 0) || (req.url.indexOf('/localrelay.ashx/.websocket') >= 0)) { next(); return; } if ((req.url.indexOf('/meshrelay.ashx/.websocket') >= 0) || (req.url.indexOf('/agent.ashx/.websocket') >= 0) || (req.url.indexOf('/localrelay.ashx/.websocket') >= 0)) { next(); return; }
// If this domain has configured headers, use them. // Setup security headers
// Example headers: { 'Strict-Transport-Security': 'max-age=360000;includeSubDomains' }; const geourl = (domain.geolocation ? ' *.openstreetmap.org' : '');
// { 'Referrer-Policy': 'no-referrer', 'x-frame-options': 'SAMEORIGIN', 'X-XSS-Protection': '1; mode=block', 'X-Content-Type-Options': 'nosniff', 'Content-Security-Policy': "default-src http: ws: data: 'self';script-src http: 'unsafe-inline';style-src http: 'unsafe-inline'" }; var selfurl = ' wss://' + req.headers.host;
if ((xforwardedhost != null) && (xforwardedhost != req.headers.host)) { selfurl += ' wss://' + xforwardedhost; }
const extraScriptSrc = (parent.config.settings.extrascriptsrc != null) ? (' ' + parent.config.settings.extrascriptsrc) : '';
const headers = {
'Referrer-Policy': 'no-referrer',
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'Permissions-Policy': 'interest-cohort=()', // Remove Google's FLoC Network
'Content-Security-Policy': "default-src 'none'; font-src 'self'; script-src 'self' 'unsafe-inline'" + extraScriptSrc + "; connect-src 'self'" + geourl + selfurl + "; img-src 'self' blob: data:" + geourl + " data:; style-src 'self' 'unsafe-inline'; frame-src 'self' mcrouter:; media-src 'self'; form-action 'self'"
};
if ((parent.config.settings.allowframing !== true) && (typeof parent.config.settings.allowframing !== 'string')) { headers['X-Frame-Options'] = 'sameorigin'; }
if ((parent.config.settings.stricttransportsecurity === true) || ((parent.config.settings.stricttransportsecurity !== false) && (obj.isTrustedCert(domain)))) { if (typeof parent.config.settings.stricttransportsecurity == 'string') { headers['Strict-Transport-Security'] = parent.config.settings.stricttransportsecurity; } else { headers['Strict-Transport-Security'] = 'max-age=63072000'; } }
// If this domain has configured headers, add them. If a header is set to null, remove it.
if ((domain != null) && (domain.httpheaders != null) && (typeof domain.httpheaders == 'object')) { if ((domain != null) && (domain.httpheaders != null) && (typeof domain.httpheaders == 'object')) {
res.set(domain.httpheaders); for (var i in domain.httpheaders) { if (domain.httpheaders === null) { delete headers[i]; } else { headers[i] = domain.httpheaders[i]; } }
} else {
// Use default security headers
const geourl = (domain.geolocation ? ' *.openstreetmap.org' : '');
var selfurl = ' wss://' + req.headers.host;
if ((xforwardedhost != null) && (xforwardedhost != req.headers.host)) { selfurl += ' wss://' + xforwardedhost; }
const extraScriptSrc = (parent.config.settings.extrascriptsrc != null) ? (' ' + parent.config.settings.extrascriptsrc) : '';
const headers = {
'Referrer-Policy': 'no-referrer',
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'Permissions-Policy': 'interest-cohort=()', // Remove Google's FLoC Network
'Content-Security-Policy': "default-src 'none'; font-src 'self'; script-src 'self' 'unsafe-inline'" + extraScriptSrc + "; connect-src 'self'" + geourl + selfurl + "; img-src 'self' blob: data:" + geourl + " data:; style-src 'self' 'unsafe-inline'; frame-src 'self' mcrouter:; media-src 'self'; form-action 'self'"
};
if ((parent.config.settings.allowframing !== true) && (typeof parent.config.settings.allowframing !== 'string')) { headers['X-Frame-Options'] = 'sameorigin'; }
if ((parent.config.settings.stricttransportsecurity === true) || ((parent.config.settings.stricttransportsecurity !== false) && (obj.isTrustedCert(domain)))) { if (typeof parent.config.settings.stricttransportsecurity == 'string') { headers['Strict-Transport-Security'] = parent.config.settings.stricttransportsecurity; } else { headers['Strict-Transport-Security'] = 'max-age=63072000'; } }
res.set(headers);
} }
res.set(headers);
// Check the session if bound to the external IP address // Check the session if bound to the external IP address
if ((parent.config.settings.cookieipcheck !== false) && (req.session.ip != null) && (req.clientIp != null) && (req.session.ip != req.clientIp)) { req.session = {}; } if ((parent.config.settings.cookieipcheck !== false) && (req.session.ip != null) && (req.clientIp != null) && (req.session.ip != req.clientIp)) { req.session = {}; }