Regla
Evite involuntarias global variable caching.In Node.js
y Python servidores, globales variables persisten en a través de
peticiones, causando datos de datos y carrera condiciones de carrera.
Lenguajes compatibles: JavaScript, TypeScript, PythonIntroducción
Las variables globales en los servidores Node.js persisten durante la vida útil del proceso, no solo para una única solicitud. Cuando los manejadores de solicitudes almacenan datos de usuario en variables globales, esos datos permanecen accesibles para solicitudes posteriores de diferentes usuarios. Esto crea vulnerabilidades de seguridad donde los datos de sesión, los tokens de autenticación o la información personal del usuario A se filtran al usuario B.
Por qué es importante
Implicaciones de seguridad (fugas de datos): Las variables globales que almacenan en caché datos específicos del usuario crean fugas de datos entre solicitudes. El estado de autenticación, los datos de sesión o la información personal de un usuario se hacen visibles para otros usuarios, violando los límites de privacidad y seguridad.
Condiciones de carrera: Cuando múltiples solicitudes concurrentes modifican la misma variable global, existe una alta probabilidad de comportamiento impredecible. Los datos del usuario A pueden ser sobrescritos por la solicitud del usuario B a mitad del procesamiento, lo que lleva a cálculos incorrectos, estados corruptos o que los usuarios vean los datos de otros.
Complejidad de la depuración: Los problemas causados por el almacenamiento en caché de variables globales son notoriamente difíciles de reproducir porque dependen del tiempo de la solicitud y la concurrencia. Los errores aparecen intermitentemente en producción bajo carga, pero rara vez se manifiestan en pruebas de desarrollo de un solo hilo.
Fugas de memoria: Las variables globales que acumulan datos sin limpieza crecen sin límite con el tiempo. Cada solicitud añade más datos a las cachés o arrays globales, agotando finalmente la memoria del servidor y requiriendo reinicios del proceso.
Ejemplos de código
❌ No 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
};
}
Por qué está mal: Las variables globales currentUser y requestData persisten entre solicitudes. Cuando múltiples solicitudes se ejecutan concurrentemente, la solicitud del usuario B puede sobrescribir currentUser mientras buildUserProfile() del usuario A todavía se está ejecutando, haciendo que el usuario A vea los datos del usuario 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
};
}
Por qué esto es importante: Todos los datos específicos de la solicitud se almacenan en variables locales con ámbito en el manejador de solicitudes. Cada solicitud tiene un estado aislado que no puede filtrarse a otras solicitudes concurrentes. Las funciones reciben datos a través de parámetros en lugar de acceder al estado global, eliminando las condiciones de carrera.
Conclusión
Mantén todos los datos específicos de la solicitud en variables locales u objetos de solicitud proporcionados por tu framework. Usa variables globales solo para estados verdaderamente compartidos, como la configuración, los pools de conexión o las cachés de solo lectura. Cuando el estado global sea necesario, utiliza controles de concurrencia adecuados y asegúrate de que los datos nunca sean específicos del usuario.
.avif)
