Merge remote-tracking branch 'remotes/origin/hotfix/v6.2.2' into develop

# Conflicts:
#	Common/config/development-mac.json
#	Common/config/development-windows.json
#	Common/sources/commondefines.js
#	Common/sources/utils.js
This commit is contained in:
Sergey Konovalov
2021-05-11 14:53:54 +03:00
8 changed files with 72 additions and 3 deletions

View File

@ -191,6 +191,10 @@
"useforrequest": false,
"errorcode": 403
},
"request-filtering-agent" : {
"allowPrivateIPAddress": true,
"allowMetaIPAddress": true
},
"secret": {
"browser": {"string": "secret", "file": "", "tenants": {}},
"inbox": {"string": "secret", "file": "", "tenants": {}},

View File

@ -35,6 +35,10 @@
"utils": {
"utils_common_fontdir": "/usr/share/fonts"
},
"request-filtering-agent" : {
"allowPrivateIPAddress": true,
"allowMetaIPAddress": true
},
"sockjs": {
"sockjs_url": "/web-apps/vendor/sockjs/sockjs.min.js"
}

View File

@ -41,6 +41,10 @@
"dbUser": "root",
"dbPass": "onlyoffice"
},
"request-filtering-agent" : {
"allowPrivateIPAddress": true,
"allowMetaIPAddress": true
},
"sockjs": {
"sockjs_url": "/office/vendor/sockjs/sockjs.min.js"
}

View File

@ -41,6 +41,10 @@
"dbUser": "root",
"dbPass": "onlyoffice"
},
"request-filtering-agent" : {
"allowPrivateIPAddress": true,
"allowMetaIPAddress": true
},
"sockjs": {
"sockjs_url": "/web-apps/vendor/sockjs/sockjs.min.js"
}

View File

@ -707,6 +707,21 @@
}
}
},
"request-filtering-agent": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/request-filtering-agent/-/request-filtering-agent-1.0.5.tgz",
"integrity": "sha512-zkO5wg1VhoPqz5FIIXLY+iEveiX+p6A/i++SS4ZXd0UDms6VtHLLYLw9hQnIbMsKbYwHgzhNeIis7jMncoG9ag==",
"requires": {
"ipaddr.js": "^1.9.1"
},
"dependencies": {
"ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
}
}
},
"rfdc": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.2.tgz",

View File

@ -23,6 +23,7 @@
"node-statsd": "^0.1.1",
"openpgp": "^4.10.8",
"request": "^2.88.0",
"request-filtering-agent": "^1.0.5",
"rhea": "^0.3.9",
"uri-js": "^4.2.2",
"win-ca": "^3.4.5"

View File

@ -37,6 +37,7 @@ const constants = require('./constants');
function InputCommand(data, copyExplicit) {
//must be set explicitly to prevent vulnerability(downloadAs(with url) creates request to integrator with authorization)
this['withAuthorization'] = undefined;//bool
this['isbuilder'] = undefined;//bool
this['externalChangeInfo'] = undefined;//zero DB changes case: set password, undo all changes
this['wopiParams'] = undefined;
if (data) {
@ -97,11 +98,11 @@ function InputCommand(data, copyExplicit) {
this['rediskey'] = data['rediskey'];
this['nobase64'] = data['nobase64'];
this['forgotten'] = data['forgotten'];
this['isbuilder'] = data['isbuilder'];
this['status_info_in'] = data['status_info_in'];
this['attempt'] = data['attempt'];
if (copyExplicit) {
this['withAuthorization'] = data['withAuthorization'];
this['isbuilder'] = data['isbuilder'];
this['externalChangeInfo'] = data['externalChangeInfo'];
this['wopiParams'] = data['wopiParams'];
}
@ -155,7 +156,6 @@ function InputCommand(data, copyExplicit) {
this['rediskey'] = undefined;
this['nobase64'] = true;
this['forgotten'] = undefined;
this['isbuilder'] = undefined;
this['status_info_in'] = undefined;
this['attempt'] = undefined;
}

View File

@ -57,6 +57,7 @@ const constants = require('./constants');
const logger = require('./logger');
const forwarded = require('forwarded');
const mime = require('mime');
const { RequestFilteringHttpAgent, RequestFilteringHttpsAgent } = require("request-filtering-agent");
const openpgp = require('openpgp');
require('win-ca');
@ -80,6 +81,7 @@ const cfgTokenOutboxUrlExclusionRegex = config.get('services.CoAuthoring.token.o
const cfgPasswordEncrypt = config.get('openpgpjs.encrypt');
const cfgPasswordDecrypt = config.get('openpgpjs.decrypt');
const cfgPasswordConfig = config.get('openpgpjs.config');
const cfgRequesFilteringAgent = config.get('services.CoAuthoring.request-filtering-agent');
Object.assign(openpgp.config, cfgPasswordConfig);
@ -106,6 +108,10 @@ var g_oIpFilterRules = function() {
}();
const pemfileCache = new NodeCache({stdTTL: ms(cfgExpPemStdTtl) / 1000, checkperiod: ms(cfgExpPemCheckPeriod) / 1000, errorOnMissing: false, useClones: true});
function getRequestFilterAgent(url, options) {
return url.startsWith("https") ? new RequestFilteringHttpsAgent(options) : new RequestFilteringHttpAgent(options);
}
exports.CONVERTION_TIMEOUT = 1.5 * (cfgVisibilityTimeout + cfgQueueRetentionPeriod) * 1000;
exports.addSeconds = function(date, sec) {
@ -257,13 +263,43 @@ function raiseError(ro, code, msg) {
ro.emit('error', error);
}
function downloadUrlPromise(uri, optTimeout, optLimit, opt_Authorization, opt_headers) {
//todo replace deprecated request module
let filterPrivate = opt_Authorization ? false : true;
const maxRedirects = (undefined !== cfgRequestDefaults.maxRedirects) ? cfgRequestDefaults.maxRedirects : 10;
const followRedirect = (undefined !== cfgRequestDefaults.followRedirect) ? cfgRequestDefaults.followRedirect : true;
var redirectsFollowed = 0;
let doRequest = function(curUrl) {
return downloadUrlPromiseWithoutRedirect(curUrl, optTimeout, optLimit, opt_Authorization, filterPrivate)
.catch(function(err) {
let response = err.response;
if (response && response.statusCode >= 300 && response.statusCode < 400 && response.caseless.has('location')) {
let redirectTo = response.caseless.get('location');
if (followRedirect && redirectsFollowed < maxRedirects) {
if (!/^https?:/.test(redirectTo) && err.request) {
redirectTo = url.resolve(err.request.uri.href, redirectTo)
}
logger.debug('downloadUrlPromise redirectsFollowed:%d redirectTo: %s', redirectsFollowed, redirectTo);
redirectsFollowed++;
return doRequest(redirectTo);
}
}
throw err;
});
};
return doRequest(uri);
}
function downloadUrlPromiseWithoutRedirect(uri, optTimeout, optLimit, opt_Authorization, opt_filterPrivate) {
return new Promise(function (resolve, reject) {
//IRI to URI
uri = URI.serialize(URI.parse(uri));
var urlParsed = url.parse(uri);
//if you expect binary data, you should set encoding: null
let connectionAndInactivity = optTimeout && optTimeout.connectionAndInactivity && ms(optTimeout.connectionAndInactivity);
var options = {uri: urlParsed, encoding: null, timeout: connectionAndInactivity};
var options = {uri: urlParsed, encoding: null, timeout: connectionAndInactivity, followRedirect: false};
if (opt_filterPrivate) {
options.agent = getRequestFilterAgent(uri, cfgRequesFilteringAgent);
}
if (opt_Authorization) {
options.headers = {};
options.headers[cfgTokenOutboxHeader] = cfgTokenOutboxPrefix + opt_Authorization;
@ -295,6 +331,7 @@ function downloadUrlPromise(uri, optTimeout, optLimit, opt_Authorization, opt_he
let responseHeaders = JSON.stringify(response.headers);
let error = new Error(`Error response: statusCode:${code}; headers:${responseHeaders}; body:\r\n${body}`);
error.statusCode = response.statusCode;
error.request = ro;
error.response = response;
reject(error);
}