Deadshot est un scanner Pull Request qui recherche l'introduction de secrets via des PR en faisant correspondre chaque ligne de différence avec un ensemble d'expressions secrètes connues.
Le service est responsable de :
Le service NE :
Deadshot est une application multi-conteneur Flask-Celery-Redis qui est installée en tant qu'application Github pour s'exécuter sur chaque Pull Request créée sur la branche principale d'un dépôt sur lequel l'application Github est installée.
Le conteneur Flask est le point d'entrée du service en exposant les routes API définies dans blueprints.py. Une fois qu'une charge utile de demande Pull est reçue sur la route API, le service transmet la charge utile à une file d'attente Redis pour que le conteneur Celery récupère et analyse le diff de la demande Pull. Une fois que le conteneur céleri a recherché les expressions régulières secrètes spécifiées, il commente les PR, Slack informe le canal de l'équipe de sécurité ou crée un ticket JIRA pour que l'équipe puisse assurer le suivi. L'application Github est configurée avec l'URL de l'API Flask et un secret partagé utilisé pour générer la somme de contrôle SHA de la charge utile.
Une façon de configurer l'URL de l'API consiste à déployer ce code sur un hôte et à attribuer un équilibreur de charge d'application à cet hôte.
Remarque : lors de la création de l'application, assurez-vous d'avoir un DNS prêt pour l'hôte sur lequel vous allez déployer des conteneurs Deadshot et une chaîne secrète sécurisée pour le secret du webhook.
Les administrateurs Github devront créer et installer une application Github sur Github avant d'exécuter ou de déployer l'application Deadshot. Pour en savoir plus sur la création d'une application Github, veuillez lire ce guide
Nom de l'application : deadshot (tout en minuscules. Ceci est important car le service utilise ce nom pour récupérer les commentaires précédents qu'il a faits sur un PR)
URL du webhook : http(s)://your-hosted-deadshot-dns/api/v1/deadshot-webhook
Pour tester cela localement, vous pouvez créer un point de terminaison ngrok pour alimenter la section webhook de votre application Github.
Pour que cette application fonctionne, votre application Github devra activer les autorisations et abonnements suivants sur la page des autorisations de l'application Github : Autorisations du référentiel :
Toutes les autres autorisations restent inchangées avec la valeur par défaut de Aucun accès.
Abonnez-vous aux événements :
Cliquez enfin sur « Créer une application GitHub ». Après la création réussie de l'application, suivez le lien « générer une clé privée » dans la section supérieure de la page Web de l'application.
Une fois la clé privée générée, stockez-la dans un emplacement sécurisé. Cette clé privée générée est l'une des données utilisées pour générer un jeton de session pour l'interaction avec l'application.
Après avoir généré la clé privée, installez l'application sur toutes les organisations que vous souhaitez surveiller.
Il s'agit d'une application multi-conteneurs conçue pour afficher les trois conteneurs (Flask, Celery, Redis) via /bin/run.sh, donc l'exécution de l'image Dockerfile devrait afficher l'intégralité de l'application.
Les trois variables ci-dessous sont des valeurs de chaîne unique fournies par l'utilisateur
Les variables d'environnement ci-dessous chargent le chemin d'accès aux fichiers contenant les informations d'identification. Chargez les valeurs clés du fichier json dans les fichiers disponibles ici avant d'exécuter l'application.
Remarque : Si vous ne déplacez pas l'emplacement des fichiers secrets JSON, vous n'avez pas besoin de mettre à jour les valeurs des trois variables d'environnement ci-dessus déjà présentes dans les Dockerfiles ou docker-compose.yaml.
Cette commande utilisera docker-compose.yaml pour afficher tous les conteneurs. Veuillez mettre à jour configuration/environment/localdev.env avec les valeurs pertinentes pour votre organisation avant d'exécuter la commande ci-dessous
make serve
Une fois que vous avez fait cela et que vous n'avez pas l'intention d'utiliser Dockerfile pour servir l'application, passez à la section « Server Healthcheck »
Il existe deux manières de créer et d'exécuter les Dockerfiles. Il y a quatre Dockerfiles présents dans le référentiel, dont trois sont utilisés pour générer une image individuelle pour chaque conteneur nécessaire au fonctionnement de ce service, et le quatrième est une configuration Dockerfile pour créer une image qui peut être utilisée soit pour afficher le Application Flask ou le travailleur de céleri en fonction de la valeur de la variable d'environnement DEADSHOT_RUN_MODE (api ou travailleur) fournie. Pour exécuter l'une des étapes ci-dessous, vous devez être présent dans le dossier racine du référentiel
Remarque : Assurez-vous d'avoir mis à jour les variables d'environnement dans les fichiers Dockerfile.api et Dockerfile.celery.
Il existe trois fichiers Docker pertinents pour cette étape. Dockerfile.api, Dockerfile.celery et 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> .
Les trois images créées au cours des étapes précédentes fonctionnent toutes sur des réseaux distincts, ce qui les empêche de se parler. Pour permettre les communications entre conteneurs, nous devons les ajouter à un réseau de conteneurs
docker network create deadshot-network
Exécutez les images à l'aide du réseau créé dans l'ordre suivant : Démarrez le conteneur Redis :
docker run --net deadshot-network --name redis deadshot-redis:<version>
Démarrer le récipient de céleri :
docker run --net deadshot-network deadshot-worker:<version>
Démarrez le conteneur API Flask :
docker run --net deadshot-network -p 9001:9001 deadshot-api:<version>
Pour créer une seule image Docker pour afficher l'API et le travailleur de céleri basé sur la variable d'environnement DEADSHOT_RUN_MODE
make build
Cette commande créera également l'image Redis nécessaire au service
Si l'image construite est exécutée avec la variable d'environnement DEADSHOT_RUN_MODE=api, elle fera apparaître l'application Flask. Si l'image est exécutée avec la variable d'environnement DEADSHOT_RUN_MODE=worker, le travailleur céleri sera lancé.
Maintenant que l'API est prête à recevoir des requêtes, la navigation vers http://localhost:9001/api/v1/heartbeat
dans un navigateur devrait renvoyer une réponse valide ou vous pouvez effectuer une boucle.
curl localhost:9001/api/v1/healthcheck
Les deux devraient afficher le message suivant : {"healthcheck": "ready"}
Si vous disposez d'une charge utile webhook de l'application Github pour votre demande d'extraction, vous pouvez exécuter la commande curl suivante localement pour tester votre application :
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
Si vous souhaitez que l'outil surveille d'autres types de secrets, ajoutez vos expressions régulières dans le fichier regex.json
Remarque : l'indicateur de vérification d'entropie vous permet de rechercher des résultats d'entropie élevée en plus de la correspondance d'expression régulière.
Pour le moment, Deadshot n'a été testé qu'avec Github Enterprise, mais devrait également fonctionner avec le cloud Github.