Regola
Evitare la la ricorsione senza protezione .
Ricorsione senza adeguata profondità limitazione rischi pila
overflow e crea vulnerabilità vulnerabilità derivanti da input
. Ricorsione con restrizioni profondità limiti e adeguati
limiti verifica è accettabile.
Supporto linguistico: 45+Introduzione
Le funzioni ricorsive senza limiti di profondità possono esaurire lo stack delle chiamate, causando arresti anomali. Input dannosi, come oggetti JSON profondamente annidati o strutture di dati cicliche, possono innescare intenzionalmente una ricorsione illimitata. Una singola richiesta appositamente costruita può causare l'arresto anomalo del servizio superando i limiti dello stack, creando una vulnerabilità di tipo denial-of-service (DoS) di facile sfruttamento.
Perché è importante
Implicazioni per la sicurezza (attacchi DoS): gli aggressori possono creare input che innescano una ricorsione profonda, causando il crash dell'applicazione. Strutture JSON, XML o dati collegati profondamente annidati sono vettori di attacco comuni. Una singola richiesta dannosa esaurisce lo stack, mettendo fuori uso l'intero servizio per tutti gli utenti.
Stabilità del sistema: gli errori di overflow dello stack causano l'arresto immediato del processo senza un degrado graduale. In ambiente di produzione, ciò comporta la perdita di richieste, l'interruzione delle transazioni e l'indisponibilità del servizio. Il ripristino richiede il riavvio dell'intera applicazione.
Esaurimento delle risorse: la ricorsione illimitata consuma la memoria dello stack in modo esponenziale. Ogni chiamata ricorsiva aggiunge un frame dello stack e le catene di ricorsione profonde possono consumare megabyte di memoria. Ciò influisce sugli altri processi presenti sullo stesso server e può causare condizioni di esaurimento della memoria.
Esempi di codice
❌ Non conforme:
function processNestedData(obj) {
if (typeof obj !== 'object' || obj === null) {
return obj;
}
const result = {};
for (const key in obj) {
result[key] = processNestedData(obj[key]);
}
return result;
}Perché è sbagliato: L'assenza di un limite di profondità consente agli autori degli attacchi di inviare oggetti profondamente annidati che superano i limiti dello stack. Input come {a: {a: {a: {...}}}} Una ricorsione annidata di 10.000 livelli provoca il crash dell'applicazione a causa di uno stack overflow. La funzione esegue la ricorsione in modo cieco, senza verificare la profondità.
✅ Conforme:
function processNestedData(obj, depth = 0, maxDepth = 100) {
if (depth > maxDepth) {
throw new Error('Maximum nesting depth exceeded');
}
if (typeof obj !== 'object' || obj === null) {
return obj;
}
const result = {};
for (const key in obj) {
result[key] = processNestedData(obj[key], depth + 1, maxDepth);
}
return result;
}Perché è importante: Il maxDepth Questo parametro limita la ricorsione a 100 livelli, impedendo il traboccamento dello stack. Tale limite è sufficientemente elevato per le strutture di dati annidate legittime (la maggior parte dei dati reali raramente supera i 10-20 livelli), pur essendo sufficientemente basso da bloccare gli attacchi prima che consumino una quantità significativa di memoria dello stack. Un input dannoso profondamente annidato genera un errore anziché causare il crash dell'applicazione. Il controllo della profondità avviene prima dell'elaborazione, con un'interruzione immediata in caso di superamento dei limiti.
Conclusione
Aggiungere parametri di profondità a tutte le funzioni ricorsive che elaborano dati esterni. Impostare valori massimi di profondità ragionevoli in base alla complessità prevista della struttura dei dati. Quando i limiti di profondità vengono superati, generare errori o restituire valori predefiniti, anziché causare un arresto anomalo del programma.

