File tree 3 files changed +20
-5
lines changed
3 files changed +20
-5
lines changed Original file line number Diff line number Diff line change @@ -280,4 +280,18 @@ describe('Vulnerabilities', () => {
280
280
expect ( text . error ) . toBe ( 'Prohibited keyword in request data: {"value":"aValue[123]*"}.' ) ;
281
281
} ) ;
282
282
} ) ;
283
+
284
+ describe ( 'Ignore non-matches' , ( ) => {
285
+ it ( 'ignores write request that contains only fraction of denied keyword' , async ( ) => {
286
+ await reconfigureServer ( {
287
+ requestKeywordDenylist : [ { key : 'abc' } ] ,
288
+ } ) ;
289
+ // Initially saving an object executes the keyword detection in RestWrite.js
290
+ const obj = new TestObject ( { a : { b : { c : 0 } } } ) ;
291
+ await expectAsync ( obj . save ( ) ) . toBeResolved ( ) ;
292
+ // Modifying a nested key executes the keyword detection in DatabaseController.js
293
+ obj . increment ( 'a.b.c' ) ;
294
+ await expectAsync ( obj . save ( ) ) . toBeResolved ( ) ;
295
+ } ) ;
296
+ } ) ;
283
297
} ) ;
Original file line number Diff line number Diff line change @@ -11,6 +11,7 @@ import intersect from 'intersect';
11
11
// @flow -disable-next
12
12
import deepcopy from 'deepcopy' ;
13
13
import logger from '../logger' ;
14
+ import Utils from '../Utils' ;
14
15
import * as SchemaController from './SchemaController' ;
15
16
import { StorageAdapter } from '../Adapters/Storage/StorageAdapter' ;
16
17
import MongoStorageAdapter from '../Adapters/Storage/Mongo/MongoStorageAdapter' ;
@@ -1763,8 +1764,8 @@ class DatabaseController {
1763
1764
if ( this . options && this . options . requestKeywordDenylist ) {
1764
1765
// Scan request data for denied keywords
1765
1766
for ( const keyword of this . options . requestKeywordDenylist ) {
1766
- const isMatch = ( a , b ) => ( typeof a === 'string' && new RegExp ( a ) . test ( b ) ) || a === b ;
1767
- if ( isMatch ( firstKey , keyword . key ) ) {
1767
+ const match = Utils . objectContainsKeyValue ( { firstKey : undefined } , keyword . key , undefined ) ;
1768
+ if ( match ) {
1768
1769
throw new Parse . Error (
1769
1770
Parse . Error . INVALID_KEY_NAME ,
1770
1771
`Prohibited keyword in request data: ${ JSON . stringify ( keyword ) } .`
Original file line number Diff line number Diff line change @@ -341,9 +341,9 @@ class Utils {
341
341
* @returns {Boolean } True if a match was found, false otherwise.
342
342
*/
343
343
static objectContainsKeyValue ( obj , key , value ) {
344
- const isMatch = ( a , b ) => ( typeof a === 'string' && new RegExp ( a ) . test ( b ) ) || a === b ;
345
- const isKeyMatch = k => isMatch ( key , k ) ;
346
- const isValueMatch = v => isMatch ( value , v ) ;
344
+ const isMatch = ( a , b ) => ( typeof a === 'string' && new RegExp ( b ) . test ( a ) ) || a === b ;
345
+ const isKeyMatch = k => isMatch ( k , key ) ;
346
+ const isValueMatch = v => isMatch ( v , value ) ;
347
347
for ( const [ k , v ] of Object . entries ( obj ) ) {
348
348
if ( key !== undefined && value === undefined && isKeyMatch ( k ) ) {
349
349
return true ;
You can’t perform that action at this time.
0 commit comments