Skip to main content

Depth Limiting Protection

Overview

Depth limiting prevents attackers from sending deeply nested objects to overwhelm your server, bypass validation, or exploit parsing vulnerabilities.

Why This Is Important

The Problem: Deeply Nested Attack Payloads

Attackers can craft malicious payloads with excessive nesting to:

1. Stack Overflow Attacks

{
"level1": {
"level2": {
"level3": {
// ... 1000+ levels deep
"level1000": {
"__proto__": {
"isAdmin": true
}
}
}
}
}
}

What Happens Without Protection:

  • JavaScript call stack overflows
  • Server crashes with RangeError: Maximum call stack size exceeded
  • Application becomes unavailable
  • Denial of Service (DoS) achieved

Impact:

  • Application crashes and downtime
  • Continuous crash loops
  • CPU spikes and memory leaks
  • All users affected

2. Validation Bypass

{
"user": {
"profile": {
"settings": {
"preferences": {
"security": {
"advanced": {
"deep": {
"hidden": {
"backdoor": {
"__proto__": {
"isAdmin": true
}
}
}
}
}
}
}
}
}
}
}

What Happens Without Protection:

  • Shallow validators only check top 2-3 levels
  • Deep malicious payloads go undetected
  • Prototype pollution succeeds
  • Security breach achieved

Impact:

  • Authentication bypass
  • Privilege escalation
  • Unauthorized data access

3. Parser Exploitation

// Deeply nested arrays
[[[[[[[[[[[[[[[["malicious"]]]]]]]]]]]]]]]

What Happens Without Protection:

  • JSON parser works harder for each level
  • Exponential time complexity: O(n²) or O(n³)
  • Server becomes unresponsive
  • CPU usage spikes to 100%

Impact:

  • Response time degradation
  • CPU exhaustion
  • Service degradation for all users

4. Memory Exhaustion

// Each level allocates memory
// 1000 levels × 100 bytes = 100KB per request
// 1000 concurrent requests = 100MB

What Happens Without Protection:

  • Each nested level allocates memory
  • Memory not released until request completes
  • Multiple concurrent requests multiply impact
  • Server runs out of memory

Impact:

  • Out of Memory errors and crashes
  • Garbage collection storms
  • Performance degradation

How nextjs-fortress Solves This

The Algorithm

/**
* Check nesting depth to prevent deeply nested attacks
*/
private checkDepth(obj: unknown, currentDepth: number): ValidationResult {
// Base case: exceeded max depth
if (currentDepth > this.config.maxDepth) {
return {
valid: false,
severity: 'medium',
message: `Nesting depth exceeds maximum (${this.config.maxDepth})`,
rule: 'max_depth_exceeded',
confidence: 0.85,
}
}

// Not an object - no need to go deeper
if (obj === null || typeof obj !== 'object') {
return { valid: true }
}

// Recursively check all nested values
for (const value of Object.values(obj)) {
if (value !== null && typeof value === 'object') {
const result = this.checkDepth(value, currentDepth + 1)
if (!result.valid) {
return result // Stop immediately on failure
}
}
}

return { valid: true }
}

Why This Works

1. Early Detection - Stops immediately when limit exceeded 2. Efficient Checking - O(n) time, O(d) space 3. Configurable Limits - Adjust based on your needs

How to Initialize

import { FortressConfig } from '@mindfiredigital/nextjs-fortress';

export const fortressConfig: FortressConfig = {
enabled: true,
mode: 'development',

modules: {
deserialization: {
enabled: true,
maxDepth: 10, // Set depth limit
detectCircular: true, // Enable circular detection
blockList: [ // Dangerous keys
'__proto__',
'constructor',
'prototype'
],
},
},
};

Summary

What happens without depth limiting:

  • Stack overflow crashes
  • DoS attacks succeed
  • Validation bypasses
  • Memory exhaustion

What nextjs-fortress provides:

  • Configurable depth limits
  • Early attack detection
  • Efficient validation
  • Zero performance impact

How to initialize:

deserialization: {
enabled: true,
maxDepth: 10, // Blocks after 10 levels
detectCircular: true,
}

Related Documentation: