Contournement de la protection des branches
Verrouillez la conduite principale avant que quelqu'un ne la pousse de force.
Qu'est-ce que Contournement de la protection des branches?
Une branche par défaut sans protection accepte tout ce qui lui est envoyé. Toute personne disposant d'un accès push peut s'engager directement dans le push principal ou forcer son historique. Les révisions et les vérifications de statut ne fonctionnent que si quelque chose force des changements à les modifier. Vous passerez directement au principal avec les informations d'identification d'un contributeur hameçonné, puis forcerez l'historique et verrez CI être ignoré. Vous ajouterez une protection de branche : nécessitez une demande d'extraction, des réviseurs, des vérifications réussies et aucune poussée forcée, avec le paramètre include-administrators activé, car une règle que les comptes privilégiés peuvent contourner n'est pas un contrôle.
Ce que vous apprendrez dans Contournement de la protection des branches
- Reconnaître ce qu'une branche par défaut non protégée permet : des poussées directes et des poussées forcées qui réécrivent l'historique et contournent l'examen des demandes d'extraction et les vérifications de l'état des CI
- Découvrez comment un seul compte de contributeur compromis peut transmettre du code non révisé directement en production lors de la fusion avec le déploiement automatique de la branche par défaut.
- Comprendre pourquoi une poussée forcée vers une branche partagée est dangereuse, car elle réécrit l'historique que d'autres ont examiné et construit et peut effacer les validations sans enregistrement
- Appliquer des règles de protection de branche qui nécessitent une demande d'extraction, des réviseurs requis et des contrôles de statut réussis et qui bloquent les poussées forcées sur la branche par défaut
- Activez l'option include-administrators afin que la règle ne puisse pas être contournée par les comptes privilégiés, ce qui rend le contrôle exécutoire pour tout le monde.
Contournement de la protection des branches — Étapes de la formation
-
Un siège de contributeur volé
Aujourd'hui, Bob cible Riftwell, une société de logiciels de logistique. Il a hameçonné les informations d'identification d'un contributeur pour le référentiel dispatch-api et souhaite que son propre code s'exécute en production, sans qu'une seule personne ne l'examine au préalable. Il commence par ouvrir le référentiel vers lequel le compte volé peut être transféré.
-
Rien ne garde le principal
Le tableau d'état du référentiel indique à Bob tout ce dont il a besoin. La branche par défaut est principale, sa protection de branche n'en lit aucune et chaque poussée vers main est déployée directement en production. En l'absence de règles sur la branche, il peut y accéder directement et forcer son historique, ainsi que tout ce qui atterrit en production par lui-même.
-
Cloner le référentiel
Bob clone le référentiel localement avec le compte volé, afin de pouvoir réécrire son historique et créer ses modifications avant de le repousser vers le compte principal.
-
Rembobiner au-delà de la validation d'audit
Le commit examiné le plus récent sur la journalisation d'audit principale ajoutée au service d'authentification, exactement l'enregistrement qui signalerait le changement que Bob est sur le point d'apporter. Il commence donc par rembobiner son commit principal local, abandonnant complètement ce commit de journalisation d'audit. Sur une branche protégée, cela serait impossible. Ici, il s'agit d'une seule commande.
-
Poussée forcée sur le principal
Bob pousse son histoire rembobinée directement au principal. Étant donné que la branche n'a aucune protection, le serveur l'accepte et la validation de journalisation d'audit examinée disparaît de la branche partagée, comme si elle n'avait jamais été fusionnée. Tous les autres utilisateurs qui tirent le principal perdront désormais également ce commit en silence. C’est ce que fait une poussée forcée vers une branche partagée : elle réécrit l’histoire que d’autres personnes ont déjà examinée et sur laquelle ils se sont appuyés.
-
Ouvrez le middleware d'authentification
Maintenant, Bob ajoute son propre code. Il ouvre le middleware d'authentification, le fichier par lequel passe chaque requête adressée à l'API de répartition, et le lit proprement avant de le toucher.
-
Plantez le contournement
Bob ajoute un court bloc en haut du middleware. Cela se lit comme une cale de compatibilité pour un relais existant, mais toute demande portant une valeur d'en-tête fixe est transmise en tant qu'administrateur, sans jeton ni vérification de signature. Une porte dérobée sur chaque itinéraire protégé par le service, déguisée en plomberie inoffensive.
-
Enterré à la vue de tous
Le bloc ajouté se situe parmi les middlewares ordinaires et se lit comme quelque chose qu'un ingénieur backend pourrait écrire. Rien dans cela ne semble alarmant à première vue, c'est exactement pourquoi il survivrait à un examen rapide, si jamais un examen avait lieu.
-
S'engager sur le principal
Bob valide le changement directement sur main avec un message concernant un délai d'attente du relais, rien qui mentionne l'authentification. Il n'y a pas de branche ni de pull request ; le commit est déjà assis sur la branche par défaut de son clone.
-
Passez directement à la production
Bob pousse le commit directement vers le main. Il n'y a aucune pull request à ouvrir, aucun réviseur pour l'approuver et aucune vérification de statut à réussir. La branche l'accepte, et parce qu'elle fusionne avec le déploiement automatique principal, sa porte dérobée est en production quelques secondes plus tard.
Couverture des référentiels de sécurité
CWE
- CWE-285 Improper Authorization
- CWE-862 Missing Authorization
MITRE ATT&CK
- T1195.002 Supply Chain Compromise: Compromise Software Supply Chain
CIS Controls
- CIS 16 Application Software Security
NIST CSF
- PR.AT-02 Individuals in specialized roles are provided with awareness and training so that they possess the knowledge and skills to perform relevant tasks with cybersecurity risks in mind
- PR.PS Platform Security