diff --git a/src/appconfig.ejs b/src/appconfig.ejs index 33e37dbeb..f1eabb6fc 100644 --- a/src/appconfig.ejs +++ b/src/appconfig.ejs @@ -72,10 +72,6 @@ server { ssl_dhparam /home/yellowtent/boxdata/dhparams.pem; add_header Strict-Transport-Security "max-age=15768000"; - # https://developer.mozilla.org/en-US/docs/Web/HTTP/X-Frame-Options - add_header X-Frame-Options "<%= xFrameOptions %>"; - proxy_hide_header X-Frame-Options; - # https://github.com/twitter/secureheaders # https://www.owasp.org/index.php/OWASP_Secure_Headers_Project#tab=Compatibility_Matrix # https://wiki.mozilla.org/Security/Guidelines/Web_Security diff --git a/src/appdb.js b/src/appdb.js index 812ec6b95..32e8f136b 100644 --- a/src/appdb.js +++ b/src/appdb.js @@ -69,7 +69,7 @@ var APPS_FIELDS_PREFIXED = [ 'apps.id', 'apps.appStoreId', 'apps.installationSta 'apps.health', 'apps.containerId', 'apps.manifestJson', 'apps.httpPort', 'subdomains.subdomain AS location', 'subdomains.domain', 'apps.accessRestrictionJson', 'apps.restoreConfigJson', 'apps.oldConfigJson', 'apps.updateConfigJson', 'apps.memoryLimit', 'apps.label', 'apps.tagsJson', - 'apps.xFrameOptions', 'apps.sso', 'apps.debugModeJson', 'apps.robotsTxt', 'apps.enableBackup', + 'apps.sso', 'apps.debugModeJson', 'apps.robotsTxt', 'apps.enableBackup', 'apps.creationTime', 'apps.updateTime', 'apps.ownerId', 'apps.mailboxName', 'apps.enableAutomaticUpdate', 'apps.dataDir', 'apps.ts', 'apps.healthTime' ].join(','); @@ -121,9 +121,6 @@ function postProcess(result) { if (result.accessRestriction && !result.accessRestriction.users) result.accessRestriction.users = []; delete result.accessRestrictionJson; - // TODO remove later once all apps have this attribute - result.xFrameOptions = result.xFrameOptions || 'SAMEORIGIN'; - result.sso = !!result.sso; // make it bool result.enableBackup = !!result.enableBackup; // make it bool result.enableAutomaticUpdate = !!result.enableAutomaticUpdate; // make it bool @@ -279,7 +276,6 @@ function add(id, appStoreId, manifest, location, domain, ownerId, portBindings, const accessRestriction = data.accessRestriction || null; const accessRestrictionJson = JSON.stringify(accessRestriction); const memoryLimit = data.memoryLimit || 0; - const xFrameOptions = data.xFrameOptions || ''; const installationState = data.installationState || exports.ISTATE_PENDING_INSTALL; const restoreConfigJson = data.restoreConfig ? JSON.stringify(data.restoreConfig) : null; // used when cloning const sso = 'sso' in data ? data.sso : null; @@ -293,10 +289,10 @@ function add(id, appStoreId, manifest, location, domain, ownerId, portBindings, var queries = []; queries.push({ - query: 'INSERT INTO apps (id, appStoreId, manifestJson, installationState, accessRestrictionJson, memoryLimit, xFrameOptions,' + query: 'INSERT INTO apps (id, appStoreId, manifestJson, installationState, accessRestrictionJson, memoryLimit, ' + 'restoreConfigJson, sso, debugModeJson, robotsTxt, ownerId, mailboxName, label, tagsJson) ' - + ' VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', - args: [ id, appStoreId, manifestJson, installationState, accessRestrictionJson, memoryLimit, xFrameOptions, restoreConfigJson, + + ' VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', + args: [ id, appStoreId, manifestJson, installationState, accessRestrictionJson, memoryLimit, restoreConfigJson, sso, debugModeJson, robotsTxt, ownerId, mailboxName, label, tagsJson ] }); diff --git a/src/apps.js b/src/apps.js index eb68b0498..f72ec7738 100644 --- a/src/apps.js +++ b/src/apps.js @@ -90,7 +90,6 @@ var appdb = require('./appdb.js'), taskmanager = require('./taskmanager.js'), TransformStream = require('stream').Transform, updateChecker = require('./updatechecker.js'), - url = require('url'), util = require('util'), uuid = require('uuid'), validator = require('validator'), @@ -241,20 +240,6 @@ function validateMemoryLimit(manifest, memoryLimit) { return null; } -// https://tools.ietf.org/html/rfc7034 -function validateXFrameOptions(xFrameOptions) { - assert.strictEqual(typeof xFrameOptions, 'string'); - - if (xFrameOptions === 'DENY') return null; - if (xFrameOptions === 'SAMEORIGIN') return null; - - var parts = xFrameOptions.split(' '); - if (parts.length !== 2 || parts[0] !== 'ALLOW-FROM') return new AppsError(AppsError.BAD_FIELD, 'xFrameOptions must be "DENY", "SAMEORIGIN" or "ALLOW-FROM uri"' ); - - var uri = url.parse(parts[1]); - return (uri.protocol === 'http:' || uri.protocol === 'https:') ? null : new AppsError(AppsError.BAD_FIELD, 'xFrameOptions ALLOW-FROM uri must be a valid http[s] uri' ); -} - function validateDebugMode(debugMode) { assert.strictEqual(typeof debugMode, 'object'); @@ -372,7 +357,7 @@ function getAppConfig(app) { accessRestriction: app.accessRestriction, portBindings: app.portBindings, memoryLimit: app.memoryLimit, - xFrameOptions: app.xFrameOptions || 'SAMEORIGIN', + robotsTxt: app.robotsTxt, sso: app.sso, alternateDomains: app.alternateDomains || [], @@ -389,7 +374,7 @@ function removeInternalFields(app) { return _.pick(app, 'id', 'appStoreId', 'installationState', 'installationProgress', 'runState', 'health', 'location', 'domain', 'fqdn', 'mailboxName', - 'accessRestriction', 'manifest', 'portBindings', 'iconUrl', 'memoryLimit', 'xFrameOptions', + 'accessRestriction', 'manifest', 'portBindings', 'iconUrl', 'memoryLimit', 'sso', 'debugMode', 'robotsTxt', 'enableBackup', 'creationTime', 'updateTime', 'ts', 'tags', 'label', 'alternateDomains', 'ownerId', 'env', 'enableAutomaticUpdate', 'dataDir'); } @@ -585,7 +570,6 @@ function install(data, user, auditSource, callback) { cert = data.cert || null, key = data.key || null, memoryLimit = data.memoryLimit || 0, - xFrameOptions = data.xFrameOptions || 'SAMEORIGIN', sso = 'sso' in data ? data.sso : null, debugMode = data.debugMode || null, robotsTxt = data.robotsTxt || null, @@ -620,9 +604,6 @@ function install(data, user, auditSource, callback) { error = validateMemoryLimit(manifest, memoryLimit); if (error) return callback(error); - error = validateXFrameOptions(xFrameOptions); - if (error) return callback(error); - error = validateDebugMode(debugMode); if (error) return callback(error); @@ -679,7 +660,6 @@ function install(data, user, auditSource, callback) { var data = { accessRestriction: accessRestriction, memoryLimit: memoryLimit, - xFrameOptions: xFrameOptions, sso: sso, debugMode: debugMode, mailboxName: mailboxName, @@ -761,12 +741,6 @@ function configure(appId, data, user, auditSource, callback) { if (error) return callback(error); } - if ('xFrameOptions' in data) { - values.xFrameOptions = data.xFrameOptions; - error = validateXFrameOptions(values.xFrameOptions); - if (error) return callback(error); - } - if ('debugMode' in data) { values.debugMode = data.debugMode; error = validateDebugMode(values.debugMode); @@ -1138,7 +1112,6 @@ function clone(appId, data, user, auditSource, callback) { installationState: appdb.ISTATE_PENDING_CLONE, memoryLimit: app.memoryLimit, accessRestriction: app.accessRestriction, - xFrameOptions: app.xFrameOptions, restoreConfig: { backupId: backupId, backupFormat: backupInfo.format }, sso: !!app.sso, mailboxName: mailboxName, diff --git a/src/reverseproxy.js b/src/reverseproxy.js index 677637909..ad58b0980 100644 --- a/src/reverseproxy.js +++ b/src/reverseproxy.js @@ -392,7 +392,6 @@ function writeAdminNginxConfig(bundle, configFileName, vhost, callback) { endpoint: 'admin', certFilePath: bundle.certFilePath, keyFilePath: bundle.keyFilePath, - xFrameOptions: 'SAMEORIGIN', robotsTxtQuoted: JSON.stringify('User-agent: *\nDisallow: /\n') }; var nginxConf = ejs.render(NGINX_APPCONFIG_EJS, data); @@ -457,8 +456,7 @@ function writeAppNginxConfig(app, bundle, callback) { endpoint: endpoint, certFilePath: bundle.certFilePath, keyFilePath: bundle.keyFilePath, - robotsTxtQuoted: app.robotsTxt ? JSON.stringify(app.robotsTxt) : null, - xFrameOptions: app.xFrameOptions || 'SAMEORIGIN' // once all apps have been updated/ + robotsTxtQuoted: app.robotsTxt ? JSON.stringify(app.robotsTxt) : null }; var nginxConf = ejs.render(NGINX_APPCONFIG_EJS, data); @@ -487,8 +485,7 @@ function writeAppRedirectNginxConfig(app, fqdn, bundle, callback) { endpoint: 'redirect', certFilePath: bundle.certFilePath, keyFilePath: bundle.keyFilePath, - robotsTxtQuoted: null, - xFrameOptions: 'SAMEORIGIN' + robotsTxtQuoted: null }; var nginxConf = ejs.render(NGINX_APPCONFIG_EJS, data); diff --git a/src/routes/apps.js b/src/routes/apps.js index bf6441753..1edf75bd3 100644 --- a/src/routes/apps.js +++ b/src/routes/apps.js @@ -107,8 +107,6 @@ function installApp(req, res, next) { if ('memoryLimit' in data && typeof data.memoryLimit !== 'number') return next(new HttpError(400, 'memoryLimit is not a number')); - if (data.xFrameOptions && typeof data.xFrameOptions !== 'string') return next(new HttpError(400, 'xFrameOptions must be a string')); - if ('sso' in data && typeof data.sso !== 'boolean') return next(new HttpError(400, 'sso must be a boolean')); if ('enableBackup' in data && typeof data.enableBackup !== 'boolean') return next(new HttpError(400, 'enableBackup must be a boolean')); if ('enableAutomaticUpdate' in data && typeof data.enableAutomaticUpdate !== 'boolean') return next(new HttpError(400, 'enableAutomaticUpdate must be a boolean')); @@ -166,7 +164,6 @@ function configureApp(req, res, next) { if (!data.cert && data.key) return next(new HttpError(400, 'cert must be provided')); if ('memoryLimit' in data && typeof data.memoryLimit !== 'number') return next(new HttpError(400, 'memoryLimit is not a number')); - if (data.xFrameOptions && typeof data.xFrameOptions !== 'string') return next(new HttpError(400, 'xFrameOptions must be a string')); if ('enableBackup' in data && typeof data.enableBackup !== 'boolean') return next(new HttpError(400, 'enableBackup must be a boolean')); if ('enableAutomaticUpdate' in data && typeof data.enableAutomaticUpdate !== 'boolean') return next(new HttpError(400, 'enableAutomaticUpdate must be a boolean')); diff --git a/src/test/database-test.js b/src/test/database-test.js index 37587ef50..b92f9e4a1 100644 --- a/src/test/database-test.js +++ b/src/test/database-test.js @@ -412,7 +412,6 @@ describe('database', function () { oldConfig: null, newConfig: null, memoryLimit: 4294967296, - xFrameOptions: 'DENY', sso: true, debugMode: null, robotsTxt: null, @@ -993,7 +992,6 @@ describe('database', function () { oldConfig: null, updateConfig: null, memoryLimit: 4294967296, - xFrameOptions: 'DENY', sso: true, debugMode: null, robotsTxt: null, @@ -1028,7 +1026,6 @@ describe('database', function () { oldConfig: null, updateConfig: null, memoryLimit: 0, - xFrameOptions: 'SAMEORIGIN', sso: true, debugMode: null, robotsTxt: null,