Regola
Evitare un globali variabile . In Node.js
e Python server, le variabili variabili rimangono attraverso
richieste, causando perdite perdite e situazioni condizioni di competizione.
Linguaggi supportati: JavaScript, TypeScript, PythonIntroduzione
Le variabili globali nei server Node.js permangono per tutta la durata del processo, non solo per una singola richiesta. Quando i gestori delle richieste memorizzano i dati degli utenti nelle variabili globali, tali dati rimangono accessibili alle richieste successive provenienti da utenti diversi. Ciò crea vulnerabilità di sicurezza in cui i dati di sessione, i token di autenticazione o le informazioni personali dell'utente A vengono divulgati all'utente B.
Perché è importante
Implicazioni per la sicurezza (fughe di dati): le variabili globali che memorizzano nella cache dati specifici dell'utente causano fughe di dati tra le richieste. Lo stato di autenticazione, i dati di sessione o le informazioni personali di un utente diventano visibili ad altri utenti, violando i limiti di privacy e sicurezza.
Condizioni di competizione: quando più richieste simultanee modificano la stessa variabile globale, vi è un’elevata probabilità che si verifichino comportamenti imprevedibili. I dati dell’utente A possono essere sovrascritti dalla richiesta dell’utente B durante l’elaborazione, causando calcoli errati, uno stato corrotto o la visualizzazione reciproca dei dati da parte degli utenti.
Complessità del debug: i problemi causati dalla memorizzazione nella cache delle variabili globali sono notoriamente difficili da riprodurre, poiché dipendono dalla tempistica delle richieste e dalla concorrenza. I bug compaiono in modo intermittente in produzione sotto carico, ma raramente si manifestano nei test di sviluppo a thread singolo.
Perdite di memoria: le variabili globali che accumulano dati senza essere ripulite crescono senza limiti nel tempo. Ogni richiesta aggiunge ulteriori dati alle cache o agli array globali, finendo per esaurire la memoria del server e rendendo necessario il riavvio del processo.
Esempi di codice
❌ Non conforme:
let currentUser = null;
let requestData = {};
app.get('/profile', async (req, res) => {
currentUser = await getUserById(req.userId);
requestData = req.body;
const profile = await buildUserProfile(currentUser);
res.json(profile);
});
function buildUserProfile(user) {
return {
name: currentUser.name,
data: requestData
};
}
Perché è sbagliato: le variabili globali `currentUser` e `requestData` permangono tra una richiesta e l'altra. Quando più richieste vengono eseguite contemporaneamente, la richiesta dell'utente B può sovrascrivere `currentUser` mentre la funzione `buildUserProfile()` dell'utente A è ancora in esecuzione, facendo sì che l'utente A visualizzi i dati dell'utente B.
✅ Conforme:
app.get('/profile', async (req, res) => {
const currentUser = await getUserById(req.userId);
const requestData = req.body;
const profile = buildUserProfile(currentUser, requestData);
res.json(profile);
});
function buildUserProfile(user, data) {
return {
name: user.name,
data: data
};
}
Perché è importante: tutti i dati specifici di una richiesta vengono memorizzati in variabili locali il cui ambito è limitato al gestore della richiesta. Ogni richiesta ha uno stato isolato che non può interferire con altre richieste in corso. Le funzioni ricevono i dati tramite parametri anziché accedere allo stato globale, eliminando così le condizioni di competizione.
Conclusione
Conserva tutti i dati specifici della richiesta in variabili locali o negli oggetti di richiesta forniti dal framework. Utilizza le variabili globali solo per lo stato effettivamente condiviso, come la configurazione, i pool di connessioni o le cache di sola lettura. Quando lo stato globale è necessario, utilizza adeguati controlli di concorrenza e assicurati che i dati non siano mai specifici per un utente.

