Check composite keys containing hidden props

This commit is contained in:
Raymond Feng 2018-10-29 07:57:55 -07:00
parent 8fa7c94605
commit dbe25f282d
3 changed files with 76 additions and 3 deletions

View File

@ -302,6 +302,19 @@ function selectFields(fields) {
};
}
function isProhibited(key, prohibitedKeys) {
if (!prohibitedKeys || !prohibitedKeys.length) return false;
if (typeof key !== 'string') {
return false;
}
for (var k of prohibitedKeys) {
if (k === key) return true;
// x.secret, secret.y, or x.secret.y
if (key.split('.').indexOf(k) !== -1) return true;
}
return false;
}
/**
* Sanitize the query object
* @param query {object} The query object
@ -341,7 +354,7 @@ function sanitizeQuery(query, options) {
* Make sure prohibited keys are removed from the query to prevent
* sensitive values from being guessed
*/
if (prohibitedKeys && prohibitedKeys.indexOf(this.key) !== -1) {
if (isProhibited(this.key, prohibitedKeys)) {
offendingKeys.push(this.key);
this.remove();
return;

View File

@ -394,7 +394,6 @@ describe('DataSource define model', function() {
User.create({name: 'Jeff'}, function(err, data) {
if (err) {
console.log(err);
return;
}
var post = data.posts.build({title: 'My Post'});

View File

@ -395,7 +395,10 @@ describe('ModelDefinition class', function() {
*/
function givenChildren(hiddenProps) {
hiddenProps = hiddenProps || {hidden: ['secret']};
Child = memory.createModel('child', {}, hiddenProps);
Child = memory.createModel('child', {
name: String,
secret: String,
}, hiddenProps);
return Child.create([{
name: 'childA',
secret: 'secret',
@ -412,6 +415,64 @@ describe('ModelDefinition class', function() {
}
});
describe('hidden nested properties', function() {
var Child;
beforeEach(givenChildren);
it('should be removed if used in where as a composite key - x.secret', function() {
return Child.find({
where: {'x.secret': 'guess'},
}).then(assertHiddenPropertyIsIgnored);
});
it('should be removed if used in where as a composite key - secret.y', function() {
return Child.find({
where: {'secret.y': 'guess'},
}).then(assertHiddenPropertyIsIgnored);
});
it('should be removed if used in where as a composite key - a.secret.b', function() {
return Child.find({
where: {'a.secret.b': 'guess'},
}).then(assertHiddenPropertyIsIgnored);
});
function givenChildren() {
var hiddenProps = {hidden: ['secret']};
Child = memory.createModel('child', {
name: String,
x: {
secret: String,
},
secret: {
y: String,
},
a: {
secret: {
b: String,
},
},
}, hiddenProps);
return Child.create([{
name: 'childA',
x: {secret: 'secret'},
secret: {y: 'secret'},
a: {secret: {b: 'secret'}},
}, {
name: 'childB',
x: {secret: 'guess'},
secret: {y: 'guess'},
a: {secret: {b: 'guess'}},
}]);
}
function assertHiddenPropertyIsIgnored(children) {
// All children are found whether the `secret` condition matches or not
// as the condition is removed because it's hidden
children.length.should.equal(2);
}
});
function assertParentIncludeChildren(parents) {
parents[0].toJSON().children.length.should.equal(1);
}