ReDoS mitigation, memory exhaustion payload attacks, event loop saturation runbooks, and cascade failure recovery for financial infrastructure.
Module 15 — Resiliency Runbooks & High-Load Security Defenses
What this module covers: A blockchain indexer processing 50,000 events/second is a valuable target. An attacker who can send one malicious payload that blocks the event loop for 30 seconds can effectively take the service offline. A ReDoS attack requires only an HTTP request. A memory exhaustion attack requires only a cleverly crafted JSON payload. This module covers the exact attack surfaces in high-throughput Node.js applications, the defensive patterns that prevent them, and the runbooks your team needs written down before the incident happens — because the worst time to write a runbook is during an outage.
ReDoS: Regular Expression Denial of Service
ReDoS exploits catastrophic backtracking in certain regular expression patterns. When these patterns are given carefully crafted input, the regex engine's backtracking algorithm takes exponential time.
The Vulnerable Pattern
Identifying Vulnerable Patterns
Vulnerable patterns share common characteristics:
- Nested quantifiers:
(a+)+,(a|aa)+ - Alternation with common prefixes:
(abc|abcd)+ - Overlapping quantifiers:
(\w+\s*)+
Safe Validation Patterns
Runtime Protection: statement_timeout for Regex
For regexes you cannot replace, enforce time limits:
JSON Payload Bombs: Memory Exhaustion via Deserialization
A crafted JSON payload can expand exponentially in memory after parsing.
Defense: Request Size Limits and Depth Limits
Schema-First Validation: Reject Before Parsing
The most effective defense: use ajv's compiled schema to validate structure before your application code runs.
Event Loop Blocking Attacks
Any synchronous operation on the event loop is an attack surface: if an attacker can cause your code to execute a long synchronous operation, the entire service is blocked.
JSON.parse on Large Payloads
Even with size limits, a 1MB JSON payload takes ~8ms to parse synchronously. At 50K req/sec, if even 1% of requests are 1MB payloads: 500 req/sec × 8ms = 4,000ms/sec of blocking — event loop ELU 400% (impossible — starvation).
Synchronous Crypto in Hot Paths
Circuit Breakers: Preventing Cascade Failures
When an upstream service (database, external API, blockchain RPC node) becomes slow or unavailable, requests back up — each waiting for a timeout. This cascades: slow upstream → slow application → slow everything else → OOM.
A circuit breaker short-circuits failing calls immediately after a failure threshold, giving the upstream time to recover.
Bulkhead Pattern: Isolating Failure Domains
If your service makes calls to multiple upstream services, a slow upstream should not exhaust the connection pool for all upstreams.
The Five Runbooks
Every team running Node.js in production needs these five runbooks written before they need them.
Runbook 1: Event Loop Saturation
Symptoms: ELU > 0.90, high latency, db_pool_waiting_count > 0 but CPU looks idle.
Runbook 2: Memory Leak
Symptoms: Heap memory growing continuously over hours, GC running but memory not dropping.
Runbook 3: Database Connection Pool Exhaustion
Symptoms: db_pool_waiting_count > 0, P99 latency spike to connectionTimeoutMillis.
Runbook 4: Kafka Consumer Lag Spike
Symptoms: kafka_consumer_lag_total > 100_000, analytics/notifications delayed.
Runbook 5: Service Cascade Failure
Symptoms: One upstream service goes down, your service starts failing, downstream services start failing.
Supply Chain Security: Protecting the Module Graph
Node.js applications import hundreds of transitive dependencies. Any one of them could be compromised.
Summary
| Concept | Key Takeaway |
|---|---|
| ReDoS | Catastrophic backtracking in nested quantifier regexes. Use safe-regex to audit. Enforce 10ms timeout on untrusted input. |
| JSON bombs | Deep nesting or large arrays amplify memory. Set bodyLimit, validate depth, use schema-first ajv validation. |
| Sync crypto | crypto.scryptSync and similar block the event loop. Always use async variants for expensive operations. |
| Circuit breaker | CLOSED → OPEN after N failures. Fail fast. HALF_OPEN after recovery timeout. Prevents cascade. |
| Bulkhead | Separate connection pools per upstream. Slow analytics DB cannot exhaust main DB pool. |
| Event loop runbook | ELU > 0.90 → flame graph → move blocking code to worker_threads or async. |
| Memory leak runbook | Two heap snapshots → comparison view → identify delta object type → trace to root. |
| Pool exhaustion runbook | waiting_count > 0 → kill idle-in-transaction → increase pool size → find root cause. |
| Kafka lag runbook | Scale consumers or reset offsets if from historical replay. |
| Cascade runbook | Verify circuit open → enable degraded mode → monitor HALF_OPEN recovery → restore. |
| Supply chain | Exact versions in production. npm audit. Node.js Permission Model to restrict runtime capabilities. |
The system is secure and resilient. The remaining modules cover the advanced Node.js features that eliminate entire categories of deployment, security, and performance problems: zero-trust runtime isolation, single executable deployment, native Rust integration, the Web Standards shift, and automated post-mortem diagnostics.
Next: Module 16 — Zero-Trust Runtime Architecture & The Node.js Permission Model →
A Node.js application receives a massive JSON payload with a deeply nested structure (e.g., hundreds of levels of nesting). Which of the following is the most robust, schema-first defense mechanism against memory exhaustion (JSON bombs) before the application logic even runs?
How does the Bulkhead pattern differ from a Circuit Breaker when designing resilient Node.js services?
During an incident, the Event Loop Utilization (ELU) spikes above 0.90, latency is high, but CPU usage appears idle. Following the runbook, what is the most appropriate next step to diagnose the root cause?
Test your knowledge with more question sets
Sign in to access a wider variety of questions and get notified when new practice sets are added to this module.
Sign in & RegisterDiscussion
0Join the discussion