File tree Expand file tree Collapse file tree 3 files changed +20
-5
lines changed Expand file tree Collapse file tree 3 files changed +20
-5
lines changed Original file line number Diff line number Diff line change @@ -280,4 +280,18 @@ describe('Vulnerabilities', () => {
280280 expect ( text . error ) . toBe ( 'Prohibited keyword in request data: {"value":"aValue[123]*"}.' ) ;
281281 } ) ;
282282 } ) ;
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+ } ) ;
283297} ) ;
Original file line number Diff line number Diff line change @@ -11,6 +11,7 @@ import intersect from 'intersect';
1111// @flow -disable-next
1212import deepcopy from 'deepcopy' ;
1313import logger from '../logger' ;
14+ import Utils from '../Utils' ;
1415import * as SchemaController from './SchemaController' ;
1516import { StorageAdapter } from '../Adapters/Storage/StorageAdapter' ;
1617import MongoStorageAdapter from '../Adapters/Storage/Mongo/MongoStorageAdapter' ;
@@ -1763,8 +1764,8 @@ class DatabaseController {
17631764 if ( this . options && this . options . requestKeywordDenylist ) {
17641765 // Scan request data for denied keywords
17651766 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 ) {
17681769 throw new Parse . Error (
17691770 Parse . Error . INVALID_KEY_NAME ,
17701771 `Prohibited keyword in request data: ${ JSON . stringify ( keyword ) } .`
Original file line number Diff line number Diff line change @@ -341,9 +341,9 @@ class Utils {
341341 * @returns {Boolean } True if a match was found, false otherwise.
342342 */
343343 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 ) ;
347347 for ( const [ k , v ] of Object . entries ( obj ) ) {
348348 if ( key !== undefined && value === undefined && isKeyMatch ( k ) ) {
349349 return true ;
You can’t perform that action at this time.
0 commit comments