Segurança
A sua aplicação é de baixo risco. O seu pipeline de build não é.
Se o seu software é interno, de nicho ou pouco entusiasmante, é razoável colocar a segurança no fim da lista. Os ataques à cadeia de abastecimento não querem saber do que a sua aplicação faz. Visam o pipeline e os pacotes que todas as aplicações partilham.
Atualizado a
O raciocínio é válido, até certo ponto
Ouvimo-lo muitas vezes, e costuma vir de um ponto de vista sensato. A aplicação é um dashboard interno, um pipeline de dados ou um pequeno serviço com meia dúzia de utilizadores. Não contém nada que um atacante queira. O orçamento de segurança vai primeiro para o produto voltado para os clientes.
Essa lógica é válida para a aplicação. Não é válida para a forma como a aplicação é construída. Todas as equipas, seja o que for que distribuam, têm um pipeline de CI com credenciais e uma árvore de dependências que não escreveram. Vale a pena atacá-los porque são partilhados, e um comprometimento aí chega a tudo o resto a que essas credenciais dão acesso: os seus registos de pacotes, as suas contas cloud e os seus outros repositórios.
Ataques que não quiseram saber do que a aplicação fazia
Nenhum destes incidentes visou um tipo específico de aplicação. Cada um chegou às equipas através de uma ferramenta ou pacote que usavam para construir software.
tj-actions/changed-files, 2025
Uma GitHub Action amplamente usada para detetar ficheiros alterados foi comprometida. Segundo a CISA, as versões maliciosas estiveram disponíveis entre 12 e 15 de março de 2025, e o comprometimento expôs segredos, incluindo chaves de acesso, tokens de acesso pessoal do GitHub, tokens npm e chaves RSA privadas. A Wiz reportou que o código fazia um dump da memória do runner de CI, pelo que, em repositórios públicos, os segredos acabaram nos registos dos workflows. Os workflows que referenciavam a action por uma tag de versão executaram o código malicioso, fosse qual fosse o conteúdo do repositório.
Worm npm Shai-Hulud, 2025
Em setembro de 2025, a CISA alertou para um worm autorreplicante que tinha comprometido mais de 500 pacotes npm. Recolheu tokens de acesso pessoal do GitHub e chaves de API cloud para AWS, Google Cloud e Azure. A Unit 42 da Palo Alto Networks descreveu como usava tokens npm roubados para publicar versões infetadas dos outros pacotes da vítima, e como uma vaga posterior era executada durante a pré-instalação, o que alargou o seu alcance aos pipelines de CI/CD.
Shai-Hulud and other supply chain attacks
Como o worm do npm Shai-Hulud roubou credenciais durante a instalação e as usou para publicar mais pacotes comprometidos, com os ataques anteriores a que dá seguimento.
Petteri Pulkkinen e Erika Marttinen em Kubernetes Community Days Helsinki 2026, de 4:30 a 7:57 de SBOMbastic: Getting Ready for Upcoming EU Cybersecurity Regulation in Software Supply Chains.
Codecov Bash Uploader, 2021
Um atacante extraiu uma credencial através de um erro no processo de build da imagem Docker da Codecov e modificou o script Bash Uploader que muitas equipas executavam na CI. De 31 de janeiro a 1 de abril de 2021, o script alterado podia enviar a terceiros variáveis de ambiente, incluindo credenciais, tokens e chaves disponíveis no ambiente de CI. Foi descoberto quando um cliente reparou que o checksum do script não correspondia.
xz utils, 2024
Foi incorporado código malicioso nas versões 5.6.0 e 5.6.1 do XZ Utils, uma biblioteca de compressão de dados que pode estar presente em distribuições Linux. A CISA aconselhou a voltar a uma versão não comprometida, como a 5.4.6, e a procurar atividade maliciosa. Uma biblioteca de compressão é das dependências menos glamorosas que existem e, ainda assim, foi um alvo.
event-stream, 2018
Uma pessoa que se fez passar por um responsável de manutenção prestável assumiu o controlo do popular pacote npm event-stream e acrescentou uma dependência maliciosa, flatmap-stream, na versão 3.3.6. A equipa do npm reportou que o payload visava uma aplicação específica, a carteira de bitcoin Copay. Todos os outros que instalaram o event-stream receberam igualmente o código malicioso.
O que estes incidentes têm em comum
- Aconteceram durante o build ou a instalação. O código malicioso foi executado em máquinas de programadores e runners de CI, não na aplicação em produção.
- Procuraram credenciais. Os tokens e as chaves no pipeline eram o prémio, porque abrem portas para além do projeto em construção.
- Chegaram através de nomes de confiança. Uma action conhecida, um pacote conhecido, um script conhecido. Ninguém escolheu instalar malware.
- A primeira pergunta depois foi a mesma. Algum dos nossos builds obteve a versão comprometida, e a que é que podia chegar? As equipas sem um registo do que cada build usou tiveram de o reconstruir.
Como é o esforço mínimo
Não precisa de uma equipa de segurança para cobrir o básico. A maior parte dos conselhos do GitHub e da CISA cabe numa lista curta:
- Fixe as GitHub Actions de terceiros num SHA de commit completo em vez de numa tag, para que uma tag movida não possa alterar o que é executado.
- Faça commit dos lockfiles e fixe as dependências em versões comprovadamente seguras.
- Dê aos tokens de CI as permissões mais restritas que funcionem e faça a sua rotação quando um incidente afetar algo que utiliza.
- Exija autenticação multifator resistente a phishing nas contas de programadores e de publicação.
- Mantenha um registo do que cada build instalou, para poder responder a "fomos afetados?" com dados e não de memória.
Os quatro primeiros são configuração. O quinto é o que a maioria das pequenas equipas ignora, porque exige ferramentas.
Onde entra o CRACI com pouco esforço
O CRACI trata do registo e acrescenta uma fronteira de rede, sem lhe pedir que altere a sua aplicação ou os seus workflows.
- Uma linha por job. Altere
runs-onparacraci. Os seus workflows de GitHub Actions ficam como estão, e as execuções continuam a aparecer no GitHub. - Uma SBOM de cada build. O CRACI regista os pacotes que cada job realmente obtém, incluindo pacotes restaurados de caches, e exporta o resultado em CycloneDX ou SPDX.
- Um traço de rede por job. Quando um incidente é anunciado, pode verificar que builds obtiveram o pacote afetado e a que destinos se ligou cada job.
- Uma política de egress que pode passar para negação por predefinição. Permita as fontes de pacotes de que um job precisa, e um passo comprometido terá menos sítios para onde enviar o que encontrar. As políticas falham em modo fechado, e as violações acionam um alerta.
- Reavaliação contínua. As SBOM monitorizadas são novamente verificadas à medida que são publicadas novas vulnerabilidades, para que um build antigo não continue "limpo" só porque ninguém olhou.
Sejamos claros quanto aos limites: uma política de egress não teria impedido o comprometimento do tj-actions de imprimir segredos num registo público, e nenhuma ferramenta anula um token divulgado. A fixação e a rotação continuam a ser importantes. O que o CRACI muda é a rapidez com que consegue dizer se esteve exposto, e até onde pode chegar um passo comprometido.
Pôr um primeiro workflow a funcionar implica instalar a GitHub App e alterar uma linha para runs-on: craci.
Quanto custa
O CRACI cobra apenas os minutos de build: $0.002 por vCPU-minuto ($0.004 para um runner predefinido de 2 vCPU), medido ao segundo, sem mensalidade e sem custos por SBOM. Consulte preços para os termos completos. As startups elegíveis podem candidatar-se ao programa para startups para um mínimo de 100k minutos de build gratuitos e integração acompanhada.
Se vende software na UE, vale também a pena verificar se o Cyber Resilience Act se aplica a si. O nosso guia do CRA explica o âmbito e os prazos.
Veja o que o seu build realmente obtém
Marque uma demo e execute um dos seus workflows no CRACI. Obtém uma SBOM e um traço de rede do job, sem alterar a sua aplicação.
Marcar demo