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: