SentriKat is live, launch pricing and hands-on onboarding for founding customers. Get started
All articles

Your AI coding agent ships an actively exploited vulnerability. Your scanner says it's clean

I aimed our scanner at something almost nobody checks: the container images AI coding agents run inside. The current latest images ship a git flaw CISA lists as actively exploited, patched for months, and most scanners won't tell you. Here's why, and what to do about it.

Denis Sota · · 13 min read
Your AI coding agent ships an actively exploited vulnerability. Your scanner says it's clean

I did something boring the other week. Instead of pointing our scanner at customer servers, I aimed it at something almost nobody checks: the container images that AI coding agents run inside. The dev containers, the CI runners, the throwaway sandbox an agent spins up to clone a repo and run it. I pulled the public images and looked. That’s it. No clever technique, no zero-day hunt.

Then a number stopped me.

The current image (the latest tag you’d pull today, not some fossil from 2021) of one of the most popular open-source coding agents ships, right there in the sandbox where it runs your code, a git flaw that CISA lists as actively exploited. A second, equally popular agent ships two of them: that same git bug, plus one in FreeType that’s also being used in real attacks. Neither is a secret. Both have had a patch for months. The images just never picked it up.

The part that got me wasn’t the CVE itself. It’s that most scanners look at that same image and call it clean.

If you only read one block, read this:

  • The current latest image of a widely-used open-source AI coding agent ships an actively-exploited git flaw (CVE-2025-48384, on CISA’s Known Exploited list). A second popular agent ships that plus an exploited FreeType bug (CVE-2025-27363).
  • Most version-based scanners miss it: the distro back-ports the fix without changing the version number they read.
  • It’s reachable precisely where you’d assume it isn’t: an agent (or a CI runner) that clones untrusted repos while holding your secrets.
  • We told the maintainers privately, so no names yet. But you can check your own image in 30 seconds, the command’s near the bottom.

What I actually did

None of this needs special access, and you can repeat every step. I pulled the public images (only public images, pulled legitimately: you’re analysing a file you downloaded, not touching anyone’s systems), listed the packages that are really installed, and compared each version against the one the distribution shipped the fix in, not the “upstream” number. Then I kept only what’s genuinely exposed: cross-checked against CISA’s Known Exploited list and against whether the distro had already back-patched it.

On the current tags, the pattern was consistent. The application image of an agent, the part that runs the logic, is mostly clean. The runtime images, the ones where code actually gets executed, are the bad ones: a couple hundred packages behind on security updates, and sitting in that pile, one or two CVEs that are being exploited right now.

To make it concrete, without naming anyone before the fixes ship: across the public images I pulled, several hundred OS packages were behind their distribution’s security fix. Run a raw scanner over the same images and around ten CVEs from CISA’s actively-exploited list light up, but nearly all of them are Linux-kernel bugs, and a container can’t be attacked through those: it borrows the host’s kernel, it never runs the one baked into the image. Strip the kernel noise and what’s left is what actually matters here: the git and FreeType flaws, reachable in userspace while the agent does its normal work. One runtime image on Debian 12 was still shipping git 1:2.39.2-1.1, months after the distro published the fix in 1:2.39.5-0+deb12u3. Another, on Ubuntu 22.04, shipped git 1:2.34.1-1ubuntu1.11 against a fix in …1ubuntu1.13, plus FreeType 2.11.1+dfsg-1ubuntu0.2 against …0.3. And it wasn’t unavoidable: a different agent built on the same Debian 12 base already ships the fixed git. The patch was right there on the shelf. The vulnerable images just never picked it up.

SentriKat multi-client console: two agent runtime images with 21 and 13 open critical findings, the app build has 2.
SentriKat (Professional), anonymised. The two agent runtime images, where code runs, carry 21 and 13 open critical findings; the current app build has 2. NIS2/DORA readiness is red across the board.

Say it out loud, because it’s the whole point: this is the latest tag. Not a forgotten pin.

The two bugs, in plain words first, then properly

Why should a CVE in a sandbox scare you? It depends, and I’ll get to that. First, what they are.

git, CVE-2025-48384. The clone that gets you.

Plain version: you clone a repo just to look at it. You don’t run it, you don’t build it, you pull it and that’s it. It should be as inert as opening a zip. It isn’t. If that repo has submodules, an attacker can hide an invisible character, a carriage return, in the way they’re written, and it sends git off to write a file where it shouldn’t. Like a script that runs itself. Clone a repo that pulls those submodules in, and you can end up running their code. Linux and macOS only; Windows is immune.

The technical bit: git strips a trailing carriage return when it reads a config value, but doesn’t quote it when it writes one, so the CR gets lost on the next read. A malicious .gitmodules with a submodule path ending in \r, plus a symlink, turns that into an arbitrary file write and code execution. It triggers when submodules get initialised (git clone --recurse-submodules, or git submodule update), which is the default in a lot of CI and agent flows. CVSS 8.1. CISA gave U.S. federal agencies a hard deadline to fix it.

FreeType, CVE-2025-27363. The font that opens the door.

In plain terms: FreeType is the library that draws text, thousands of programs use it quietly to render fonts, make PDFs, generate thumbnails. A font is “just data”, right? With this bug, a font built the wrong way on purpose makes the program write past its own memory, and that can hand control to the attacker. You only have to parse it.

Under the hood: parsing subglyphs in TrueType GX / variable fonts, a signed short gets assigned to an unsigned long, the heap buffer comes out too small, and up to six longs get written past the end of it: memory corruption, control-flow hijack, remote code execution. Everything up to and including FreeType 2.13.0. CVSS 8.1, on CISA’s exploited list since May 2025.

The finding in the product: git flagged EXPLOITED with a public PoC on the current latest image.
The finding, in the product (anonymised "Runtime B"). The installed git is flagged EXPLOITED with a public PoC: an actively-exploited CVE on the current latest image, caught by comparing the installed version against the distribution's back-ported fix.

Why you’d miss it: latest doesn’t mean “safe”

Here’s the trap. latest doesn’t mean “up-to-date packages,” it means “the most recent build.” If whoever built the image didn’t rebuild on a fresh base or run apt-get upgrade, then latest hands you OS packages frozen on the day it was assembled, with every CVE that’s piled up since.

And there’s a second trap, this one on the scanners. Debian and Ubuntu fix CVEs without bumping the upstream version number: the patch goes into a string like +deb12u3, while the 2.39.2 out front stays put. A tool that reads the upstream number does one of two wrong things. It either screams, hundreds of “vulnerable” packages that are actually already patched, so you tune the whole thing out, or it trusts the number and reports zero, which is worse, because you’re sitting on +deb12u2 and you’re genuinely exposed. The real answer is in the middle, it’s small, and it includes the one that’s being exploited.

We compare on the distribution’s own axis, back-port aware, which means using the distro’s own version metadata rather than a naive semantic-version compare. That’s the only way that, out of 200-odd packages “behind,” exactly one comes out wearing the label that matters: exploited, unpatched, right here.

Two other scanners back this up, and can’t agree on much else

I didn’t want this resting on our tool alone, so I pointed two well-known open-source scanners, grype and trivy, at the same images. Two things jumped out.

First, they barely agree with each other. On one image, grype flagged 6 OS packages as critical or high; trivy flagged 360 on the identical bytes. A 60x spread between two respected tools, same image, same day. When the number itself swings that hard, the number was never the thing to act on.

Second, and this is the part that matters: buried in every one of those scans, grype’s and trivy’s alike, were the same two actively-exploited CVEs. Two independent tools, their own numbers, and both carried the exact bugs we flagged. The signal was there the whole time. It was just drowned in thousands of findings. This isn’t “the other scanners are wrong.” It’s that counting vulnerabilities is noise, and the job is adjudication: pull the exploited handful to the top on KEV and EPSS, back-port aware, and leave the rest where it belongs.

”But it’s a throwaway sandbox”: when that holds, and when it doesn’t

It’s the obvious objection, and it’s exactly where these write-ups usually oversell. So let me be straight.

If the sandbox is genuinely disposable, isolated, and holds no secrets, then yeah, the git RCE doesn’t buy an attacker much. That container runs arbitrary code by design; it’s the whole job. We say that plainly.

But in a lot of real setups, “disposable and isolated” doesn’t hold. Here’s where it actually bites:

Attack chain: the agent works on your project, clones an untrusted repo, a crafted submodule fires the CVE, attacker code runs where your keys are.
The reachable path. Ephemeral doesn't mean secret-free, the container is holding your token while it works. And a self-hosted CI runner built on the same image isn't ephemeral at all.
  • Disposable isn’t the same as empty. While the agent works your task, that container is holding your stuff: the git token in the remote, mounted SSH keys, environment secrets, the network. If hostile code runs in there, the secrets leave while the container is alive. It getting torn down five minutes later doesn’t hand them back.
  • Cloning isn’t reading. Everyone, developers, CI, agents, clones untrusted repos “just to look,” assuming it’s inert. This bug breaks that assumption: a submodule checkout of a hostile repo runs code without you building or launching a thing.
  • The not-disposable cases. A self-hosted CI runner on one of these images is persistent and stuffed with real secrets: deploy tokens, cloud keys. A pull request from a fork kicks off a recursive checkout, and there’s your RCE on the runner with the keys, no approval needed. That’s the “runner as a backdoor” class, and it’s shown up in real incidents.

Many of these self-hosted agents fall on the wrong side of that line: they’re built to run on your own machines, they run for a while, they touch your code and usually the network. This isn’t Google’s throwaway sandbox.

This is really a supply-chain problem

You pull a published image and inherit every unpatched, already-exploited component inside it. Not the exotic kind, nobody poisoned a build. The common kind: an artifact that was never rebuilt. And an AI agent makes it sharper, because the agent is itself a privileged link in your chain, it pulls untrusted code and runs it while holding your secrets. So a vulnerable git in that image isn’t a dusty CVE. It’s a live entry point into your pipeline.

How common is this

It’s not a toy with a dozen users. This is the category that blew up in 2026, agents that write and run code on their own. The leading open-source ones have tens of thousands of GitHub stars, pull eight-figure funding rounds, and are built to be installed on your own machines. The base images underneath them (debian, ubuntu, node, python) are among the most-pulled on Earth, billions of times over. One of them, not rebuilt, times every developer, every build, every agent session.

We told the maintainers first

Before publishing, we did the decent thing: privately flagged it to the maintainers of the projects involved, with which exploited CVEs their current images ship and how to close them, in most cases a rebuild does it. That’s why we’re not naming them here. We’re not interested in dragging an open-source project; these are good tools that a lot of people rely on. We care about the pattern: if it happens to the best-run, most-watched projects, it happens to everyone. When they’ve had time to fix it, we’ll come back with the details, ideally writing “already fixed.”

Check your own image in 30 seconds

You don’t need us for this part. Pull the image your agent or CI actually uses, and ask its own package database what git it ships:

docker run --rm --entrypoint dpkg-query <your-image> -W -f '${Version}\n' git

If that version is below your distro’s fix, the image is carrying the exploited CVE. Ubuntu 22.04 fixed CVE-2025-48384 in 1:2.34.1-1ubuntu1.13; Debian 12 in 1:2.39.5-0+deb12u3. The same check works for libfreetype6 and CVE-2025-27363. It takes longer to read this paragraph than to run it.

What to do on Monday

Three moves, in the order that matters.

  1. Don’t trust the tag. latest is a build date, not a guarantee. Rebuild your images on a schedule; if you pin, pin to a digest and have a rebuild process.
  2. Adjudicate, don’t count. Filter on KEV + EPSS + the distro’s back-port status, not the raw version number. It’s the only way to skip the noise without falling asleep on a false “all clear.”
  3. Treat the agent’s box like production. SBOM it, scan it, and think about the vector: if that container holds your secrets or lives on a persistent runner, the CVE isn’t hypothetical.

The check itself is trivial to automate, we do it with SentriKat in one step: point it at the image and it tells you the residual that’s actually exposed, back-port aware, even offline. But the method above is public and you can run it with free tools. Whether you use us or something else honestly doesn’t matter. What matters is that someone actually looks, because almost nobody is looking at these environments yet.


Sources & method

Public images analysed locally on 2026-07-20 (UTC); package inventory via dpkg / CycloneDX SBOM; native per-distro (dpkg/rpm) version comparison, back-port aware; each candidate adjudicated against CISA KEV. latest tags are mutable, so the named follow-up will pin every image by sha256 digest alongside the full disclosure timeline.

Ready to automate your vulnerability management?

Deploy SentriKat on-premises in minutes. Track CISA KEV vulnerabilities, generate NIS2 compliance reports, and protect your infrastructure.

Request a Demo