Skip to content

Commit

Permalink
fix and optimize keyword detection
Browse files Browse the repository at this point in the history
  • Loading branch information
mtrezza committed Mar 24, 2022
1 parent b279d73 commit 640f926
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 4 deletions.
14 changes: 14 additions & 0 deletions spec/vulnerabilities.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -280,4 +280,18 @@ describe('Vulnerabilities', () => {
expect(text.error).toBe('Prohibited keyword in request data: {"value":"aValue[123]*"}.');
});
});

describe('Ignore non-matches', () => {
it('ignores write request that contains only fraction of denied keyword', async () => {
await reconfigureServer({
requestKeywordDenylist: [{ key: 'abc' }],
});
// Initially saving an object executes the keyword detection in RestWrite.js
const obj = new TestObject({ a: { b: { c: 0 } } });
await expectAsync(obj.save()).toBeResolved();
// Modifying a nested key executes the keyword detection in DatabaseController.js
obj.increment('a.b.c');
await expectAsync(obj.save()).toBeResolved();
});
});
});
5 changes: 3 additions & 2 deletions src/Controllers/DatabaseController.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import intersect from 'intersect';
// @flow-disable-next
import deepcopy from 'deepcopy';
import logger from '../logger';
import Utils from '../Utils';
import * as SchemaController from './SchemaController';
import { StorageAdapter } from '../Adapters/Storage/StorageAdapter';
import MongoStorageAdapter from '../Adapters/Storage/Mongo/MongoStorageAdapter';
Expand Down Expand Up @@ -1763,8 +1764,8 @@ class DatabaseController {
if (this.options && this.options.requestKeywordDenylist) {
// Scan request data for denied keywords
for (const keyword of this.options.requestKeywordDenylist) {
const isMatch = (a, b) => (typeof a === 'string' && new RegExp(b).test(a)) || a === b;
if (isMatch(firstKey, keyword.key)) {
const match = Utils.objectContainsKeyValue({ firstKey: undefined }, keyword.key, undefined);
if (match) {
throw new Parse.Error(
Parse.Error.INVALID_KEY_NAME,
`Prohibited keyword in request data: ${JSON.stringify(keyword)}.`
Expand Down
4 changes: 2 additions & 2 deletions src/Utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,8 @@ class Utils {
*/
static objectContainsKeyValue(obj, key, value) {
const isMatch = (a, b) => (typeof a === 'string' && new RegExp(b).test(a)) || a === b;
const isKeyMatch = k => isMatch(key, k);
const isValueMatch = v => isMatch(value, v);
const isKeyMatch = k => isMatch(k, key);
const isValueMatch = v => isMatch(v, value);
for (const [k, v] of Object.entries(obj)) {
if (key !== undefined && value === undefined && isKeyMatch(k)) {
return true;
Expand Down

0 comments on commit 640f926

Please sign in to comment.