Allow configuration of maxDepthOfQuery
https://github.com/strongloop/loopback-datasource-juggler/issues/1651
This commit is contained in:
parent
b4d0cf54a8
commit
41d5f20fff
|
@ -1684,8 +1684,8 @@ DataAccessObject._sanitizeQuery = function(query, options) {
|
|||
prohibitHiddenPropertiesInQuery = true;
|
||||
}
|
||||
|
||||
if (!prohibitHiddenPropertiesInQuery)
|
||||
console.log(prohibitHiddenPropertiesInQuery);
|
||||
// See https://github.com/strongloop/loopback-datasource-juggler/issues/1651
|
||||
var maxDepthOfQuery = (+this._getSetting('maxDepthOfQuery')) || 12;
|
||||
|
||||
var prohibitedKeys = [];
|
||||
// Check violation of keys
|
||||
|
@ -1697,6 +1697,7 @@ DataAccessObject._sanitizeQuery = function(query, options) {
|
|||
}
|
||||
return sanitizeQueryOrData(query,
|
||||
Object.assign({
|
||||
maxDepth: maxDepthOfQuery,
|
||||
prohibitedKeys: prohibitedKeys,
|
||||
normalizeUndefinedInQuery: normalizeUndefinedInQuery,
|
||||
}, options));
|
||||
|
|
15
lib/utils.js
15
lib/utils.js
|
@ -336,18 +336,25 @@ function sanitizeQuery(query, options) {
|
|||
const prohibitedKeys = options.prohibitedKeys;
|
||||
const offendingKeys = [];
|
||||
const normalizeUndefinedInQuery = options.normalizeUndefinedInQuery;
|
||||
const maxDepth = options.maxDepth || 10;
|
||||
const maxDepth = options.maxDepth || 12;
|
||||
// WARNING: [rfeng] Use map() will cause mongodb to produce invalid BSON
|
||||
// as traverse doesn't transform the ObjectId correctly
|
||||
const result = traverse(query).forEach(function(x) {
|
||||
/**
|
||||
* Security risk if the client passes in a very deep where object
|
||||
*/
|
||||
if (this.level > maxDepth || this.circular) {
|
||||
const msg = g.f('The query object is too deep or circular');
|
||||
if (this.circular) {
|
||||
const msg = g.f('The query object is circular');
|
||||
const err = new Error(msg);
|
||||
err.statusCode = 400;
|
||||
err.code = 'WHERE_OBJECT_TOO_DEEP';
|
||||
err.code = 'QUERY_OBJECT_IS_CIRCULAR';
|
||||
throw err;
|
||||
}
|
||||
if (this.level > maxDepth) {
|
||||
const msg = g.f('The query object exceeds maximum depth %d', maxDepth);
|
||||
const err = new Error(msg);
|
||||
err.statusCode = 400;
|
||||
err.code = 'QUERY_OBJECT_TOO_DEEP';
|
||||
throw err;
|
||||
}
|
||||
/**
|
||||
|
|
|
@ -257,6 +257,41 @@ describe('ModelDefinition class', function() {
|
|||
done();
|
||||
});
|
||||
|
||||
describe('maxDepthOfQuery', function() {
|
||||
it('should report errors for deep query than maxDepthOfQuery', function(done) {
|
||||
var MyModel = memory.createModel('my-model', {}, {
|
||||
maxDepthOfQuery: 5,
|
||||
});
|
||||
|
||||
var filter = givenComplexFilter();
|
||||
|
||||
MyModel.find(filter, function(err) {
|
||||
should.exist(err);
|
||||
err.message.should.match('The query object exceeds maximum depth 5');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should honor maxDepthOfQuery setting', function(done) {
|
||||
var MyModel = memory.createModel('my-model', {}, {
|
||||
maxDepthOfQuery: 20,
|
||||
});
|
||||
|
||||
var filter = givenComplexFilter();
|
||||
|
||||
MyModel.find(filter, function(err) {
|
||||
should.not.exist(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
function givenComplexFilter() {
|
||||
var filter = {where: {and: [{and: [{and: [{and: [{and: [{and:
|
||||
[{and: [{and: [{and: [{x: 1}]}]}]}]}]}]}]}]}]}};
|
||||
return filter;
|
||||
}
|
||||
});
|
||||
|
||||
it('should serialize protected properties into JSON', function() {
|
||||
var ProtectedModel = memory.createModel('protected', {}, {
|
||||
protected: ['protectedProperty'],
|
||||
|
|
|
@ -88,18 +88,18 @@ describe('util.sanitizeQuery', function() {
|
|||
var q7 = {where: {x: 1}};
|
||||
q7.where.y = q7;
|
||||
(function() { sanitizeQuery(q7); }).should.throw(
|
||||
/The query object is too deep or circular/
|
||||
/The query object is circular/
|
||||
);
|
||||
|
||||
var q8 = {where: {and: [{and: [{and: [{and: [{and: [{and:
|
||||
[{and: [{and: [{and: [{x: 1}]}]}]}]}]}]}]}]}]}};
|
||||
(function() { sanitizeQuery(q8); }).should.throw(
|
||||
/The query object is too deep or circular/
|
||||
/The query object exceeds maximum depth 12/
|
||||
);
|
||||
|
||||
var q9 = {where: {and: [{and: [{and: [{and: [{x: 1}]}]}]}]}};
|
||||
(function() { sanitizeQuery(q8, {maxDepth: 4}); }).should.throw(
|
||||
/The query object is too deep or circular/
|
||||
/The query object exceeds maximum depth 4/
|
||||
);
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue