# GitLab : quand compiler une regex devient une porte vers le serveur

> Quatre CVE GitLab révèlent des corruptions mémoire dans Onigmo, le moteur de regex de Ruby. Chemin d’entrée, portée, correctifs et méthode d’analyse.

Publié le: 2026-11-04  
Canonical: https://rootzero.eu/research/gitlab-ruby-regexp-rce-2026/

**Correctifs GitLab : 23 septembre, 12 et 21 octobre 2026. Analyse rédigée le 4 novembre 2026.** Le cas le plus récent, [CVE-2026-110264](https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-5-1-released/), est noté 10,0 par GitLab. Un utilisateur non authentifié pouvait, sous certaines conditions, conduire le serveur à compiler une expression régulière spécialement conçue ; un débordement d’entier dans le moteur Ruby Onigmo pouvait aboutir à une exécution de code. Le même moteur est au centre de trois autres CVE traitées dans les semaines précédentes : [CVE-2026-89078, CVE-2026-93577 et CVE-2026-97229](https://www.ruby-lang.org/en/news/2026/10/23/regexp-fixes-for-gitlab-cves/).

Une regex ressemble à du texte, mais sa compilation produit des structures natives : instructions, tables de groupes, compteurs de répétition et offsets. Si un entier utilisé pour dimensionner ou indexer ces structures déborde, les écritures suivantes peuvent sortir de la zone prévue. C’est la frontière critique. La RCE ne vient pas du fait qu’une regex « exécute du code » par conception ; elle vient de la **corruption mémoire du compilateur** appelé avec une entrée contrôlée.

## Où le texte de l’utilisateur rencontre du code natif

[Ruby](https://www.ruby-lang.org/en/news/2026/10/23/regexp-fixes-for-gitlab-cves/) explique que GitLab compile des motifs provenant de ses utilisateurs, notamment des expressions de configuration CI, avec `Regexp.new`. Les quatre CVE correspondent à trois familles de défauts dans Onigmo : double libération si l’analyse échoue après une alternance, débordement de la taille du motif compilé, et débordement d’identifiants internes quand un motif contient de nombreuses répétitions. GitLab a distribué des Ruby corrigés dans ses propres paquets avant que Ruby publie ses versions générales.

Pour CVE-2026-110264, la description publique associe des répétitions à un dépassement d’entier dans les identifiants du compilateur. Elle ne publie pas de chaîne d’exploitation complète, ni le chemin exact de requête anonyme permettant d’atteindre le compilateur. Il faut donc garder deux niveaux de preuve séparés : GitLab **confirme** une possibilité de RCE non authentifiée dans certaines conditions ; le mécanisme précis d’un exploit HTTP reproductible n’est pas documenté dans l’avis public. Donner un exemple de requête ou un payload prétendument fonctionnel serait inventer la partie absente du dossier.

## Pourquoi quatre numéros plutôt qu’un seul

Les CVE ne désignent pas quatre syntaxes d’un même payload. Elles séparent les causes racines et les chemins d’accès. Ruby associe [89078](https://www.ruby-lang.org/en/news/2026/10/23/regexp-fixes-for-gitlab-cves/) à une double libération, [93577 et 97229](https://www.ruby-lang.org/en/news/2026/10/23/regexp-fixes-for-gitlab-cves/) à un débordement de taille, et [110264](https://www.ruby-lang.org/en/news/2026/10/23/regexp-fixes-for-gitlab-cves/) aux identifiants de répétition. Un même défaut de la bibliothèque peut être signalé dans plusieurs contextes GitLab ; inversement, corriger un compteur ne corrige pas les autres. Un scan qui cherche seulement la CVE la plus médiatisée sous-estime donc le travail de mise à jour.

La disponibilité dépend aussi du mode d’installation. Le [bulletin GitLab du 21 octobre](https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-5-1-released/) fournit les versions GitLab corrigées : 18.11.13, 19.0.10, 19.1.9, 19.2.9, 19.3.6, 19.4.3 et 19.5.1. Les installations officielles incluent le Ruby corrigé. Une installation compilée avec son **propre** runtime doit également passer à Ruby 3.3.13, 3.4.12 ou 4.0.9 au minimum. Mettre à jour GitLab seul sur ce dernier type d’installation laisse la bibliothèque vulnérable dans le processus.

## Comment découvrir ce type de faille

La recherche commence par les endroits où une chaîne externe devient `Regexp.new`, `Regexp.compile`, `Regexp.union` ou une interpolation dans un littéral regex. Il faut ensuite distinguer **compiler** le motif de **l’exécuter** sur du texte : une limite de temps de recherche ne protège pas contre une corruption lors de la compilation. Ruby précise que `Regexp.timeout` ne couvre pas ces bugs et qu’une limite de longueur n’est pas fiable pour l’ensemble des quatre cas. ([Note Ruby](https://www.ruby-lang.org/en/news/2026/10/23/regexp-fixes-for-gitlab-cves/))

Sur un environnement autorisé, un chercheur peut soumettre des motifs générés, comparer la version corrigée et l’ancienne, puis classer les crashs par trace native et zone mémoire avec AddressSanitizer. Le travail décisif est de relier un crash du moteur à un point d’entrée utilisateur et de montrer si la corruption est contrôlable. Un SIGSEGV isolé établit une indisponibilité, pas une RCE. Les détections [publiées par GitLab](https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-5-1-released/) ciblent notamment les crashs de workers natifs Onigmo et les séries d’erreurs de rendu Org mode ; ce sont des indices à corréler, pas un verdict automatique d’exploitation.

## Impact et action

Sur une instance GitLab autohébergée, le serveur stocke des dépôts, des secrets CI, des jetons et parfois des artefacts de déploiement. Une RCE sous son compte de service peut donc devenir un incident de chaîne logicielle bien plus large. Cette conséquence est **conditionnelle** à la réussite de l’exploitation et aux droits du processus. GitLab indique que GitLab.com est déjà corrigé et recommande la mise à jour immédiate des instances autogérées. Une fois la mise à jour appliquée, rechercher autour de la période d’exposition les crashs Onigmo, les erreurs de rendu anormales et les accès atypiques aux fonctions de compilation de motifs.

La règle de conception est plus générale : une chaîne d’utilisateur passée à un compilateur natif reste une entrée non fiable, même si l’application la présente comme une simple règle de filtrage.

Le dossier [PHP2Shell](/research/php2shell-deux-bugs-cycle-requete/) permet de comparer une autre famille de défauts mémoire : la durée de vie d’un état de requête, plutôt que la compilation d’un motif. Pour prioriser les correctifs sur une instance exposée, notre analyse [« CVSS n’est pas un risque »](/research/cvss-n-est-pas-un-risque/) distingue le score technique des conditions et conséquences propres au déploiement.

**Sources principales :** [GitLab, bulletin du 21 octobre](https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-5-1-released/), [Ruby, causes racines et versions corrigées](https://www.ruby-lang.org/en/news/2026/10/23/regexp-fixes-for-gitlab-cves/).
