⏱️ Lectura: 12 min
An open source maintainer publishes the patch for a security bug and, ten minutes later, is already getting automated probes hitting his server with the exact pattern of the exploit. That’s how Anil Madhavapeddy, maintainer of the OCaml library cohttp, describes what happened to him last week: you no longer need a public exploit to get attacked, a mere rumor that a bug exists is enough.
📑 En este artículo
The case exposes a phenomenon that a recent paper named bugonomics: AI agents that turn any clue (a commit, an email thread, a pull request) into a working exploit within minutes, long before a formal public advisory exists.
TL;DR
- The average time to exploit a vulnerability is now -7 days: the exploit arrives before the public patch.
- In 2018-2019 that average was 63 days; it crossed zero in 2024, according to the data Anil Madhavapeddy cites.
- A study by Fang et al. found that a GPT-4 agent exploited 87% of a benchmark of 15 vulnerabilities when given the CVE description, versus just 7% without it.
- The cohttp (OCaml) maintainer received path traversal probes just 10 minutes after opening the public pull request for the patch.
- The marimo vulnerability CVE-2026-39987 went from advisory to first exploitation attempt in 9 hours, with no public PoC.
- Langflow CVE-2026-33017 took 20 hours between the advisory and the first mass exploitation attempt.
- A May 2026 paper coined the term bugonomics: the bottleneck is no longer finding bugs, but maintainers’ capacity to validate and patch them.
- Project Glasswing already covers 150 organizations in 15 countries, but small projects like cohttp still lack equal access to frontier models.
Introduction: what is bugonomics
Anil Madhavapeddy maintains MirageOS and cohttp, the most widely used HTTP library in the OCaml ecosystem. The bug he reported was a classic case of path traversal: an improperly validated file path that allows an attacker to escape the expected directory. Nothing exotic, a type of flaw documented for decades.
What’s different isn’t the bug, it’s the speed at which it went from rumor to working exploit. That’s bugonomics: the inverted economy where building an exploit is now cheaper and faster than defending against it. It’s not a problem exclusive to OCaml, it applies to any ecosystem with a public history: npm, PyPI, crates.io, any repository on GitHub.
What happened
The report came in privately, through a Slack channel shared with Jane Street, and whoever reported it had found it using Claude Fable. Before reviewing the patch in detail, Madhavapeddy asked his own agent to investigate path normalization issues in the same code. Fable refused: the model’s safety block requires access to Project Glasswing, which Madhavapeddy doesn’t have.
DeepSeek V4 Pro had no such reservations. The model found several related issues and, in under a minute, generated an exploit capable of testing a live local server. That’s the most uncomfortable detail of the case: building the exploit took less time than writing the security advisory.
After coordinating a fix with whoever reported the bug, Madhavapeddy opened the pull request publicly in the cohttp repository. Under normal circumstances, that step takes a few days of review and a release within one or two weeks. In this case, ten minutes after opening the PR, his server was already receiving probes with percent-encoded traversal sequences like %2e%2e%2f (the equivalent of ../). Someone, or something, was already testing the exact pattern of the newly published bug.
⚠️ Heads up: if it took you a minute to build the exploit on your own machine, a ten-minute window for the first automated probe in production is actually a lot of time.
sequenceDiagram
participant M as Maintainer
participant PR as Public Pull Request
participant IA as AI Agent
participant S as Production Server
M->>PR: opens the security patch
PR-->>IA: the bug rumor becomes visible
IA->>IA: generates an exploit in under a minute
IA->>S: sends probes with encoded paths
Note over M,S: the first probes arrive within 10 minutes
Context and history
The cohttp case isn’t isolated, it’s the visible tip of a measured trend. According to the data Madhavapeddy compiles, the average time between the publication of an advisory and the first exploitation attempt was about 63 days in 2018-2019. That number crossed zero in 2024, and today, in 2026, it stands at -7 days: on average, exploitation now begins before a public patch even exists.
A study by Fang and colleagues quantified where that jump comes from: a GPT-4-based agent, given access only to a CVE description, exploited 87% of a 15-vulnerability benchmark. Without that description, the same agent only reached 7%. The gap between those two numbers is, literally, the value of a rumor: knowing something exists and where to look is enough.
Recent examples confirm the pattern. The marimo vulnerability CVE-2026-39987 went from advisory to first exploitation attempt in 9 hours, with no public proof-of-concept in existence. Langflow CVE-2026-33017 took 20 hours. Cohttp, with no formal advisory yet and only an open pull request, took 10 minutes.
| Case | Time to first exploitation attempt | Was there a public PoC? |
|---|---|---|
| Historical average (2018-2019) | 63 days after the advisory | Yes, in most cases |
| Current average (2026) | -7 days (before the patch) | Not necessarily |
| marimo CVE-2026-39987 | 9 hours from the advisory | No |
| Langflow CVE-2026-33017 | 20 hours from the advisory | No |
| cohttp (OCaml) | 10 minutes from the public pull request | No, not even a formal advisory |
Technical details and performance
A path traversal happens when a server builds a file path by directly concatenating a value that comes from the user, without normalizing sequences like ... If the server doesn’t verify that the resulting path stays within the expected directory, an attacker can request ../../etc/passwd (or its encoded version, %2e%2e%2f) and read files outside that directory.
This is how simple the bug looks in a poorly written static file server:
let read_static_file base_dir requested_path =
let full_path = base_dir ^ "/" ^ requested_path in
read_file full_path
(* requested_path = "../../etc/passwd" escapes base_dir unchecked *)
The real fix isn’t just filtering out dots: you need to resolve the path to its canonical form and confirm the result stays within the base directory before touching disk:
let read_static_file base_dir requested_path =
let candidate = Filename.concat base_dir requested_path in
let resolved = Unix.realpath candidate in
let base_resolved = Unix.realpath base_dir in
let dentro_del_base =
String.length resolved >= String.length base_resolved
&& String.sub resolved 0 (String.length base_resolved) = base_resolved
in
if dentro_del_base then read_file resolved
else raise (Invalid_argument "path traversal detected")
What DeepSeek V4 Pro ran for Madhavapeddy was, in essence, the automated version of finding the first pattern that doesn’t resolve paths across an entire repository, in a matter of seconds, and then building an HTTP client on top of it that tests encoded payload variants until it finds one the server doesn’t filter. That’s what took less than a minute: not writing the exploit from scratch, but having a model with access to the diff and the repository’s history generate and test variants until it lands on the one that works.
Getting started: auditing your own logs
You don’t need to be cohttp to be exposed to the same pattern. Any server that serves files, profile images, or templates can have the same bug. The first and cheapest step is checking whether you’ve already received probes:
grep -E "%2e%2e%2f|%252e%252e|\.\./\.\./" /var/log/nginx/access.log | tail -n 50
That command searches for the most common encoded traversal variants (single and double encoding) in the nginx access log. If you see repeated lines with 400 or 403 codes from the same IP, you already have an active probe, whether or not there’s a real bug to exploit.
To mitigate while the patch is being applied, a dedicated fail2ban jail cuts the noise quickly:
[cohttp-traversal]
enabled = true
port = http,https
filter = cohttp-traversal
logpath = /var/log/nginx/access.log
maxretry = 3
bantime = 3600
This doesn’t replace the patch (it never replaces the patch), but it reduces the window for automated probing while the fixed version is reviewed and released.
Impact and analysis: the defender is the bottleneck
The traditional security process assumes a vulnerability can be embargoed: it gets fixed privately, affected parties are notified, and only then is it published. That model depended on the secrecy of the technical detail buying time. The numbers in this article show that time barely exists anymore: an agent with a vague clue and access to a repository’s history can do its own research.
A May 2026 paper gave this a name: bugonomics. Its central argument is that the bottleneck is no longer generating exploits (models do that, faster and cheaper all the time), but the defender’s remediation capacity: how much a human maintainer can validate, prioritize, and ship with the time and tools they have.
💭 Key point: the question isn’t whether the frontier model, the open model, or static program analysis wins. The question is how to orchestrate them so that a maintainer’s limited validation and release capacity gets spent on durable fixes, not on writing reports.
There’s also an uncomfortable asymmetry. Claude Fable denied Madhavapeddy, a legitimate maintainer trying to audit his own code, access due to a lack of Project Glasswing authorization. DeepSeek V4 Pro, without that same control, helped him without issue. Project Glasswing has already expanded to 150 organizations in 15 countries, but a small project like cohttp is still left out of the privileged access circuit, while anyone with an account on a less restricted model can search for exploits on the same public repository without asking permission.
Large companies have already adapted in their own way: Google pushes microupdates directly to its products, without relying on the repository’s release cycle. Projects like OCaml or Docker don’t have that luxury: they don’t control the endpoint where their software runs, and distributions package and release on their own schedules.
What’s next
Madhavapeddy is clear that manual triage shouldn’t disappear, but he acknowledges an unsustainable increase in automated activity since models like Fable came out. There’s still no consensus on how much of the incoming traffic to any popular repository is now generated by machines hunting for the next bug, but based on what he describes, it’s obviously a lot.
What’s most likely in the short term: shorter embargo processes, or dropping them altogether in favor of fixing and publishing immediately, investment in in-house agents that audit code before an attacker does, and pressure for small projects to get the same access to frontier models that large organizations already have through programs like Glasswing.
📖 Summary on Telegram: View summary
Try it yourself: run the encoded traversal grep against your own access logs from the past week and check whether you’ve already gotten a probe with the %2e%2e%2f pattern.
Frequently Asked Questions
What is bugonomics?
It’s the term a May 2026 paper used to describe a scenario where generating an exploit is now faster and cheaper than a maintainer’s ability to validate and patch it, inverting the traditional logic of offensive and defensive security.
What is a path traversal attack?
It’s a bug where the server builds a file path using user-supplied data without normalizing sequences like .., which allows reading or writing files outside the directory the server should expose.
Why is the average exploitation time now negative?
Because on average automated exploitation attempts now start before the patch is publicly available: AI agents generate and test exploits as soon as they detect a clue, like a commit, a pull request, or a discussion thread, about a possible bug.
Do security embargoes still work?
Their effectiveness has dropped a lot. The assumption that keeping technical details secret buys time no longer holds when an agent can investigate the code on its own from a minimal clue, as happened with cohttp.
What is Project Glasswing?
It’s the program that gives authorized maintainers and organizations access to frontier models without the safety restrictions that block their use for one’s own offensive research; according to Madhavapeddy, it already covers 150 organizations in 15 countries.
How do I protect my open source project from this kind of probing?
Audit your own access logs for encoded traversal patterns, apply temporary mitigations like a fail2ban jail while you prepare the patch, and validate any file path by resolving it against the base directory before using it.
References
- Anil Madhavapeddy: Just a rumour of a bug is enough to find a security exploit these days: the original article with the cohttp case and the data cited in this piece.
- cohttp repository on GitHub: the OCaml HTTP library maintained by Anil Madhavapeddy and the Mirage project.
- NVD: CVE-2026-39987: official record of the marimo vulnerability mentioned in the article.
- NVD: CVE-2026-33017: official record of the Langflow vulnerability mentioned in the article.
- OWASP: Path Traversal: reference explanation of this type of vulnerability.
📱 Like this content? Follow @programacion on Telegram for daily tech content in Spanish: quick summaries, fresh content every day.
0 Comments