Deadshot é um scanner Pull Request que procura a introdução de segredos por meio de PRs, comparando cada linha diff com um conjunto de expressões secretas conhecidas.
O serviço é responsável por:
O serviço NÃO:
Deadshot é um aplicativo multicontêiner Flask-Celery-Redis que é instalado como um aplicativo Github para ser executado em cada solicitação pull criada no branch principal de um repositório no qual o aplicativo Github está instalado.
O contêiner Flask é o ponto de entrada para o serviço, expondo rotas de API definidas em blueprints.py. Depois que uma carga útil da solicitação pull é recebida na rota da API, o serviço encaminha a carga para uma fila Redis para o contêiner Celery coletar e verificar a diferença da solicitação pull. Depois que o contêiner de aipo verifica expressões regulares de segredos especificados, ele comenta os PRs, o Slack notifica o canal da equipe de segurança ou cria um ticket JIRA para a equipe acompanhar. O aplicativo Github é configurado com o URL da API Flask e um segredo compartilhado usado para gerar a soma de verificação SHA da carga útil.
Uma maneira de configurar o URL da API é implantando esse código em um host e atribuindo um balanceador de carga de aplicativo a esse host.
Observação: ao criar o aplicativo, certifique-se de ter um DNS pronto para o host no qual você implantará contêineres Deadshot e uma string secreta segura para o segredo do webhook.
Os administradores do Github precisariam criar e instalar um aplicativo Github no Github antes de executar ou implantar o aplicativo Deadshot. Para saber mais sobre como criar um aplicativo Github, leia este guia
Nome do aplicativo: deadshot (tudo em letras minúsculas. Isso é importante porque o serviço usa esse nome para buscar comentários anteriores feitos em um PR)
URL do webhook: http(s)://your-hosted-deadshot-dns/api/v1/deadshot-webhook
Para testar isso localmente, você pode criar um endpoint ngrok para alimentar a seção de webhook do seu aplicativo Github
Para que este aplicativo funcione, seu aplicativo Github terá que habilitar as seguintes permissões e assinaturas na página de permissões do aplicativo Github: Permissões de repositório:
Todas as outras permissões permanecem inalteradas com o valor padrão de Sem acesso
Inscreva-se em eventos:
Por fim, clique em “Criar aplicativo GitHub”. Após a criação bem-sucedida do aplicativo, siga o link “gerar uma chave privada” na seção superior da página da web do aplicativo
Depois que a chave privada for gerada, armazene-a em um local seguro. Essa chave privada gerada é um dos dados usados para gerar um token de sessão para interação do aplicativo.
Depois de gerar a chave privada, instale o aplicativo em todas as organizações que deseja monitorar.
Este é um aplicativo de vários contêineres projetado para abrir todos os três contêineres (Flask, Celery, Redis) por meio de /bin/run.sh, portanto, a execução da imagem Dockerfile deve exibir todo o aplicativo
As três variáveis abaixo são valores de string única fornecidos pelo usuário
As variáveis de ambiente abaixo carregam o caminho para os arquivos com credenciais. Carregue os valores-chave do arquivo json nos arquivos disponíveis aqui antes de executar o aplicativo.
Nota: Se você não mover o local dos arquivos secretos JSON, não será necessário atualizar os três valores de variáveis de ambiente acima já presentes nos Dockerfiles ou docker-compose.yaml
Este comando usará docker-compose.yaml para abrir todos os contêineres. Atualize configuration/environment/localdev.env com valores relevantes para sua organização antes de executar o comando abaixo
make serve
Depois de fazer isso e não pretender usar o Dockerfile para servir o aplicativo, vá para a seção “Server Healthcheck”
Existem duas maneiras de construir e executar os Dockerfiles. Existem quatro Dockerfiles presentes no repositório, três dos quais são usados para gerar uma imagem individual para cada contêiner necessário para que este serviço funcione, e o quarto é uma configuração do Dockerfile para criar uma imagem que pode ser usada para abrir o Aplicativo Flask ou aipo trabalhador dependendo do valor da variável de ambiente DEADSHOT_RUN_MODE (api ou trabalhador) fornecido Para executar qualquer uma das etapas abaixo você precisa estar presente na pasta raiz do repositório
Observação: certifique-se de ter atualizado as variáveis de ambiente nos arquivos Dockerfile.api e Dockerfile.celery
Existem três Dockerfiles relevantes para esta etapa. Dockerfile.api, Dockerfile.celery e Dockerfile.redis
docker build -f Dockerfile.api -t deadshot-api:<version> .
docker build -f Dockerfile.celery -t deadshot-worker:<version> .
docker build -f Dockerfile.redis -t deadshot-redis:<version> .
As três imagens construídas nas etapas anteriores funcionam todas em redes separadas, por isso não poderão se comunicar entre si. Para permitir comunicações entre contêineres, precisamos adicioná-los a uma rede de contêineres
docker network create deadshot-network
Execute as imagens usando a rede criada na seguinte ordem: Inicie o contêiner redis:
docker run --net deadshot-network --name redis deadshot-redis:<version>
Comece o recipiente de aipo:
docker run --net deadshot-network deadshot-worker:<version>
Inicie o contêiner da API Flask:
docker run --net deadshot-network -p 9001:9001 deadshot-api:<version>
Para construir uma única imagem docker para abrir a API e o trabalhador de aipo com base na variável de ambiente DEADSHOT_RUN_MODE
make build
Este comando também criará a imagem redis necessária para o serviço
Se a imagem construída for executada com a variável de ambiente DEADSHOT_RUN_MODE=api, ela abrirá o aplicativo Flask Se a imagem for executada com a variável de ambiente DEADSHOT_RUN_MODE=worker então o celery trabalhador será iniciado
Agora que a API está pronta para receber solicitações navegando para http://localhost:9001/api/v1/heartbeat
em um navegador deve retornar uma resposta válida ou você pode fazer um curl
curl localhost:9001/api/v1/healthcheck
Ambos devem mostrar a seguinte mensagem: {"healthcheck": "ready"}
Se você tiver uma carga webhook do aplicativo Github para sua solicitação pull, poderá executar o seguinte comando curl localmente para testar seu aplicativo:
curl -X POST -H " content-type: application/json " -H " X-GitHub-Enterprise-Host: github.mockcompany.com " -H " X-Hub-Signature: sha1=85df4936c6396c149be94144befab41168149840 " -H " X-GitHub-Event: pull_request " -d @tests/fixtures/good_pr.json http://localhost:9001/api/v1/deadshot-webhook
Se você deseja que a ferramenta monitore outros tipos de segredos, adicione suas expressões regulares no arquivo regex.json
Observação: o sinalizador de verificação de entropia permite procurar descobertas de alta entropia além da correspondência de expressão regular
No momento, Deadshot testou apenas com Github Enterprise, mas também deve funcionar com a nuvem Github.