Retour au blog
CVEGitLabsupply chainDevOps

RCE GitLab via Oj : une chaîne de corruption mémoire cachée dans un patch non-sécurité

Publié le 2026-07-257 min de lectureCleanIssue

> En bref : Une chaîne de RCE GitLab bâtie sur deux bugs de corruption mémoire dans Oj (un parser JSON Ruby) permet à tout utilisateur authentifié capable de pousser dans un projet de lancer des commandes en tant que git sur GitLab auto-hébergé. Corrigé dans 18.10.8, 18.11.5 et 19.0.2 — mais le correctif du 10 juin a été classé en bug fixes, pas en sécurité, sans CVE. depthfirst a publié un PoC fonctionnel le 24 juillet.

Pourquoi ça vous concerne

GitLab, c'est l'endroit où vivent votre code source, vos secrets CI/CD et vos deploy keys. Une compromission de GitLab auto-hébergé est un incident supply chain : l'attaquant récupère votre code et votre pipeline en un seul mouvement. Si vous auto-hébergez GitLab pour des raisons de souveraineté ou de coût (beaucoup d'éditeurs SaaS français le font), cette chaîne atterrit directement sur votre infrastructure.

Le détail le plus gênant n'est pas le bug en lui-même — c'est que le correctif est sorti six semaines avant le PoC, et la plupart des opérateurs n'ont jamais su qu'il avait un enjeu sécurité. GitLab a listé le bump Oj 3.17.3 en bug fixes. Pas de CVE, pas de CVSS, pas d'advisory. Les équipes qui trient les releases selon la table sécurité n'avaient aucun signal pour monter de version en urgence.

La chaîne en termes simples

Le renderer de notebooks de GitLab (ipynbdiff) passe le JSON .ipynb contrôlé par le dépôt à Oj::Parser.usual.parse dans un worker Puma longue durée. Deux bugs Oj font fonctionner la chaîne :

  • Une écriture au-delà d'une stack de nesting fixe de 1 024 octets qui finit par contrôler le callback start du parser.
  • Une troncature d'une clé d'objet de 65 565 octets en un champ signé 16 bits de 29 octets qui renvoie un pointeur heap vivant — que GitLab rend dans le diff de commit.
  • L'attaquant commit un notebook Jupyter forgé et ouvre son diff de commit. Ça leak un pointeur heap. En répétant assez de fois pour localiser libc en mémoire, deux notebooks supplémentaires déclenchent le payload en pointant le callback vers system(). Pas de droits admin, pas d'accès CI/runner, pas d'interaction victime, pas d'accès au projet d'un autre.

    Les versions affectées et le piège Helm

    Tous les tiers sont affectés, CE et EE, Free jusqu'à Ultimate :

  • GitLab 15.2.0 à 18.10.7 → correctif en 18.10.8
  • GitLab 18.11.0 à 18.11.4 → correctif en 18.11.5
  • GitLab 19.0.0 à 19.0.1 → correctif en 19.0.2
  • gem Oj 3.13.0 à 3.17.1 → correctif en 3.17.3
  • Le piège : si vous déployez GitLab via Helm ou l'Operator, vérifiez la version GitLab dans l'image Webservice qui fait tourner Puma, pas la version du chart ou de l'Operator. Tout ce qui est en 15.2 à 18.9 n'a pas de backport — ces lignes sont hors des trains de patch sécurité-maintenus par GitLab, donc ces installs doivent passer à une release supportée.

    Ce qu'il faut faire

  • Monter en 18.10.8, 18.11.5 ou 19.0.2 selon votre train. Il n'existe pas de workaround configurable-only documenté que GitLab ou depthfirst endosseraient.
  • Auditer qui a le droit de push. Tant que vous n'êtes pas à jour, la chaîne n'a besoin que d'un utilisateur authentifié avec droit de push sur n'importe quel projet. Resserrez cette surface, surtout les contributeurs externes.
  • Revoir les logs d'accès à la recherche de vues de diff de notebooks et de commits inhabituels antérieurs à la mise à jour — la phase de recherche mémoire prend 5 à 10 minutes sur une install fraîche à deux workers, donc le sondage laisse des traces.
  • Rotater les secrets qui vivaient dans l'instance GitLab après une exposition suspectée : tokens CI/CD, deploy keys, tokens d'enregistrement de runners, tout ce qui est dans les CI variables. Les commandes lancées en tant que git atteignent le code source, les secrets Rails, les identifiants de service et les données CI/CD.
  • La leçon plus large : les correctifs sécurité qui n'en ont pas l'air

    Le takeaway le plus important pour une équipe ops est procédural. Tous les correctifs sécurité ne sont pas publiés comme tels. La revue Oj plus large de depthfirst a produit neuf autres advisories CVE, aucun n'est cette chaîne. Le correctif GitLab est passé par HackerOne mais a été classé en bug fix dans les release notes. Votre process de patch ne peut pas se reposer uniquement sur la table « security fixes » — il doit trier les bumps de dépendances sur les parsers sécurité-sensibles (Oj, libxml2, Jackson, Fastjson) comme si c'étaient des CVE même quand aucune CVE n'est attachée. C'est comme ça que vous auriez attrapé ça le 10 juin plutôt que le 24 juillet.

    Vous éditez un logiciel RH, paie ou recrutement ? CleanIssue réalise des audits de sécurité pour SaaS RH en conditions réelles, sans accès au code. Pour une première lecture de votre exposition, commencez par une revue externe de votre application.

    Besoin d'une revue externe de votre SaaS RH ?

    Expliquez votre produit, votre stack et votre contexte client. Nous revenons vers vous avec le bon niveau de revue.

    Parler de votre audit