Regra
Evitar não intencional global variáveis caching.In Node.js
e Python servidores, globais variáveis persistem através de
pedidos, causando dados fugas e condições de corrida condições de corrida.
Linguagens suportadas: JavaScript, TypeScript, PythonIntrodução
As variáveis globais nos servidores Node.js persistem durante o tempo de vida do processo, e não apenas num único pedido. Quando os manipuladores de pedidos armazenam dados do utilizador em variáveis globais, esses dados permanecem acessíveis a pedidos subsequentes de diferentes utilizadores. Isto cria vulnerabilidades de segurança em que os dados da sessão, os tokens de autenticação ou as informações pessoais do utilizador A vazam para o utilizador B.
Porque é importante
Implicações de segurança (fugas de dados): As variáveis globais que armazenam em cache dados específicos do utilizador criam fugas de dados entre pedidos. O estado de autenticação, os dados da sessão ou as informações pessoais de um utilizador tornam-se visíveis para outros utilizadores, violando os limites de privacidade e segurança.
Condições de corrida: Quando várias solicitações simultâneas modificam a mesma variável global, há uma grande chance de comportamento imprevisível. Os dados do utilizador A podem ser substituídos pelo pedido do utilizador B a meio do processamento, levando a cálculos incorrectos, estado corrompido ou utilizadores a verem os dados uns dos outros.
Complexidade da depuração: Os problemas causados pelo armazenamento em cache de variáveis globais são notoriamente difíceis de reproduzir porque dependem do tempo e da simultaneidade da solicitação. Os erros aparecem intermitentemente na produção sob carga, mas raramente se manifestam em testes de desenvolvimento de thread único.
Fugas de memória: As variáveis globais que acumulam dados sem limpeza crescem sem limites ao longo do tempo. Cada pedido adiciona mais dados às caches ou matrizes globais, acabando por esgotar a memória do servidor e exigindo o reinício do processo.
Exemplos de código
Não 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
};
}
Porque é que está errado: As variáveis globais currentUser e requestData persistem entre pedidos. Quando vários pedidos são executados em simultâneo, o pedido do utilizador B pode substituir currentUser enquanto o buildUserProfile() do utilizador A ainda está a ser executado, fazendo com que o utilizador A veja os dados do utilizador B.
Conformidade:
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 que isso é importante: Todos os dados específicos do pedido são armazenados em variáveis locais com escopo para o manipulador de pedido. Cada solicitação tem um estado isolado que não pode vazar para outras solicitações simultâneas. As funções recebem dados através de parâmetros em vez de acederem ao estado global, eliminando condições de corrida.
Conclusão
Mantenha todos os dados específicos do pedido em variáveis locais ou objectos de pedido fornecidos pela sua estrutura. Use variáveis globais apenas para estado verdadeiramente compartilhado, como configuração, pools de conexão ou caches somente leitura. Quando o estado global for necessário, utilize controlos de concorrência adequados e garanta que os dados nunca são específicos do utilizador.
.avif)
