Resolução do Problema de Certificado SELF_SIGNED_CERT_IN_CHAIN em Ambientes Corporativos
O problema começou a ocorrer repentinamente em todos os projetos, com a mensagem de erro SELF_SIGNED_CERT_IN_CHAIN ao executar o comando npm install. Inicialmente, pensou-se que o problema estivesse relacionado a um repositório específico, ao tempo de inatividade do registro do npm ou a um cache corrompido. No entanto, após investigação, descobriu-se que o problema ocorria em todos os projetos e estava relacionado à configuração de rede corporativa, que utiliza o Zscaler SSL Inspection para interceptar o tráfego HTTPS de saída.
A interceptação TLS (MITM) realizada pelo Zscaler altera a cadeia de certificados, substituindo o certificado original do registro do npm por um certificado re-assinado pelo Zscaler. Em vez da cadeia de certificados normal, que inclui o certificado do registro do npm e o certificado de autoridade de certificação pública, a cadeia de certificados se torna: registry.npmjs.org (re-assinado) → Zscaler Intermediate → Internal Enterprise CA → Enterprise Root CA. Essa alteração na cadeia de certificados é comum em ambientes corporativos.
Causa do Problema
A causa do problema foi a mudança no comportamento de validação de certificados do Node.js, que passou a ser mais estrito a partir da versão 22. As versões anteriores do Node.js eram mais tolerantes em relação a cadeias de certificados incompletas. Com a versão 22, o Node.js passou a usar o OpenSSL 3.x, que exige uma validação de certificado mais rigorosa e não reconstrói automaticamente as cadeias de certificados intermediários incompletas. Portanto, fornecer apenas o certificado de autoridade de certificação raiz da empresa não é mais suficiente.
Para diagnosticar o problema, foi realizada uma verificação da cadeia de certificados live, utilizando o comando openssl s_client -showcerts -connect registry.npmjs.org:443 -servername registry.npmjs.org < /dev/null > /tmp/npm-chain.txt. Em seguida, foi realizada uma contagem dos certificados presentes na cadeia, utilizando o comando grep -c "BEGIN CERTIFICATE" /tmp/npm-chain.txt, que resultou em 5 certificados. Isso indicou que a cadeia de certificados estava incompleta.
Solução
A solução para o problema consistiu em fornecer a cadeia de certificados completa para o Node.js. Isso foi realizado em três etapas:
Etapa 1: Dividir os certificados em arquivos separados, utilizando o comando awk '/BEGIN CERTIFICATE/{i++} {print > ("/c/certs/npm-chain-" i ".pem")}' /tmp/npm-chain.txt.
Etapa 2: Combinar os certificados em um arquivo único, utilizando o comando cat /c/certs/npm-chain-1.pem /c/certs/npm-chain-2.pem /c/certs/npm-chain-3.pem /c/certs/npm-chain-4.pem /c/certs/npm-chain-5.pem > /c/certs/npm-full-chain.pem.
Etapa 3: Configurar o npm e o Node.js para utilizar a cadeia de certificados completa, utilizando os comandos npm config set cafile "C:\\certs\\npm-full-chain.pem" e export NODE_EXTRA_CA_CERTS=/c/certs/npm-full-chain.pem, seguidos de npm cache clean --force e npm install.
Essa solução funcionou porque o Node.js valida as cadeias de certificados de forma estrita, exigindo que a cadeia completa seja fornecida para validar a confiança. Se alguma parte da cadeia estiver faltando, o erro SELF_SIGNED_CERT_IN_CHAIN ocorre.
Além disso, foi observado que os navegadores funcionam corretamente porque utilizam o repositório de certificados do Windows, enquanto o Node.js não utiliza por padrão. Isso explica por que os navegadores não apresentam o mesmo problema.
Em resumo, a solução para o problema de certificado SELF_SIGNED_CERT_IN_CHAIN em ambientes corporativos consiste em fornecer a cadeia de certificados completa para o Node.js, utilizando as etapas descritas acima. Isso garante que a confiança seja validada corretamente e o problema seja resolvido.
Referência técnica: dev.to. Curadoria e Insights: Redação Developers.