mirror of https://github.com/xwiki-labs/cryptpad
guard against possible typeErrors from unvalidated config input
This commit is contained in:
parent
c392d52fe2
commit
b5d3a10dc2
|
@ -176,13 +176,12 @@ var restoreArchivedDocument = function (Env, Server, cb) {
|
|||
};
|
||||
|
||||
// CryptPad_AsyncStore.rpc.send('ADMIN', [ 'ADMIN_DECREE', ['RESTRICT_REGISTRATION', [true]]], console.log)
|
||||
var adminDecree = function (Env, Server, cb, data, safeKey) {
|
||||
var adminDecree = function (Env, Server, cb, data, unsafeKey) {
|
||||
var value = data[1];
|
||||
if (!Array.isArray(value)) { return void cb('INVALID_DECREE'); }
|
||||
|
||||
var command = value[0];
|
||||
var args = value[1];
|
||||
var unsafeKey = Util.unescapeKeyCharacters(safeKey);
|
||||
|
||||
/*
|
||||
|
||||
|
@ -253,15 +252,16 @@ Admin.command = function (Env, safeKey, data, _cb, Server) {
|
|||
var cb = Util.once(Util.mkAsync(_cb));
|
||||
|
||||
var admins = Env.admins;
|
||||
//var unsafeKey = Util.unescapeKeyCharacters(safeKey);
|
||||
if (admins.indexOf(safeKey) === -1) {
|
||||
|
||||
var unsafeKey = Util.unescapeKeyCharacters(safeKey);
|
||||
if (admins.indexOf(unsafeKey) === -1) {
|
||||
return void cb("FORBIDDEN");
|
||||
}
|
||||
|
||||
var command = commands[data[0]];
|
||||
|
||||
if (typeof(command) === 'function') {
|
||||
return void command(Env, Server, cb, data, safeKey);
|
||||
return void command(Env, Server, cb, data, unsafeKey);
|
||||
}
|
||||
|
||||
return void cb('UNHANDLED_ADMIN_COMMAND');
|
||||
|
|
|
@ -85,6 +85,8 @@ module.exports.create = function (config, cb) {
|
|||
|
||||
(function () {
|
||||
var custom = config.customLimits;
|
||||
if (!custom) { return; }
|
||||
|
||||
var stored = Env.customLimits;
|
||||
|
||||
Object.keys(custom).forEach(function (k) {
|
||||
|
@ -147,11 +149,15 @@ module.exports.create = function (config, cb) {
|
|||
Core.DEFAULT_LIMIT;
|
||||
|
||||
try {
|
||||
// XXX this should be the same as is exposed in server.js
|
||||
// /api/config.adminKeys
|
||||
Env.admins = (config.adminKeys || []).map(function (k) {
|
||||
k = k.replace(/\/+$/, '');
|
||||
var s = k.split('/');
|
||||
return s[s.length-1];
|
||||
});
|
||||
try {
|
||||
return Keys.canonicalize(k);
|
||||
} catch (err) {
|
||||
return;
|
||||
}
|
||||
}).filter(Boolean);
|
||||
} catch (e) {
|
||||
console.error("Can't parse admin keys. Please update or fix your config.js file!");
|
||||
}
|
||||
|
|
17
server.js
17
server.js
|
@ -90,8 +90,6 @@ config.flushCache = function () {
|
|||
config.log.info("UPDATING_FRESH_KEY", FRESH_KEY);
|
||||
};
|
||||
|
||||
const clone = (x) => (JSON.parse(JSON.stringify(x)));
|
||||
|
||||
var setHeaders = (function () {
|
||||
// load the default http headers unless the admin has provided their own via the config file
|
||||
var headers;
|
||||
|
@ -99,7 +97,7 @@ var setHeaders = (function () {
|
|||
var custom = config.httpHeaders;
|
||||
// if the admin provided valid http headers then use them
|
||||
if (custom && typeof(custom) === 'object' && !Array.isArray(custom)) {
|
||||
headers = clone(custom);
|
||||
headers = Util.clone(custom);
|
||||
} else {
|
||||
// otherwise use the default
|
||||
headers = Default.httpHeaders();
|
||||
|
@ -120,7 +118,7 @@ var setHeaders = (function () {
|
|||
headers['Content-Security-Policy'] = Default.contentSecurity(config.httpUnsafeOrigin);
|
||||
}
|
||||
|
||||
const padHeaders = clone(headers);
|
||||
const padHeaders = Util.clone(headers);
|
||||
if (typeof(config.padContentSecurity) === 'string') {
|
||||
padHeaders['Content-Security-Policy'] = config.padContentSecurity;
|
||||
} else {
|
||||
|
@ -202,6 +200,7 @@ app.use(/^\/[^\/]*$/, Express.static('customize.dist'));
|
|||
var admins = [];
|
||||
try {
|
||||
admins = (config.adminKeys || []).map(function (k) {
|
||||
// XXX is there any reason not to use Keys.canonicalize ?
|
||||
// return each admin's "unsafeKey"
|
||||
// this might throw and invalidate all the other admin's keys
|
||||
// but we want to get the admin's attention anyway.
|
||||
|
@ -228,12 +227,12 @@ var serveConfig = (function () {
|
|||
allowSubscriptions: (config.allowSubscriptions === true),
|
||||
websocketPath: config.externalWebsocketURL,
|
||||
httpUnsafeOrigin: config.httpUnsafeOrigin,
|
||||
adminEmail: config.adminEmail,
|
||||
adminEmail: config.adminEmail, // XXX mutable
|
||||
adminKeys: admins,
|
||||
inactiveTime: config.inactiveTime,
|
||||
inactiveTime: config.inactiveTime, // XXX mutable
|
||||
supportMailbox: config.supportMailboxPublicKey,
|
||||
maxUploadSize: config.maxUploadSize,
|
||||
premiumUploadSize: config.premiumUploadSize,
|
||||
maxUploadSize: config.maxUploadSize, // XXX mutable
|
||||
premiumUploadSize: config.premiumUploadSize, // XXX mutable
|
||||
}, null, '\t'),
|
||||
'obj.httpSafeOrigin = ' + (function () {
|
||||
if (config.httpSafeOrigin) { return '"' + config.httpSafeOrigin + '"'; }
|
||||
|
@ -259,6 +258,8 @@ var serveConfig = (function () {
|
|||
}
|
||||
// generate a lookup key for the cache
|
||||
var cacheKey = host + ':' + cacheString();
|
||||
|
||||
// XXX we must be able to clear the cache when updating any mutable key
|
||||
// if there's nothing cached for that key...
|
||||
if (!configCache[cacheKey]) {
|
||||
// generate the response and cache it in memory
|
||||
|
|
Loading…
Reference in New Issue