Rule
Avoid unintended global variable caching.In Node.js
and Python servers, global variables persist across
requests, causing data leaks and race conditions.
Supported languages: JavaScript, TypeScript, PythonIntroduction
Global variables in Node.js servers persist for the lifetime of the process, not just a single request. When request handlers store user data in global variables, that data remains accessible to subsequent requests from different users. This creates security vulnerabilities where user A's session data, authentication tokens, or personal information leak to user B.
Why it matters
Security implications (data leaks): Global variables that cache user-specific data create cross-request data leaks. One user's authentication state, session data, or personal information becomes visible to other users, violating privacy and security boundaries.
Race conditions: When multiple concurrent requests modify the same global variable, there's a high chance of unpredictable behavior. User A's data can get overwritten by user B's request mid-processing, leading to incorrect calculations, corrupted state, or users seeing each other's data.
Debugging complexity: Issues caused by global variable caching are notoriously difficult to reproduce because they depend on request timing and concurrency. Bugs appear intermittently in production under load but rarely manifest in single-threaded development testing.
Memory leaks: Global variables that accumulate data without cleanup grow unbounded over time. Each request adds more data to global caches or arrays, eventually exhausting server memory and requiring process restarts.
Code examples
❌ Non-compliant:
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
};
}
Why it's wrong: The global variables currentUser and requestData persist across requests. When multiple requests execute concurrently, user B's request can overwrite currentUser while user A's buildUserProfile() is still executing, causing user A to see user B's data.
✅ Compliant:
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
};
}
Why this matters: All request-specific data is stored in local variables scoped to the request handler. Each request has isolated state that can't leak to other concurrent requests. Functions receive data through parameters rather than accessing global state, eliminating race conditions.
Conclusion
Keep all request-specific data in local variables or request objects provided by your framework. Use global variables only for truly shared state like configuration, connection pools, or read-only caches. When global state is necessary, use proper concurrency controls and ensure data is never user-specific.
.avif)
