@@ -164,6 +164,11 @@ static int yajl_start_array(void *ctx) {
164164 else {
165165 msr -> json -> prefix = apr_pstrdup (msr -> mp , msr -> json -> current_key );
166166 }
167+ msr -> json -> current_depth ++ ;
168+ if (msr -> json -> current_depth > msr -> txcfg -> reqbody_json_depth_limit ) {
169+ msr -> json -> depth_limit_exceeded = 1 ;
170+ return 0 ;
171+ }
167172
168173 if (msr -> txcfg -> debuglog_level >= 9 ) {
169174 msr_log (msr , 9 , "New JSON hash context (prefix '%s')" , msr -> json -> prefix );
@@ -200,6 +205,7 @@ static int yajl_end_array(void *ctx) {
200205 */
201206 msr -> json -> prefix = (unsigned char * ) NULL ;
202207 }
208+ msr -> json -> current_depth -- ;
203209
204210 return 1 ;
205211}
@@ -229,6 +235,11 @@ static int yajl_start_map(void *ctx)
229235 else {
230236 msr -> json -> prefix = apr_pstrdup (msr -> mp , msr -> json -> current_key );
231237 }
238+ msr -> json -> current_depth ++ ;
239+ if (msr -> json -> current_depth > msr -> txcfg -> reqbody_json_depth_limit ) {
240+ msr -> json -> depth_limit_exceeded = 1 ;
241+ return 0 ;
242+ }
232243
233244 if (msr -> txcfg -> debuglog_level >= 9 ) {
234245 msr_log (msr , 9 , "New JSON hash context (prefix '%s')" , msr -> json -> prefix );
@@ -270,6 +281,7 @@ static int yajl_end_map(void *ctx)
270281 msr -> json -> current_key = msr -> json -> prefix ;
271282 msr -> json -> prefix = (unsigned char * ) NULL ;
272283 }
284+ msr -> json -> current_depth -- ;
273285
274286 return 1 ;
275287}
@@ -308,6 +320,9 @@ int json_init(modsec_rec *msr, char **error_msg) {
308320 msr -> json -> prefix = (unsigned char * ) NULL ;
309321 msr -> json -> current_key = (unsigned char * ) NULL ;
310322
323+ msr -> json -> current_depth = 0 ;
324+ msr -> json -> depth_limit_exceeded = 0 ;
325+
311326 /**
312327 * yajl initialization
313328 *
@@ -337,7 +352,11 @@ int json_process_chunk(modsec_rec *msr, const char *buf, unsigned int size, char
337352 msr -> json -> status = yajl_parse (msr -> json -> handle , buf , size );
338353 if (msr -> json -> status != yajl_status_ok ) {
339354 /* We need to free the yajl error message later, how to do this? */
340- * error_msg = yajl_get_error (msr -> json -> handle , 0 , buf , size );
355+ if (msr -> json -> depth_limit_exceeded ) {
356+ * error_msg = "JSON depth limit exceeded" ;
357+ } else {
358+ * error_msg = yajl_get_error (msr -> json -> handle , 0 , NULL , 0 );
359+ }
341360 return -1 ;
342361 }
343362
@@ -357,7 +376,12 @@ int json_complete(modsec_rec *msr, char **error_msg) {
357376 msr -> json -> status = yajl_complete_parse (msr -> json -> handle );
358377 if (msr -> json -> status != yajl_status_ok ) {
359378 /* We need to free the yajl error message later, how to do this? */
360- * error_msg = yajl_get_error (msr -> json -> handle , 0 , NULL , 0 );
379+ if (msr -> json -> depth_limit_exceeded ) {
380+ * error_msg = "JSON depth limit exceeded" ;
381+ } else {
382+ * error_msg = yajl_get_error (msr -> json -> handle , 0 , NULL , 0 );
383+ }
384+
361385 return -1 ;
362386 }
363387
0 commit comments