@@ -3600,3 +3600,119 @@ describe('(GHSA-qpc3-fg4j-8hgm) Protected field change detection oracle via Live
36003600 expect ( updateSpy ) . not . toHaveBeenCalled ( ) ;
36013601 } ) ;
36023602} ) ;
3603+
3604+ describe ( '(GHSA-6qh5-m6g3-xhq6) LiveQuery query depth DoS via deeply nested subscription' , ( ) => {
3605+ afterEach ( async ( ) => {
3606+ const client = await Parse . CoreManager . getLiveQueryController ( ) . getDefaultLiveQueryClient ( ) ;
3607+ if ( client ) {
3608+ await client . close ( ) ;
3609+ }
3610+ } ) ;
3611+
3612+ it ( 'should reject LiveQuery subscription with deeply nested $or when queryDepth is set' , async ( ) => {
3613+ Parse . CoreManager . getLiveQueryController ( ) . setDefaultLiveQueryClient ( null ) ;
3614+ await reconfigureServer ( {
3615+ liveQuery : { classNames : [ 'TestClass' ] } ,
3616+ startLiveQueryServer : true ,
3617+ verbose : false ,
3618+ silent : true ,
3619+ requestComplexity : { queryDepth : 10 } ,
3620+ } ) ;
3621+ const query = new Parse . Query ( 'TestClass' ) ;
3622+ let where = { field : 'value' } ;
3623+ for ( let i = 0 ; i < 15 ; i ++ ) {
3624+ where = { $or : [ where ] } ;
3625+ }
3626+ query . _where = where ;
3627+ await expectAsync ( query . subscribe ( ) ) . toBeRejectedWith (
3628+ jasmine . objectContaining ( {
3629+ code : Parse . Error . INVALID_QUERY ,
3630+ message : jasmine . stringMatching ( / Q u e r y c o n d i t i o n n e s t i n g d e p t h e x c e e d s m a x i m u m a l l o w e d d e p t h / ) ,
3631+ } )
3632+ ) ;
3633+ } ) ;
3634+
3635+ it ( 'should reject LiveQuery subscription with deeply nested $and when queryDepth is set' , async ( ) => {
3636+ Parse . CoreManager . getLiveQueryController ( ) . setDefaultLiveQueryClient ( null ) ;
3637+ await reconfigureServer ( {
3638+ liveQuery : { classNames : [ 'TestClass' ] } ,
3639+ startLiveQueryServer : true ,
3640+ verbose : false ,
3641+ silent : true ,
3642+ requestComplexity : { queryDepth : 10 } ,
3643+ } ) ;
3644+ const query = new Parse . Query ( 'TestClass' ) ;
3645+ let where = { field : 'value' } ;
3646+ for ( let i = 0 ; i < 50 ; i ++ ) {
3647+ where = { $and : [ where ] } ;
3648+ }
3649+ query . _where = where ;
3650+ await expectAsync ( query . subscribe ( ) ) . toBeRejectedWith (
3651+ jasmine . objectContaining ( {
3652+ code : Parse . Error . INVALID_QUERY ,
3653+ message : jasmine . stringMatching ( / Q u e r y c o n d i t i o n n e s t i n g d e p t h e x c e e d s m a x i m u m a l l o w e d d e p t h / ) ,
3654+ } )
3655+ ) ;
3656+ } ) ;
3657+
3658+ it ( 'should reject LiveQuery subscription with deeply nested $nor when queryDepth is set' , async ( ) => {
3659+ Parse . CoreManager . getLiveQueryController ( ) . setDefaultLiveQueryClient ( null ) ;
3660+ await reconfigureServer ( {
3661+ liveQuery : { classNames : [ 'TestClass' ] } ,
3662+ startLiveQueryServer : true ,
3663+ verbose : false ,
3664+ silent : true ,
3665+ requestComplexity : { queryDepth : 10 } ,
3666+ } ) ;
3667+ const query = new Parse . Query ( 'TestClass' ) ;
3668+ let where = { field : 'value' } ;
3669+ for ( let i = 0 ; i < 50 ; i ++ ) {
3670+ where = { $nor : [ where ] } ;
3671+ }
3672+ query . _where = where ;
3673+ await expectAsync ( query . subscribe ( ) ) . toBeRejectedWith (
3674+ jasmine . objectContaining ( {
3675+ code : Parse . Error . INVALID_QUERY ,
3676+ message : jasmine . stringMatching ( / Q u e r y c o n d i t i o n n e s t i n g d e p t h e x c e e d s m a x i m u m a l l o w e d d e p t h / ) ,
3677+ } )
3678+ ) ;
3679+ } ) ;
3680+
3681+ it ( 'should allow LiveQuery subscription within the depth limit' , async ( ) => {
3682+ Parse . CoreManager . getLiveQueryController ( ) . setDefaultLiveQueryClient ( null ) ;
3683+ await reconfigureServer ( {
3684+ liveQuery : { classNames : [ 'TestClass' ] } ,
3685+ startLiveQueryServer : true ,
3686+ verbose : false ,
3687+ silent : true ,
3688+ requestComplexity : { queryDepth : 10 } ,
3689+ } ) ;
3690+ const query = new Parse . Query ( 'TestClass' ) ;
3691+ let where = { field : 'value' } ;
3692+ for ( let i = 0 ; i < 5 ; i ++ ) {
3693+ where = { $or : [ where ] } ;
3694+ }
3695+ query . _where = where ;
3696+ const subscription = await query . subscribe ( ) ;
3697+ expect ( subscription ) . toBeDefined ( ) ;
3698+ } ) ;
3699+
3700+ it ( 'should allow LiveQuery subscription when queryDepth is disabled' , async ( ) => {
3701+ Parse . CoreManager . getLiveQueryController ( ) . setDefaultLiveQueryClient ( null ) ;
3702+ await reconfigureServer ( {
3703+ liveQuery : { classNames : [ 'TestClass' ] } ,
3704+ startLiveQueryServer : true ,
3705+ verbose : false ,
3706+ silent : true ,
3707+ requestComplexity : { queryDepth : - 1 } ,
3708+ } ) ;
3709+ const query = new Parse . Query ( 'TestClass' ) ;
3710+ let where = { field : 'value' } ;
3711+ for ( let i = 0 ; i < 15 ; i ++ ) {
3712+ where = { $or : [ where ] } ;
3713+ }
3714+ query . _where = where ;
3715+ const subscription = await query . subscribe ( ) ;
3716+ expect ( subscription ) . toBeDefined ( ) ;
3717+ } ) ;
3718+ } ) ;
0 commit comments