flawopen.com/Path Traversal/Node.js path.join()
Node.js path.join() impede Path Traversal?
Não. path.join() normaliza segmentos, mas não impede que .. saia do diretório pretendido. Resolva o caminho candidato em relação à base e confirme que o caminho relativo permanece dentro dela. Essa verificação lexical não contém symlinks do sistema de arquivos.
const filePath = path.join( BASE_DIR, userFilename ); // userFilename = "../../etc/passwd" // still escapes BASE_DIR
const base = path.resolve(BASE_DIR);
const resolved = path.resolve(base, userFilename);
const relative = path.relative(base, resolved);
if (
relative === '' ||
relative === '..' ||
relative.startsWith('..' + path.sep) ||
path.isAbsolute(relative)
) {
throw new Error("Invalid path");
}
Por que path.join() sozinho não ajuda
path.join() combina segmentos com o separador da plataforma e normaliza o resultado. A normalização não rejeita .., que é válido em muitos caminhos. Juntar ../../etc/passwd a uma base ainda pode produzir um caminho fora dela; join() não verifica contenção.
Perguntas frequentes
path.normalize() resolve segmentos .. e . na string, mas não verifica se o resultado está dentro de uma base permitida. Compare path.relative(base, resolved) e rejeite resultado vazio quando um arquivo é obrigatório, .., prefixo .. seguido de path.sep ou resultado relativo absoluto.
Não. path.resolve() e path.relative() comparam strings; não seguem symlinks do sistema de arquivos. Se um atacante puder criar ou substituir symlinks sob a base, valide o destino real e use operações que evitem uma corrida entre verificação e uso. Restrinja escrita na árvore quando possível.