Skip to content

Commit

Permalink
Allow configuration of maxDepthOfQuery
Browse files Browse the repository at this point in the history
  • Loading branch information
raymondfeng committed Oct 31, 2018
1 parent 3348d50 commit eb85b3e
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 9 deletions.
5 changes: 3 additions & 2 deletions lib/dao.js
Expand Up @@ -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
Expand All @@ -1697,6 +1697,7 @@ DataAccessObject._sanitizeQuery = function(query, options) {
}
return sanitizeQueryOrData(query,
Object.assign({
maxDepth: maxDepthOfQuery,
prohibitedKeys: prohibitedKeys,
normalizeUndefinedInQuery: normalizeUndefinedInQuery,
}, options));
Expand Down
15 changes: 11 additions & 4 deletions lib/utils.js
Expand Up @@ -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;
}
/**
Expand Down
35 changes: 35 additions & 0 deletions test/model-definition.test.js
Expand Up @@ -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'],
Expand Down
6 changes: 3 additions & 3 deletions test/util.test.js
Expand Up @@ -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/
);
});

Expand Down

0 comments on commit eb85b3e

Please sign in to comment.