
Laboratório de pesquisa em segurança: reprodução controlada do GHSA-3g6g-gq4r-xjm9 / CVE-2026-35580 (injeção de shell em entrada workflow_dispatch do GitHub Actions) contra um snapshot fixado de NationalSecurityAgency/emissary
Artefato de pesquisa automatizado — não é o projeto upstream.
Este repositório é um laboratório descartável construído por um harness automatizado para uma dissertação de mestrado na Université Laval sobre a reprodução de vulnerabilidades publicadas em workflows do GitHub Actions. É um snapshot verbatim de
NationalSecurityAgency/emissaryno commit898488b489615581ea66d17954742c8e4ffb0323(2026-01-09), redistribuído sob a licença do próprio projeto, cujo arquivo está incluído inalterado neste snapshot.O projeto upstream não está envolvido, nunca é alvo, e a vulnerabilidade estudada aqui já é pública. Cada segredo e variável neste repositório é um valor fictício gerado aleatoriamente — nenhuma credencial real está presente. Referências de ações e imagens de runners estão fixadas no que resolveram em 2026-01-09; veja
pinning.mdna saída do harness para cada alteração feita no snapshot.Perguntas ou objeções: [email protected]

Emissary é um motor de workflow orientado a dados baseado em P2P que executa em uma rede P2P heterogênea, possivelmente amplamente dispersa, de múltiplas camadas, de recursos computacionais. Os itinerários de workflow não são pré-planejados como em motores de workflow convencionais, mas são descobertos à medida que mais informações são descobertas sobre os dados. Normalmente não há interação do usuário em um workflow do Emissary; em vez disso, os dados são processados de forma orientada a objetivos até atingirem um estado de conclusão.
O Emissary é altamente configurável, mas nesta implementação base quase não faz nada. Espera-se que os usuários deste framework forneçam classes que estendam emissary.place.ServiceProviderPlace para realizar trabalho em payloads de emissary.core.IBaseDataObject.
Uma variedade de coisas pode ser feita e o workflow é gerenciado em estágios, por exemplo, STUDY, ID, COORDENAR, TRANSFORM, ANALYZE, IO, REVIEW.
As classes responsáveis por direcionar o workflow são o emissary.core.MobileAgent e classes derivadas dele, que gerenciam o caminho de um conjunto de objetos de payload relacionados através do workflow e o emissary.directory.DirectoryPlace que gerencia os serviços disponíveis, seu custo e qualidade e mantém a rede P2P conectada.
Leia o guia DEVELOPING.md para obter informações sobre a instalação dos componentes necessários, obtenção do código-fonte, compilação e execução do Emissary.
Execute mvn clean package para compilar, testar e empacotar o Emissary
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 9.132 s
[INFO] Finished at: 2022-01-10T22:31:05Z
[INFO] ------------------------------------------------------------------------
Há um script bash no Emissary que executa tudo. Ele está no diretório de nível superior do Emissary. O script executa a classe emissary.Emissary que possui vários comandos Picocli disponíveis para lidar com diferentes funções.
Se o script emissary for executado sem nenhum argumento, você obterá uma listagem de todos os subcomandos de configuração e uma breve descrição.
./emissary
Executar ./emissary help fornecerá a mesma saída que executar sem argumentos. Se você quiser ver informações mais
detalhadas sobre um comando, adicione o nome do comando após help. Por exemplo, para ver todos os
argumentos com descrições para o comando server, execute:
./emissary help server
O restante dos comandos possui argumentos (-b ou --projectBase) que podem ser definidos, mas devem corresponder ao PROJECT_BASE.
O diretório de configuração é padronizado para /config mas também pode ser passado com (-c ou --config). Ao executar a partir do checkout do git, você deve usar target como projectBase. Sinta-se à vontade para modificar os arquivos de configuração em target/config antes de iniciar.
O registro de logs é tratado pelo logback. Você pode apontar para um arquivo personalizado com o argumento --logbackConfig.
Veja o help -c para cada comando para obter mais informações.
Este comando iniciará um servidor Emissary e inicializará todos os lugares, um lugar de coleta (pickup place) e filtros de entrega que estão configurados. Ele iniciará em modo standalone se -m ou --mode não for especificado. Por padrão, o número de MobileAgents é calculado com base nas especificações da máquina. Em computadores modernos, isso pode ser alto. Você pode controlar o número de agentes com -a ou --agents. Aqui está um exemplo de execução.
./emissary server -a 2
Sem configuração adicional, ele iniciará em http://localhost:8001. Se você navegar para essa url, precisará inserir o nome de usuário e a senha definidos em target/config/jetty-users.properties, que são emissary e emissary123.
O PickUpPlace padrão está configurado para ler arquivos de target/data/InputData. Se você copiar arquivos para esse diretório, verá o Emissary processá-los. Tenha em mente que apenas toUpper e toLower estão configurados, então a saída não será muito interessante.
Parar o serviço de aceitar trabalho
./emissary server --pause
Permitir que um serviço pausado aceite trabalho
./emissary server --unpause
Invalidar serviços que são atualizáveis. Esta é uma atualização "leve" que é uma abordagem sem tempo de inatividade que invalida um ServiceProviderRefreshablePlace. Quando o lugar é então puxado do DirectoryPlace, o lugar é recriado usando as mesmas chaves para DirectoryPlace e Namespace, mas o configurador é recarregado e o lugar pode recarregar um subconjunto de suas configurações.
./emissary server --invalidate
Forçar a atualização dos serviços. Esta é uma atualização "rígida", o servidor é pausado e há uma espera para que os MobileAgents se esvaziem. Uma vez que o servidor está totalmente ocioso, todas as chaves existentes do ServiceProviderRefreshablePlace são removidas do DirectoryPlace e Namespace, e os lugares são totalmente recriados. Isso permite alterações em nomes de serviços, proxies, listas de negação, etc. O servidor é então retomado para continuar o processamento. Qualquer falha na atualização colocaria o servidor em um estado ruim, então o servidor é encerrado.
./emissary server --refresh
Encerrar o serviço
./emissary server --stop
Forçar o encerramento do serviço
./emissary server --kill
O comando agents mostra o número de MobileAgents para o host configurado e o que esses agentes estão fazendo. Por padrão, a porta é 9001, mas você pode usar -p ou --port para alterá-la. Supondo que você esteja executando na porta 8001 do comando server acima, tente:
./emissary agents -p 8001
Pool é uma visão condensada dos agentes para um nó. Ele também usa a porta 9001 por padrão. Para executar para o servidor standalone iniciado acima, execute
./emissary pool -p 8001
Este comando é mais útil para um cluster, pois fornece uma visão mais digerível de cada nó.
O comando Env requer que um servidor esteja em execução. Ele perguntará ao servidor por alguns valores de configuração, como PROJECT_BASE e BIN_DIR. Sem argumentos, ele despejará uma resposta json não formatada.
./emissary env
Mas você também pode despejar uma resposta adequada para uso em bash.
./emissary env --bashable
Iniciar o servidor Emissary na verdade chama este endpoint e despeja $PROJECT_BASE}/env.sh
com as variáveis configuradas. Isso é feito para que scripts de shell possam source $PROJECT_BASE}/env.sh
e então ter essas variáveis disponíveis sem precisar se preocupar em configurá-las em outro lugar.
O comando config permite que você veja a configuração efetiva para um lugar/serviço/classe especificado. Como o Emissary usa
flavors, este comando mostrará a configuração resultante de uma classe após todos os flavors terem sido aplicados. Este comando pode
ser usado para conectar a um nó Emissary em execução especificando -h para host (padrão é localhost) e -p para
a porta (padrão é 8001). Para conectar a um Emissary em execução local na porta 8001, qualquer um dos seguintes comandos funcionará:
./emissary config --place emissary.place.sample.ToLowerPlace
./emissary config --place emissary.place.sample.ToLowerPlace -h localhost -p 8001
Opcionalmente, você pode especificar o modo offline usando --offline para usar os arquivos de configuração especificados em seu
CONFIG_DIR local:
./emissary config --place emissary.place.sample.ToLowerPlace --offline
No modo offline, você pode fornecer flavors para ver as diferenças nas configurações:
./emissary config --place emissary.place.sample.ToLowerPlace --offline --flavor STANDALONE,TESTING
Estes são úteis para ver a configuração efetiva, mas também podemos executar em um modo verboso para
ver todos os arquivos de configuração junto com a saída final. Isso é controlado com o
sinalizador --detailed:
./emissary config --place emissary.place.sample.ToLowerPlace --detailed
ou no modo offline:
./emissary config --place emissary.place.sample.ToLowerPlace --offline --detailed
O Emissary é divertido em standalone, mas executar em cluster é mais apropriado para trabalho real. A maneira de executar em cluster é semelhante ao standalone, mas você precisa de -m cluster para dizer ao nó para conectar a outros nós. Em modo cluster, o Emissary também iniciará o PickUpClient em vez do PickUpPlace, então você precisará iniciar um feeder.
Veja o target/config/peers.cfg para ver os peers de rendezvous. Neste caso, há 3. Nós executando nas portas 8001 e 9001 são apenas nós Emissary. O nó executando na porta 7001 é o feeder. Então vamos iniciar 8001 e 9001 em dois terminais diferentes.
./emissary server -a 2 -m cluster
./emissary server -a 2 -m cluster -p 9001
Como esses nós conhecem as portas 8001, 9001 e 7001, você verá erros nos logs enquanto eles continuam tentando conectar.
Observe que, em implantações do mundo real, não executamos múltiplos processos Emissary no mesmo nó. Você pode configurar o hostname com -h.
Com os nós iniciados nas portas 8001 e 9001, precisamos iniciar o feeder. O comando feed usa a porta 7001 por padrão, mas precisamos configurar um diretório do qual o feeder lerá. Arquivos colocados nesse diretório estarão disponíveis para os nós trabalhadores pegarem e o trabalho deve ser distribuído entre o cluster. Inicie o feed com
mkdir ~/Desktop/feed1
./emissary feed -i ~/Desktop/feed1/
Você deve conseguir acessar http://localhost:8001, http://localhost:9001 e http://localhost:7001 no navegador e ver os lugares configurados. Coloque alguns arquivos em ~/Desktop/feed1 e veja os 2 nós processá-los. Pode levar um minuto para eles começarem a processar.
Agentes no modo cluster novamente mostra detalhes sobre os mobileAgents. Ele começa no nó que você configura (localhost:9001 por padrão), então chama todos os nós que conhece e obtém as mesmas informações. Execute com:
./emissary agents --cluster
Pool no modo cluster também faz o mesmo que pool em standalone. Ele começa no nó (localhost:9001) por padrão então vai para todos os nós que conhece e agrega uma visão condensada do cluster. Execute com
./emissary pool --cluster
A topologia fala com o nó configurado (localhost:8001 por padrão) e fala com cada nó que conhece. A resposta é o que todos esses nós conhecem, então você pode construir uma topologia de rede do seu cluster. Execute com
./emissary topology
O keystore e a senha do keystore estão no arquivo emissary.client.EmissaryClient-SSL.cfg. Incluído e configurado por padrão está um keystore de exemplo que você pode usar para testar esta funcionalidade. Não recomendamos usar o keystore de exemplo em ambientes de produção. Para usar seu próprio keystore, altere os valores de configuração no arquivo emissary.client.EmissaryClient-SSL.cfg.
Standalone
./emissary server -p 8443 --ssl --disableSniHostCheck
Cluster
./emissary server -p 8443 --ssl --disableSniHostCheck --mode cluster
./emissary server -p 9443 --ssl --disableSniHostCheck --mode cluster
mkdir ~/Desktop/feed1
./emissary feed -p 7443 --ssl --disableSniHostCheck -i ~/Desktop/feed1/
Se você tiver alguma dúvida ou preocupação sobre este projeto, pode nos contatar em: [email protected]
Para perguntas de segurança e relato de vulnerabilidades, consulte SECURITY.md