{"id":3731,"date":"2026-10-31T11:25:43","date_gmt":"2026-10-31T18:25:43","guid":{"rendered":"https:\/\/cyber.mag212.com\/?p=3731"},"modified":"2026-10-31T11:25:43","modified_gmt":"2026-10-31T18:25:43","slug":"gitlab-cve-2026-97229-investigation-guide","status":"publish","type":"post","link":"https:\/\/cyber.mag212.com\/fr\/gitlab-cve-2026-97229-investigation-guide\/","title":{"rendered":"Au c\u0153ur de la faille GitLab\u00a0: de la configuration CI \u00e0 l\u2019ex\u00e9cution sur le serveur (CVE-2026-97229)"},"content":{"rendered":"<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700;800&#038;family=Source+Serif+4:opsz,wght@8..60,400;8..60,600&#038;family=JetBrains+Mono:wght@400;500&#038;display=swap\" rel=\"stylesheet\"><style>.m212{--ink:#0e1726;--body:#2b3647;--muted:#5d6b80;--line:#e3e8ef;--paper:#ffffff;--tint:#f5f7fa;--navy:#0a1424;--navy2:#13233b;--accent:#19c39a;--accent-dk:#0e8f70;--crit:#d6363f;--warn:#b7791f;--sans:\"Inter\",system-ui,-apple-system,\"Segoe UI\",Roboto,sans-serif;--serif:\"Source Serif 4\",Georgia,\"Times New Roman\",serif;--mono:\"JetBrains Mono\",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;background:var(--paper);color:var(--body);font-family:var(--serif);font-size:19px;line-height:1.7;-webkit-font-smoothing:antialiased;margin:0}.m212 *{box-sizing:border-box}.m212 a{color:var(--accent-dk);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px}.m212 a:hover{color:var(--ink)}.m212 .hero{background:radial-gradient(1200px 500px at 85% -10%,#1b3a5c 0%,transparent 60%),linear-gradient(180deg,var(--navy) 0%,var(--navy2) 100%);color:#e8eef6;padding:44px 24px 64px;border-radius:16px}.m212 .hero-inner{max-width:820px;margin:0 auto}.m212 .kicker{font-family:var(--sans);font-size:12.5px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--accent);margin:0 0 18px}.m212 .dek{font-family:var(--serif);font-size:21px;line-height:1.55;color:#c7d3e3;margin:0 0 28px;max-width:720px}.m212 .byline{font-family:var(--sans);font-size:14px;color:#9fb0c6;display:flex;flex-wrap:wrap;gap:6px 18px}.m212 .byline strong{color:#fff;font-weight:600}.m212 .tags{display:flex;flex-wrap:wrap;gap:8px;margin-top:22px}.m212 .tag{font-family:var(--sans);font-size:12px;font-weight:600;padding:5px 10px;border-radius:999px;border:1px solid #2c4566;color:#cfe0f2;background:rgba(255,255,255,.04)}.m212 .tag.crit{border-color:#7a2a31;background:rgba(214,54,63,.18);color:#ffb8bd}.m212 .facts{max-width:1080px;margin:-36px auto 0;padding:0 24px;position:relative}.m212 .facts-grid{display:grid;grid-template-columns:repeat(4,1fr);background:#fff;border:1px solid var(--line);border-radius:14px;box-shadow:0 12px 32px rgba(10,20,36,.10);overflow:hidden}.m212 .fact{padding:18px 20px;border-right:1px solid var(--line);font-family:var(--sans)}.m212 .fact:last-child{border-right:0}.m212 .fact .k{font-size:11.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);font-weight:600}.m212 .fact .v{font-size:22px;font-weight:800;color:var(--ink);margin-top:4px;line-height:1.2}.m212 .fact .v.crit{color:var(--crit)}.m212 .fact .s{font-size:13px;color:var(--muted);margin-top:2px;line-height:1.4}.m212 .wrap{max-width:760px;margin:0 auto;padding:48px 0 24px}.m212 p{margin:0 0 1.15em}.m212 .lede{font-size:21px;line-height:1.65;color:var(--ink)}.m212 h2{font-family:var(--sans);font-size:28px;line-height:1.25;letter-spacing:-.01em;color:var(--ink);margin:2.4em 0 .7em;font-weight:800}.m212 h2 .num{display:block;font-size:12.5px;letter-spacing:.16em;color:var(--accent-dk);font-weight:700;margin-bottom:6px}.m212 h3{font-family:var(--sans);font-size:19px;color:var(--ink);margin:1.8em 0 .5em;font-weight:700}.m212 strong{color:var(--ink)}.m212 sup.ref{font-family:var(--sans);font-size:11.5px;font-weight:600;line-height:0;margin-left:1px}.m212 sup.ref a{text-decoration:none;color:var(--accent-dk)}.m212 code{font-family:var(--mono);font-size:.82em;background:var(--tint);border:1px solid var(--line);border-radius:5px;padding:1px 6px;color:#1d2a3d}.m212 .callout{font-family:var(--sans);font-size:16px;line-height:1.6;border-radius:12px;padding:18px 22px;margin:28px 0;border:1px solid var(--line);background:var(--tint)}.m212 .callout .lbl{display:block;font-size:11.5px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;margin-bottom:6px;color:var(--muted)}.m212 .callout p:last-child{margin:0}.m212 .callout.alert{background:#fff5f5;border-color:#f3c7ca;border-left:4px solid var(--crit)}.m212 .callout.alert .lbl{color:var(--crit)}.m212 .callout.note{border-left:4px solid var(--accent)}.m212 .callout.note .lbl{color:var(--accent-dk)}.m212 .callout.caution{background:#fffaf0;border-color:#f1dfb8;border-left:4px solid var(--warn)}.m212 .callout.caution .lbl{color:var(--warn)}.m212 .takeaways{font-family:var(--sans);background:var(--navy);color:#dfe8f3;border-radius:14px;padding:24px 26px;margin:8px 0 36px}.m212 .takeaways h4{margin:0 0 12px;font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--accent)}.m212 .takeaways ul{margin:0;padding-left:20px;font-size:16px;line-height:1.6}.m212 .takeaways li{margin:0 0 8px}.m212 .takeaways li:last-child{margin:0}.m212 .takeaways strong{color:#fff}.m212 .tbl{overflow-x:auto;margin:24px 0 10px;border:1px solid var(--line);border-radius:12px}.m212 table{width:100%;border-collapse:collapse;font-family:var(--sans);font-size:14.5px;line-height:1.45;margin:0}.m212 th{background:var(--tint);text-align:left;font-weight:700;color:var(--ink);font-size:12px;letter-spacing:.06em;text-transform:uppercase;padding:12px 14px;border-bottom:1px solid var(--line);vertical-align:bottom}.m212 td{padding:11px 14px;border-bottom:1px solid var(--line);vertical-align:top}.m212 tr:last-child td{border-bottom:0}.m212 td.ver{font-family:var(--mono);font-size:13.5px;white-space:nowrap}.m212 td.rec{font-family:var(--mono);font-size:13.5px;font-weight:600;color:var(--accent-dk);white-space:nowrap}.m212 td.na{color:var(--muted);font-style:italic}.m212 .tbl-note{font-family:var(--sans);font-size:13.5px;color:var(--muted);margin:0 0 24px}.m212 figure{margin:32px 0;font-family:var(--sans)}.m212 .diagram{background:linear-gradient(180deg,var(--navy) 0%,var(--navy2) 100%);border-radius:14px;padding:26px 24px}.m212 .diagram .dtitle{color:#fff;font-weight:800;font-size:15px;letter-spacing:.06em;text-transform:uppercase;margin:0 0 16px}.m212 .steps{list-style:none;margin:0;padding:0;counter-reset:s}.m212 .steps li{counter-increment:s;position:relative;background:rgba(255,255,255,.05);border:1px solid #2a4262;border-radius:10px;padding:13px 16px 13px 60px;margin:0 0 22px;color:#b9c8da;font-size:14.5px;line-height:1.45}.m212 .steps li:last-child{margin-bottom:0}.m212 .steps li::before{content:counter(s,decimal-leading-zero);position:absolute;left:18px;top:13px;font-weight:800;color:var(--accent);font-size:17px}.m212 .steps li:not(:last-child)::after{content:\"\";position:absolute;left:50%;bottom:-17px;width:2px;height:12px;background:var(--accent);opacity:.7}.m212 .steps li b{display:block;color:#fff;font-size:15.5px;margin-bottom:2px}.m212 .layers{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}.m212 .layer{background:rgba(255,255,255,.05);border:1px solid #2a4262;border-radius:10px;padding:14px 16px;color:#b9c8da;font-size:14px;line-height:1.5}.m212 .layer b{display:block;color:var(--accent);font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;margin-bottom:4px}.m212 .layer i{display:block;font-style:normal;color:#fff;font-weight:700;font-size:15px;margin-bottom:6px}.m212 .layer ul{margin:0;padding-left:16px}.m212 .join{margin-top:14px;text-align:center;color:#fff;font-size:14px;font-weight:600;border:1px dashed var(--accent);border-radius:10px;padding:10px}.m212 figcaption{font-size:13.5px;color:var(--muted);margin-top:10px;line-height:1.5}.m212 .code{margin:24px 0 8px;border-radius:12px;overflow:hidden;border:1px solid #1e2f47;background:#0b1422}.m212 .code-h{display:flex;justify-content:space-between;align-items:center;gap:12px;font-family:var(--sans);font-size:12.5px;color:#9fb0c6;background:#111d30;padding:9px 14px;border-bottom:1px solid #1e2f47}.m212 .code-h b{color:#fff;font-weight:600}.m212 .code-h .lang{font-family:var(--mono);font-size:11.5px;color:var(--accent)}.m212 .code pre{margin:0;padding:16px 18px;overflow-x:auto;font-family:var(--mono);font-size:13.5px;line-height:1.65;color:#dbe6f3;white-space:pre;background:transparent;border:0}.m212 .code pre .c{color:#6f86a3}.m212 .code-n{font-family:var(--sans);font-size:13.5px;color:var(--muted);margin:0 0 22px;line-height:1.5}.m212 .check{list-style:none;padding:0;margin:20px 0;font-family:var(--sans);font-size:16px;line-height:1.55}.m212 .check li{position:relative;padding:12px 0 12px 34px;border-bottom:1px solid var(--line)}.m212 .check li:last-child{border-bottom:0}.m212 .check li::before{content:\"\";position:absolute;left:4px;top:16px;width:16px;height:16px;border:2px solid var(--accent-dk);border-radius:4px}.m212 .check li strong{display:block;margin-bottom:2px}.m212 .sources{font-family:var(--sans);font-size:14.5px;line-height:1.55;padding-left:28px}.m212 .sources li{margin:0 0 8px;padding-left:4px}.m212 .sources .pub{color:var(--muted)}.m212 .method{font-family:var(--sans);font-size:13.5px;color:var(--muted);border-top:1px solid var(--line);padding-top:18px;margin-top:28px;line-height:1.6}.m212 .author{display:flex;gap:16px;align-items:center;font-family:var(--sans);border:1px solid var(--line);border-radius:14px;padding:18px 20px;margin:40px 0 0}.m212 .avatar{flex:0 0 52px;height:52px;border-radius:50%;background:var(--navy);color:var(--accent);display:flex;align-items:center;justify-content:center;font-weight:800;font-size:18px}.m212 .author p{margin:0;font-size:14.5px;line-height:1.5}.m212 .author p b{color:var(--ink);font-size:15.5px}.m212 .cta{max-width:760px;margin:36px auto 0;padding:0 0 56px}.m212 .cta-box{background:linear-gradient(135deg,var(--navy) 0%,#163150 100%);border-radius:16px;padding:30px;color:#cfdbe9;font-family:var(--sans);display:flex;gap:24px;align-items:center;justify-content:space-between;flex-wrap:wrap}.m212 .cta-box h4{color:#fff;margin:0 0 4px;font-size:20px}.m212 .cta-box p{margin:0;font-size:15px}.m212 .btn{display:inline-block;background:var(--accent);color:#06221a!important;text-decoration:none!important;font-weight:700;font-size:15px;padding:12px 22px;border-radius:10px;white-space:nowrap}.m212 .btn:hover{background:#2be0b4}@media (max-width:760px){.m212{font-size:18px}.m212 .facts-grid{grid-template-columns:repeat(2,1fr)}.m212 .fact:nth-child(2){border-right:0}.m212 .fact:nth-child(-n+2){border-bottom:1px solid var(--line)}.m212 .layers{grid-template-columns:1fr}.m212 .facts{padding:0 12px}}<\/style>\n<article class=\"m212\">\n<header class=\"hero\">\n  <div class=\"hero-inner\">\n    <p class=\"kicker\">Vulnerability Analysis \u00b7 CVE-2026-97229<\/p>\n    <p class=\"dek\">A CVSS 10.0 bug in GitLab&#8217;s regular-expression compiler is now being exploited. This guide covers who is exposed, which version to upgrade to now (it is not the one in the original advisory), how the attack works, and how to look for signs of earlier compromise.<\/p>\n    <div class=\"byline\"><span>By <strong>El Mostafa Ouchen<\/strong><\/span><span>October 31, 2026<\/span><span>15 min read<\/span><\/div>\n    <div class=\"tags\"><span class=\"tag crit\">Actively exploited<\/span><span class=\"tag\">CISA KEV<\/span><span class=\"tag\">GitLab CE\/EE<\/span><span class=\"tag\">Remote code execution<\/span><span class=\"tag\">DFIR<\/span><\/div>\n  <\/div>\n<\/header>\n<div class=\"facts\">\n  <div class=\"facts-grid\">\n    <div class=\"fact\"><div class=\"k\">Gravit\u00e9<\/div><div class=\"v crit\">CVSS 10.0<\/div><div class=\"s\">Critical \u00b7 AV:N\/PR:N\/UI:N\/S:C<\/div><\/div>\n    <div class=\"fact\"><div class=\"k\">Weakness<\/div><div class=\"v\">CWE-190<\/div><div class=\"s\">Integer overflow in the regex compiler<\/div><\/div>\n    <div class=\"fact\"><div class=\"k\">Exploitation<\/div><div class=\"v crit\">Confirmed<\/div><div class=\"s\">Added to CISA KEV on Oct 29, 2026<\/div><\/div>\n    <div class=\"fact\"><div class=\"k\">Patch to<\/div><div class=\"v\">19.5.3<\/div><div class=\"s\">or 19.4.5 \/ 19.3.7 \/ 19.2.10<\/div><\/div>\n  <\/div>\n<\/div>\n<div class=\"wrap\">\n<p class=\"lede\">GitLab sits at the center of the software supply chain. It holds source code, runs builds and often keeps credentials that reach all the way into production. When a flaw in that platform lets an outsider run commands on the server, patching it is only half the job. The other half is working out whether someone got in first.<\/p>\n<p>On October 29, 2026, the U.S. Cybersecurity and Infrastructure Security Agency (CISA) added <strong>CVE-2026-97229<\/strong> to its Known Exploited Vulnerabilities (KEV) catalog. That confirms the flaw is being exploited in the wild.<sup class=\"ref\"><a href=\"#src4\">4<\/a><\/sup> GitLab released the fix on October 12.<sup class=\"ref\"><a href=\"#src1\">1<\/a><\/sup> Rapid7 published a full technical analysis and a public proof of concept days later.<sup class=\"ref\"><a href=\"#src7\">7<\/a>,<a href=\"#src8\">8<\/a><\/sup> Any self-managed instance that is still unpatched should be treated as a priority incident.<\/p>\n<div class=\"takeaways\">\n  <h4>Points cl\u00e9s \u00e0 retenir<\/h4>\n  <ul>\n    <li><strong>Upgrade to GitLab&#8217;s October 29 releases<\/strong> (19.5.3, 19.4.5, 19.3.7, 19.2.10 or the matching release for your branch). The first fixes for this CVE (19.4.2, 19.3.5, 19.2.8) are still exposed to a second CVSS 10.0 regex-compiler flaw, <strong>CVE-2026-110264<\/strong>, patched on October 21.<sup class=\"ref\"><a href=\"#src2\">2<\/a>,<a href=\"#src3\">3<\/a><\/sup><\/li>\n    <li><strong>The flaw gives code execution on the GitLab application server<\/strong> as the <code data-no-translation=\"\">git<\/code> service account, not just inside a CI job. Rapid7 reproduced this on gitlab-ce 19.4.1 with ASLR enabled.<sup class=\"ref\"><a href=\"#src7\">7<\/a><\/sup><\/li>\n    <li><strong>Instances that allow open sign-up and public project creation are the easiest to attack.<\/strong> In the route Rapid7 demonstrated, the attacker needs to push to a public project first, then sends an unauthenticated CI lint request.<sup class=\"ref\"><a href=\"#src6\">6<\/a>,<a href=\"#src7\">7<\/a><\/sup><\/li>\n    <li><strong>Patching is not the same as clearing an incident.<\/strong> If your instance was exposed before you patched, investigate for prior compromise and review every credential the server could reach.<\/li>\n  <\/ul>\n<\/div>\n<div class=\"callout caution\">\n  <span class=\"lbl\">What is and isn&#8217;t known<\/span>\n  <p>Active exploitation is confirmed by CISA&#8217;s KEV listing. As of October 31, the sources we reviewed do not name an attacker or a campaign. They also contain no victim timeline and no verified list of attack IP addresses or file hashes. The attack sequence below is Rapid7&#8217;s lab reproduction, and real attacks may take another route. The commands in this guide are defensive examples, not output from a real incident.<\/p>\n<\/div>\n<h2 id=\"exposure\"><span class=\"num\">01 \/ EXPOSURE<\/span>Who needs to act, and which version to install<\/h2>\n<p>GitLab rates CVE-2026-97229 <strong>Critical, CVSS 3.1 score 10.0<\/strong> (vector <code data-no-translation=\"\">AV:N\/AC:L\/PR:N\/UI:N\/S:C\/C:H\/I:H\/A:H<\/code>). It affects both Community and Enterprise editions. The vulnerable ranges are 19.2 before 19.2.8, 19.3 before 19.3.5, and 19.4 before 19.4.2. GitLab.com already runs the patched code. GitLab patched all GitLab Dedicated tenants before the advisory was published.<sup class=\"ref\"><a href=\"#src1\">1<\/a><\/sup> The CVE record classifies the weakness as CWE-190, integer overflow or wraparound. The researcher <em>joaxcar<\/em> reported it through GitLab&#8217;s HackerOne bug bounty program.<sup class=\"ref\"><a href=\"#src5\">5<\/a><\/sup><\/p>\n<div class=\"callout alert\">\n  <span class=\"lbl\">Important: do not stop at the first fix<\/span>\n  <p>On October 21, GitLab patched <strong>CVE-2026-110264<\/strong>, another CVSS 10.0 integer overflow in the regex compiler, reported by the same researcher. It affects every version from 7.0 up to the October 21 releases. That means an instance upgraded only to 19.4.2, 19.3.5 or 19.2.8 is <strong>still critically exposed<\/strong>.<sup class=\"ref\"><a href=\"#src2\">2<\/a><\/sup> GitLab then shipped further patch releases on October 29.<sup class=\"ref\"><a href=\"#src3\">3<\/a><\/sup> Those are the versions to install today.<\/p>\n<\/div>\n<div class=\"tbl\">\n<table>\n  <thead>\n    <tr><th>Branch<\/th><th>First fix for CVE-2026-97229<br>(Oct 12)<\/th><th>Also fixes CVE-2026-110264<br>(Oct 21)<\/th><th>Recommended target<br>(Oct 29)<\/th><\/tr>\n  <\/thead>\n  <tbody>\n    <tr><td>19.5<\/td><td class=\"na\">Not in affected range<\/td><td class=\"ver\">19.5.1<\/td><td class=\"rec\">19.5.3<\/td><\/tr>\n    <tr><td>19.4<\/td><td class=\"ver\">19.4.2<\/td><td class=\"ver\">19.4.3<\/td><td class=\"rec\">19.4.5<\/td><\/tr>\n    <tr><td>19.3<\/td><td class=\"ver\">19.3.5<\/td><td class=\"ver\">19.3.6<\/td><td class=\"rec\">19.3.7<\/td><\/tr>\n    <tr><td>19.2<\/td><td class=\"ver\">19.2.8<\/td><td class=\"ver\">19.2.9<\/td><td class=\"rec\">19.2.10<\/td><\/tr>\n    <tr><td>19.1<\/td><td class=\"na\">Not in affected range<\/td><td class=\"ver\">19.1.9<\/td><td class=\"rec\">19.1.10<\/td><\/tr>\n    <tr><td>19.0<\/td><td class=\"na\">Not in affected range<\/td><td class=\"ver\">19.0.10<\/td><td class=\"rec\">19.0.11<\/td><\/tr>\n    <tr><td>18.11<\/td><td class=\"na\">Not in affected range<\/td><td class=\"ver\">18.11.13<\/td><td class=\"rec\">18.11.14<\/td><\/tr>\n  <\/tbody>\n<\/table>\n<\/div>\n<p class=\"tbl-note\">Sources: GitLab patch releases of October 12, 21 and 29, 2026.<sup class=\"ref\"><a href=\"#src1\">1<\/a>\u2013<a href=\"#src3\">3<\/a><\/sup> The October 29 release also says self-managed GitLab Runner and AI Gateway must be updated separately. Check GitLab&#8217;s releases page for anything newer before you schedule maintenance.<\/p>\n<p>The exposed population is large. Censys data reported on October 14 counted roughly 25,800 vulnerable GitLab hosts, about 31% of the GitLab hosts it observed. The largest numbers were in Germany, Russia and the United States.<sup class=\"ref\"><a href=\"#src16\">16<\/a><\/sup><\/p>\n<h2 id=\"mechanism\"><span class=\"num\">02 \/ ATTACK PATH<\/span>How repository content becomes server execution<\/h2>\n<p>The bug sits in Onigmo, the regular-expression engine built into Ruby, and in how GitLab uses it. GitLab compiles regular expressions from CI configuration, such as <code data-no-translation=\"\">rules:exists<\/code> et <code data-no-translation=\"\">rules:changes<\/code> patterns. That means text an attacker controls ends up being compiled on the server.<sup class=\"ref\"><a href=\"#src7\">7<\/a><\/sup><\/p>\n<figure>\n  <div class=\"diagram\">\n    <p class=\"dtitle\">From repository input to application execution<\/p>\n    <ol class=\"steps\">\n      <li><b>Attacker prepares a public project<\/b>Commits a malicious <code style=\"background:transparent;border:0;color:#9fe8d2;padding:0\" data-no-translation=\"\">.gitlab-ci.yml<\/code> and a file path with unusual four-byte UTF-8 characters.<\/li>\n      <li><b>Unauthenticated CI lint request<\/b>A request to the CI lint endpoint makes GitLab check the project&#8217;s paths against the attacker&#8217;s regex.<\/li>\n      <li><b>The guard is bypassed<\/b>An inline comment hides a large repeat count from GitLab&#8217;s digits-only size check, so the pattern passes.<\/li>\n      <li><b>Recompilation and overflow<\/b>The UTF-8 path forces the pattern to be compiled again, outside the timeout and size checks. The program-size calculation overflows a signed 32-bit integer.<\/li>\n      <li><b>Command execution in the Puma worker<\/b>The broken compiled code redirects execution to <code style=\"background:transparent;border:0;color:#9fe8d2;padding:0\" data-no-translation=\"\">system()<\/code>, which runs commands as the <code style=\"background:transparent;border:0;color:#9fe8d2;padding:0\" data-no-translation=\"\">git<\/code> user. The worker then crashes and is replaced.<\/li>\n    <\/ol>\n  <\/div>\n  <figcaption><strong>Figure 1.<\/strong> Simplified view of Rapid7&#8217;s demonstrated exploit route. MAG212 CYBER illustration based on Rapid7&#8217;s analysis.<sup class=\"ref\"><a href=\"#src6\">6<\/a>,<a href=\"#src7\">7<\/a><\/sup><\/figcaption>\n<\/figure>\n<p>Two details matter for defenders. First, the attack <strong>needs write access to a project<\/strong>. GitLab&#8217;s PR:N rating describes the final request, which needs no login. But Rapid7 notes that its route first requires pushing a commit, and that this does not fit neatly with a &#8220;no privileges&#8221; rating. On an instance with open sign-up and public project creation, getting that access is trivial.<sup class=\"ref\"><a href=\"#src6\">6<\/a>,<a href=\"#src7\">7<\/a><\/sup><\/p>\n<p>Second, this is <strong>code execution on the application server<\/strong>, not in a disposable CI runner. Rapid7 achieved command execution in the Rails\/Puma worker as the <code data-no-translation=\"\">git<\/code> account, with ASLR enabled. Its lab exploit needed around 2 GiB of extra memory and offsets tuned to the specific build. That is a real barrier, but a well-resourced attacker can get past it. The exploit does not by itself give root access.<sup class=\"ref\"><a href=\"#src7\">7<\/a><\/sup><\/p>\n<h2 id=\"ruby\"><span class=\"num\">03 \/ ROOT CAUSE<\/span>Why a regex timeout is not a fix<\/h2>\n<p>On October 23, the Ruby core team published an advisory covering four regex-engine bugs found through GitLab&#8217;s bug bounty program: CVE-2026-89078, CVE-2026-93577, CVE-2026-97229 and CVE-2026-110264. The advisory says CVE-2026-97229 comes from an integer overflow in the compiled pattern size. It recommends <strong>Ruby 4.0.9, 3.4.12 or 3.3.13 or later<\/strong>, the releases that contain all four fixes. On the 4.0 branch, the fix for this specific overflow first shipped in 4.0.8.<sup class=\"ref\"><a href=\"#src9\">9<\/a><\/sup><\/p>\n<p>Ruby&#8217;s guidance is clear. Only applications that compile regular expressions from attacker-controlled strings are exposed, for example through <code data-no-translation=\"\">Regexp.new<\/code>, <code data-no-translation=\"\">Regexp.union<\/code> ou <code data-no-translation=\"\">\/#{input}\/<\/code>. Patterns written by developers as constants are not affected. <code data-no-translation=\"\">Regexp.timeout<\/code> does not protect against these bugs. Limiting pattern length is also unreliable, because some of them can be triggered by short patterns.<sup class=\"ref\"><a href=\"#src9\">9<\/a><\/sup><\/p>\n<p>The upstream fix, Ruby pull request #19020, makes two changes. It replaces a multiplication that could overflow (the pattern length times the repeat count) with a comparison based on division, so the dangerous product is never calculated. It also caps the compiled program&#8217;s size while it is being built, raising a <code data-no-translation=\"\">RegexpError<\/code> before jump offsets can wrap around.<sup class=\"ref\"><a href=\"#src10\">10<\/a><\/sup> The general lesson: once a value has overflowed, checking it afterwards cannot prove it was safe. The check has to happen before the overflow.<\/p>\n<div class=\"callout note\">\n  <span class=\"lbl\">Operational consequence<\/span>\n  <p>Upgrade GitLab through its supported distribution (the Linux package, the official container image or the Helm chart). Updating the host operating system&#8217;s <code data-no-translation=\"\">ruby<\/code> package does not update the Ruby that GitLab bundles, your container images or every application node. Other Ruby applications that compile user-supplied regular expressions need their own assessment against Ruby&#8217;s advisory.<\/p>\n<\/div>\n<h2 id=\"timeline\"><span class=\"num\">04 \/ INVESTIGATION<\/span>Build a timeline before drawing conclusions<\/h2>\n<p>Start your investigation window on the date a vulnerable version first became reachable by untrusted users, not on the date CISA announced exploitation. Rapid7&#8217;s proof of concept has been public since mid-October, so the window may be wider than you expect.<sup class=\"ref\"><a href=\"#src8\">8<\/a><\/sup> Keep that window open until containment and patch verification are complete. Record every timestamp in UTC, along with the source time zone, the host or pod it came from, and any clock drift. Store repository commits and project IDs alongside request correlation IDs so events can be matched up later.<\/p>\n<figure>\n  <div class=\"diagram\">\n    <p class=\"dtitle\">Correlate three independent evidence layers<\/p>\n    <div class=\"layers\">\n      <div class=\"layer\"><b>Layer 1<\/b><i>Request<\/i><ul><li>Long-running <code style=\"background:transparent;border:0;color:#9fe8d2;padding:0\" data-no-translation=\"\">\u2026\/ci\/lint<\/code> calls<\/li><li>HTTP 502 \/ &#8220;badgateway&#8221; EOF in Workhorse<\/li><li>Proxy and WAF logs<\/li><\/ul><\/div>\n      <div class=\"layer\"><b>Layer 2<\/b><i>Application<\/i><ul><li>Puma worker restarts<\/li><li><code style=\"background:transparent;border:0;color:#9fe8d2;padding:0\" data-no-translation=\"\">regexp_matcher.rb<\/code> in traces<\/li><li>New CI configuration commits with odd paths<\/li><\/ul><\/div>\n      <div class=\"layer\"><b>Layer 3<\/b><i>Host<\/i><ul><li>Shell started by the Puma process<\/li><li>Sudden memory jump of about 2 GiB<\/li><li>New outbound connections<\/li><\/ul><\/div>\n    <\/div>\n    <div class=\"join\">Strong signal = several layers line up within the same time window and correlation ID<\/div>\n  <\/div>\n  <figcaption><strong>Figure 2.<\/strong> An investigation model built by MAG212 CYBER. Signal examples come from Rapid7&#8217;s hunting guidance.<sup class=\"ref\"><a href=\"#src7\">7<\/a><\/sup><\/figcaption>\n<\/figure>\n<div class=\"tbl\">\n<table>\n  <thead><tr><th style=\"width:42%\">Signal<\/th><th>How to interpret it<\/th><\/tr><\/thead>\n  <tbody>\n    <tr><td>Long <code data-no-translation=\"\">GET \/api\/v4\/projects\/&lt;id&gt;\/ci\/lint?content_ref=\u2026<\/code> near a worker crash<\/td><td>Matches the demonstrated route, but ordinary lint traffic is common.<\/td><\/tr>\n    <tr><td>HTTP 502 \/ &#8220;badgateway: failed to receive response: EOF&#8221; plus a Puma restart<\/td><td>A useful correlation. Not proof of compromise on its own.<\/td><\/tr>\n    <tr><td><code data-no-translation=\"\">regexp_matcher.rb<\/code> in a saved trace<\/td><td>Supports a regex-path investigation. Not proof on its own.<\/td><\/tr>\n    <tr><td>Commit with a comment-split repeat, POSIX character classes and four-byte UTF-8 path names<\/td><td>A strong lead when it doesn&#8217;t match the project&#8217;s normal activity.<\/td><\/tr>\n    <tr><td>Unexpected shell or interpreter started by a Puma worker<\/td><td>Escalate if it can&#8217;t be explained. Rule out legitimate maintenance first.<\/td><\/tr>\n    <tr><td>New tokens, users, SSH keys, webhooks or pipeline changes<\/td><td>General post-compromise hunting. Not specific to this CVE.<\/td><\/tr>\n  <\/tbody>\n<\/table>\n<\/div>\n<p class=\"tbl-note\">Rapid7 says other exploitation paths may look different. Not every successful exploit has to crash a worker.<sup class=\"ref\"><a href=\"#src7\">7<\/a><\/sup><\/p>\n<p>GitLab also publishes six detections for this CVE in its open-source <code data-no-translation=\"\">gitlab-security-oss\/tldr<\/code> repository: <code data-no-translation=\"\">onigmo_native_worker_crash<\/code>, <code data-no-translation=\"\">graphql_cilint_hostile_regexp<\/code>, <code data-no-translation=\"\">ci_regexp_oversized_non_ascii_path<\/code>, <code data-no-translation=\"\">ci_regexp_guard_rejection<\/code>, <code data-no-translation=\"\">ci_lint_workhorse_worker_crash<\/code> et <code data-no-translation=\"\">ci_lint_scripted_client_error_burst<\/code>.<sup class=\"ref\"><a href=\"#src11\">11<\/a><\/sup> Take the rule logic directly from that repository and test it against your own log schema before relying on it.<\/p>\n<h2 id=\"commands\"><span class=\"num\">05 \/ HANDS-ON<\/span>Defensive command-line triage<\/h2>\n<div class=\"callout caution\">\n  <span class=\"lbl\">Scope and safety<\/span>\n  <p>These examples are for Linux package (Omnibus) installations unless stated otherwise. They are built around documented GitLab commands and log locations. They are not a vendor-certified scanner, and they have not been run against a live incident. Work on preserved copies where you can, because inspecting a live system changes its state. Keep all output private: logs, process lists and environment data can contain secrets.<\/p>\n<\/div>\n<div class=\"code\">\n  <div class=\"code-h\"><b>A \u00b7 Identify the running environment<\/b><span class=\"lang\">bash<\/span><\/div>\n<pre data-no-translation=\"\">sudo gitlab-rake gitlab:env:info\nsudo gitlab-ctl status<\/pre>\n<\/div>\n<p class=\"code-n\">Both are documented GitLab commands.<sup class=\"ref\"><a href=\"#src12\">12<\/a>,<a href=\"#src13\">13<\/a><\/sup> Run them on every Rails application node. Record the GitLab version, revision and bundled Ruby version, and compare each node and container image digest with the version you intended to deploy. A healthy service status shows the service is up. It does not show the server was never compromised.<\/p>\n<div class=\"code\">\n  <div class=\"code-h\"><b>B \u00b7 Inventory local logs, including rotated files<\/b><span class=\"lang\">bash<\/span><\/div>\n<pre data-no-translation=\"\">sudo find \/var\/log\/gitlab -maxdepth 2 -type f \\\n  -printf '%TY-%Tm-%TdT%TH:%TM:%TS  %s  %p\\n' | sort<\/pre>\n<\/div>\n<p class=\"code-n\">Log paths and rotation behavior follow GitLab&#8217;s log documentation.<sup class=\"ref\"><a href=\"#src14\">14<\/a><\/sup> Uses GNU <code data-no-translation=\"\">find<\/code> syntax.<\/p>\n<div class=\"code\">\n  <div class=\"code-h\"><b>C \u00b7 Broad search across preserved, uncompressed logs<\/b><span class=\"lang\">bash<\/span><\/div>\n<pre data-no-translation=\"\"><span class=\"c\"># Point this at a restricted COPY of the collected logs<\/span>\nLOG_COPY='\/mnt\/evidence\/gitlab-logs'\nrg -n -i --text \\\n  'ci\/lint|cilint|content_ref|regexp_matcher\\.rb|onigmo|badgateway|failed to receive response|segmentation fault' \\\n  \"$LOG_COPY\"<\/pre>\n<\/div>\n<p class=\"code-n\">Requires ripgrep. Expect a lot of false positives. No match does not mean the system is clean. Compressed archives need the next step.<\/p>\n<div class=\"code\">\n  <div class=\"code-h\"><b>D \u00b7 Search compressed archives without altering them<\/b><span class=\"lang\">bash<\/span><\/div>\n<pre data-no-translation=\"\"><span class=\"c\"># .gz archives (logrotate) and svlogd '@\u2026.s' archives<\/span>\nfind \"$LOG_COPY\" -type f \\( -name '*.gz' -o -name '@*.s' \\) -print0 |\n  while IFS= read -r -d '' f; do\n    gzip -cdf -- \"$f\" | rg -n -i --label=\"$f\" -H \\\n      'ci\/lint|regexp_matcher\\.rb|onigmo|badgateway|EOF'\n  done<\/pre>\n<\/div>\n<p class=\"code-n\">GitLab documents both <code data-no-translation=\"\">.gz<\/code> and svlogd <code data-no-translation=\"\">.s<\/code> archives.<sup class=\"ref\"><a href=\"#src14\">14<\/a><\/sup> Check each archive&#8217;s format first, and leave the originals untouched.<\/p>\n<p>Prioritize the <code data-no-translation=\"\">gitlab-workhorse<\/code>, <code data-no-translation=\"\">puma<\/code> et <code data-no-translation=\"\">gitlab-rails<\/code> logs, together with reverse-proxy, load-balancer and central SIEM logs. For JSON logs, pull out the time, path or URI, status, remote address and <code data-no-translation=\"\">correlation_id<\/code>, using the field names your version actually writes. Field names vary between components and versions. Interpret client IP addresses in light of your trusted-proxy configuration.<sup class=\"ref\"><a href=\"#src14\">14<\/a><\/sup><\/p>\n<div class=\"code\">\n  <div class=\"code-h\"><b>E \u00b7 Capture current host context<\/b><span class=\"lang\">bash<\/span><\/div>\n<pre data-no-translation=\"\">date -u '+%Y-%m-%dT%H:%M:%SZ'\nsudo ps -eo user,pid,ppid,lstart,args --forest\nsudo ss -tpn\n<span class=\"c\"># Set the start date to the beginning of your exposure window<\/span>\nsudo journalctl -k --since '2026-10-01 00:00:00 UTC' --no-pager<\/pre>\n<\/div>\n<p class=\"code-n\">Look for a shell, interpreter or download tool (<code data-no-translation=\"\">sh<\/code>, <code data-no-translation=\"\">bash<\/code>, <code data-no-translation=\"\">curl<\/code>, <code data-no-translation=\"\">wget<\/code>, <code data-no-translation=\"\">python<\/code>) running under a Puma worker as <code data-no-translation=\"\">git<\/code>, especially one with outbound connections. Current process and socket lists will not show activity that has already ended. Kernel logs may explain a crash or out-of-memory event, but they cannot show who caused it.<\/p>\n<div class=\"code\">\n  <div class=\"code-h\"><b>F \u00b7 Review repository history in an isolated copy<\/b><span class=\"lang\">bash<\/span><\/div>\n<pre data-no-translation=\"\"><span class=\"c\"># Never run the project's pipeline or scripts during analysis<\/span>\ngit --no-pager log --all --date=iso-strict \\\n  --format='%H %ad %an %s' --name-status -- .gitlab-ci.yml\ngit --no-pager show --no-ext-diff --no-textconv '&lt;SUSPECT_COMMIT&gt;:.gitlab-ci.yml'\ngit -c core.quotePath=true ls-tree -r --name-only '&lt;SUSPECT_COMMIT&gt;'<\/pre>\n<\/div>\n<p class=\"code-n\">With <code data-no-translation=\"\">core.quotePath=true<\/code>, non-ASCII path names are shown as escaped bytes, which makes four-byte UTF-8 characters easy to spot. Also check any CI files the configuration includes and any deleted branches. A clone may not contain deleted or unreachable objects, so pull those from server-side evidence. Git author names and timestamps can be set by the attacker. Confirm them against GitLab&#8217;s server-side push and authentication records.<\/p>\n<h2 id=\"response\"><span class=\"num\">06 \/ RESPONSE<\/span>Containment, recovery and prevention<\/h2>\n<figure>\n  <div class=\"diagram\">\n    <p class=\"dtitle\">A response that closes both the flaw and the incident<\/p>\n    <ol class=\"steps\">\n      <li><b>Contain and preserve<\/b>Restrict access at the network edge. Collect volatile data and export logs before retention expires.<\/li>\n      <li><b>Patch the real deployment<\/b>Follow the required upgrade stops, then confirm the version on every application node and image.<\/li>\n      <li><b>Investigate trust and secrets<\/b>Review repositories, identity events, runners and deployment access the server could reach.<\/li>\n      <li><b>Recover and validate<\/b>Rebuild if compromised, revoke exposed credentials, and monitor for recurrence.<\/li>\n    <\/ol>\n  <\/div>\n  <figcaption><strong>Figure 3.<\/strong> MAG212 CYBER&#8217;s defensive workflow for CVE-2026-97229.<\/figcaption>\n<\/figure>\n<h3>Contenir<\/h3>\n<p>If you suspect active compromise, restrict access to the instance at a controlled network boundary and bring in incident responders. Collect volatile evidence if you can do it without delaying urgent containment. Export central logs before retention expires. Don&#8217;t publish raw CI configurations, process output or secrets as &#8220;proof&#8221;.<\/p>\n<h3>Correctif<\/h3>\n<p>Upgrade to the October 29 release for your branch, or anything newer (see Section 01). Follow GitLab&#8217;s required upgrade stops (for the 19.x series these are 19.2, 19.5, 19.8 and 19.11) and let background migrations finish between stops.<sup class=\"ref\"><a href=\"#src15\">15<\/a><\/sup> The October 12 release includes database migrations, so single-node instances should plan for downtime.<sup class=\"ref\"><a href=\"#src1\">1<\/a><\/sup> A backup taken after a known compromise is evidence. Don&#8217;t assume it is safe to restore from.<\/p>\n<h3>Reduce exposure while you patch<\/h3>\n<p>Rapid7 recommends restricting anonymous access to public projects and stopping untrusted users from creating or writing to projects. Rapid7 is explicit that this does not fix the compiler bug and may not block other routes.<sup class=\"ref\"><a href=\"#src6\">6<\/a><\/sup> In practice, that means turning off open sign-up (or requiring admin approval), limiting who can create projects, and setting default and restricted visibility levels. MFA protects accounts, but it does nothing to stop an unauthenticated request to the vulnerable endpoint.<\/p>\n<h3>Credentials<\/h3>\n<p>List every token, CI\/CD variable, SSH key, cloud identity and deployment credential the compromised service could access. After containment, revoke anything exposed and issue replacements through a trusted control plane. Check downstream audit trails, such as your cloud provider, container registry and package registries, for any use of the old credentials. Don&#8217;t limit the search to the GitLab host.<\/p>\n<h3>Recovery<\/h3>\n<p>If compromise is confirmed, rebuild the affected application infrastructure from trusted images. Restore data only after reviewing it, check the integrity of repositories and pipelines, and re-establish trust in runners and deployment integrations. Keep the originals for the investigation. Changing passwords and restarting services will not remove every possible form of persistence.<\/p>\n<div class=\"tbl\">\n<table>\n  <thead><tr><th style=\"width:42%\">Preventive control<\/th><th>Purpose<\/th><\/tr><\/thead>\n  <tbody>\n    <tr><td>Restrict sign-up and public project creation<\/td><td>Cuts down write access for untrusted users. Keep only the access the business actually needs.<\/td><\/tr>\n    <tr><td>Segment the application, runners and production<\/td><td>Limits lateral movement. Avoid privileged runner configurations unless they&#8217;re required.<\/td><\/tr>\n    <tr><td>Short-lived, narrowly scoped deployment identities<\/td><td>Makes stolen build credentials less valuable and shortens their lifetime.<\/td><\/tr>\n    <tr><td>Protect CI configuration and release approvals<\/td><td>Makes unauthorized pipeline changes harder to hide.<\/td><\/tr>\n    <tr><td>Forward logs and endpoint telemetry off-host<\/td><td>Keeps your visibility even if the server itself is tampered with.<\/td><\/tr>\n    <tr><td>Track bundled runtimes and image digests<\/td><td>Confirms the component you actually run got the fix, instead of assuming an OS update covered it.<\/td><\/tr>\n  <\/tbody>\n<\/table>\n<\/div>\n<h2 id=\"closure\"><span class=\"num\">07 \/ CLOSURE<\/span>When can you call the incident resolved?<\/h2>\n<p>Reach three separate conclusions, and record each one on its own:<\/p>\n<ul class=\"check\">\n  <li><strong>Vulnerability remediated<\/strong>Every application node and image runs a release that fixes both CVE-2026-97229 and CVE-2026-110264, and this has been checked rather than assumed.<\/li>\n  <li><strong>Investigation completed within the available evidence<\/strong>Record which nodes, date ranges, log sources and credentials were reviewed, and which telemetry was missing.<\/li>\n  <li><strong>Recovery validated<\/strong>Credentials are rotated, integrations are trusted again, and monitoring is in place to spot a recurrence.<\/li>\n<\/ul>\n<p>A clean search means no matching evidence was found in the sources you checked. It does not prove the system was never accessed. Say that plainly in your report.<\/p>\n<div class=\"callout note\">\n  <span class=\"lbl\">MAG212 CYBER assessment<\/span>\n  <p>Treat GitLab as production security infrastructure, not a developer convenience. An effective response to CVE-2026-97229 has three parts. First, an application update you have verified, to a release that also fixes CVE-2026-110264. Second, evidence correlated across the request, application and host layers. Third, a disciplined review of the delivery credentials that make this platform so valuable to attackers.<\/p>\n<\/div>\n<h2 id=\"sources\"><span class=\"num\">REFERENCES<\/span>Sources primaires<\/h2>\n<ol class=\"sources\">\n  <li id=\"src1\"><a href=\"https:\/\/docs.gitlab.com\/releases\/patches\/patch-release-gitlab-19-4-2-released\/\" target=\"_blank\" rel=\"noopener\">GitLab Critical Patch Release: 19.4.2, 19.3.5, 19.2.8<\/a> <span class=\"pub\">\u2014 GitLab, Oct 12, 2026<\/span><\/li>\n  <li id=\"src2\"><a href=\"https:\/\/docs.gitlab.com\/releases\/patches\/patch-release-gitlab-19-5-1-released\/\" target=\"_blank\" rel=\"noopener\">GitLab Critical Patch Release: 19.5.1 (CVE-2026-110264)<\/a> <span class=\"pub\">\u2014 GitLab, Oct 21, 2026<\/span><\/li>\n  <li id=\"src3\"><a href=\"https:\/\/docs.gitlab.com\/releases\/patches\/patch-release-gitlab-19-5-3-released\/\" target=\"_blank\" rel=\"noopener\">GitLab Patch Release: 19.5.3<\/a> <span class=\"pub\">\u2014 GitLab, Oct 29, 2026<\/span><\/li>\n  <li id=\"src4\"><a href=\"https:\/\/content.govdelivery.com\/accounts\/USDHSCISA\/bulletins\/4310049\" target=\"_blank\" rel=\"noopener\">CISA adds two Known Exploited Vulnerabilities to catalog<\/a> <span class=\"pub\">\u2014 CISA, Oct 29, 2026<\/span><\/li>\n  <li id=\"src5\"><a href=\"https:\/\/www.cve.org\/CVERecord?id=CVE-2026-97229\" target=\"_blank\" rel=\"noopener\">CVE-2026-97229 record<\/a> <span class=\"pub\">\u2014 CVE Program (CNA: GitLab)<\/span><\/li>\n  <li id=\"src6\"><a href=\"https:\/\/www.rapid7.com\/blog\/post\/etr-cve-2026-97229-critical-unauthenticated-remote-code-execution-in-gitlab\/\" target=\"_blank\" rel=\"noopener\">CVE-2026-97229: Critical unauthenticated remote code execution in GitLab<\/a> <span class=\"pub\">\u2014 Rapid7, Oct 13, 2026 (updated Oct 30)<\/span><\/li>\n  <li id=\"src7\"><a href=\"https:\/\/www.rapid7.com\/blog\/post\/ra-gitlab-ci-cd-regex-integer-overflow-technical-analysis-cve-2026-97229\/\" target=\"_blank\" rel=\"noopener\">GitLab CI\/CD regex integer overflow: technical analysis<\/a> <span class=\"pub\">\u2014 Rapid7, Oct 16, 2026<\/span><\/li>\n  <li id=\"src8\"><a href=\"https:\/\/github.com\/jburgess-r7\/CVE-2026-97229-PoC\" target=\"_blank\" rel=\"noopener\">CVE-2026-97229 proof of concept<\/a> <span class=\"pub\">\u2014 Jonah Burgess \/ Rapid7, GitHub<\/span><\/li>\n  <li id=\"src9\"><a href=\"https:\/\/www.ruby-lang.org\/en\/news\/2026\/10\/23\/regexp-fixes-for-gitlab-cves\/\" target=\"_blank\" rel=\"noopener\">Regexp fixes for GitLab CVEs<\/a> <span class=\"pub\">\u2014 Ruby core team, Oct 23, 2026<\/span><\/li>\n  <li id=\"src10\"><a href=\"https:\/\/github.com\/ruby\/ruby\/pull\/19020\" target=\"_blank\" rel=\"noopener\">Avoid overflow in the regexp compiler&#8217;s program size arithmetic (PR #19020)<\/a> <span class=\"pub\">\u2014 ruby\/ruby, GitHub<\/span><\/li>\n  <li id=\"src11\"><a href=\"https:\/\/gitlab.com\/gitlab-security-oss\/tldr\" target=\"_blank\" rel=\"noopener\">GitLab Security detections (tldr)<\/a> <span class=\"pub\">\u2014 GitLab Security, GitLab.com<\/span><\/li>\n  <li id=\"src12\"><a href=\"https:\/\/docs.gitlab.com\/administration\/raketasks\/maintenance\/\" target=\"_blank\" rel=\"noopener\">Maintenance Rake tasks<\/a> <span class=\"pub\">\u2014 GitLab Docs<\/span><\/li>\n  <li id=\"src13\"><a href=\"https:\/\/docs.gitlab.com\/omnibus\/maintenance\/\" target=\"_blank\" rel=\"noopener\">Linux package maintenance commands<\/a> <span class=\"pub\">\u2014 GitLab Docs<\/span><\/li>\n  <li id=\"src14\"><a href=\"https:\/\/docs.gitlab.com\/administration\/logs\/\" target=\"_blank\" rel=\"noopener\">Log system<\/a> <span class=\"pub\">\u2014 GitLab Docs<\/span><\/li>\n  <li id=\"src15\"><a href=\"https:\/\/docs.gitlab.com\/update\/upgrade_paths\/\" target=\"_blank\" rel=\"noopener\">Plan your upgrade path<\/a> <span class=\"pub\">\u2014 GitLab Docs<\/span><\/li>\n  <li id=\"src16\"><a href=\"https:\/\/dailysecurityreview.com\/?p=44542\" target=\"_blank\" rel=\"noopener\">Coverage of Censys exposure data for CVE-2026-97229<\/a> <span class=\"pub\">\u2014 Daily Security Review, Oct 14, 2026<\/span><\/li>\n<\/ol>\n<p class=\"method\"><strong>Methodology.<\/strong> Sources were checked on October 31, 2026. CISA&#8217;s KEV catalog page could not be retrieved directly, so this article confirms the KEV addition from CISA&#8217;s bulletin and the CVE record. It does not state a federal remediation deadline. GitLab&#8217;s detection rules are identified by name only, because their full contents were not independently validated. Figures are original MAG212 CYBER explanatory graphics based on the cited material. They are not vendor screenshots or incident evidence. No exploit was run and no production environment was examined for this article.<\/p>\n<div class=\"author\">\n  <div class=\"avatar\">EO<\/div>\n  <p><b>El Mostafa Ouchen<\/b><br>MAG212 CYBER. Writes practical threat research and defensive guidance for security and engineering teams.<\/p>\n<\/div>\n<\/div>\n<section class=\"cta\">\n  <div class=\"cta-box\">\n    <div><h4>Get the next analysis first<\/h4><p>Practical security research and defensive guidance, free in your inbox.<\/p><\/div>\n    <a class=\"btn\" href=\"https:\/\/cyber.mag212.com\/fr\/subscribe-free\/\">Abonnez-vous gratuitement<\/a>\n  <\/div>\n<\/section>\n<\/article>","protected":false},"excerpt":{"rendered":"<p>CVE-2026-97229, a CVSS 10.0 flaw in GitLab\u2019s regex compiler, is now in CISA\u2019s KEV catalog. Who is exposed, which version to patch to now, how the attack works and how to hunt for prior compromise.<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[19,15,14],"tags":[],"class_list":["post-3731","post","type-post","status-publish","format-standard","hentry","category-critical-cves","category-threat-intelligence","category-vulnerabilities"],"_links":{"self":[{"href":"https:\/\/cyber.mag212.com\/fr\/wp-json\/wp\/v2\/posts\/3731","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cyber.mag212.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cyber.mag212.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cyber.mag212.com\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cyber.mag212.com\/fr\/wp-json\/wp\/v2\/comments?post=3731"}],"version-history":[{"count":1,"href":"https:\/\/cyber.mag212.com\/fr\/wp-json\/wp\/v2\/posts\/3731\/revisions"}],"predecessor-version":[{"id":3732,"href":"https:\/\/cyber.mag212.com\/fr\/wp-json\/wp\/v2\/posts\/3731\/revisions\/3732"}],"wp:attachment":[{"href":"https:\/\/cyber.mag212.com\/fr\/wp-json\/wp\/v2\/media?parent=3731"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cyber.mag212.com\/fr\/wp-json\/wp\/v2\/categories?post=3731"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cyber.mag212.com\/fr\/wp-json\/wp\/v2\/tags?post=3731"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}