🪟 Windows TippsModify Windows Support Phone Number with PowerShell(03.09.2026 um 00:00 Uhr)
🔧 AI Nachrichten Podcast: ChatGPT schwatzt Nutzern in Deutschland jetzt Werbung auf(28.08.2026 um 08:46 Uhr)
🪟 Windows TippsMicrosoft bringt Emoji 17.0 auf Windows 11(31.08.2026 um 08:16 Uhr)
🪟 Windows TippsModify Windows Support Phone Number with PowerShell(03.09.2026 um 00:00 Uhr)
🔧 AI Nachrichten Podcast: ChatGPT schwatzt Nutzern in Deutschland jetzt Werbung auf(28.08.2026 um 08:46 Uhr)
🪟 Windows TippsMicrosoft bringt Emoji 17.0 auf Windows 11(31.08.2026 um 08:16 Uhr)

🔧 Programmierung 🕛 vor 3 Monaten 8 Min Lesezeit CVE-2026-25223
0

I gave Gemini 3.5 Flash a CVE-fix PR to review. It found another bug in the same file.

Cyber Threat & Vulnerability Dossier CVSS 9.5 CRITICAL (Heuristik) EPSS 86%
ANGRIPPSVEKTOR
🌐 Netzwerk (Remote)
AUTHENTIFIZIERUNG
🔓 Keine Authentifizierung nötig
SCHADENSPROFIL
RCE / Vollzugriff / Full Compromise
CWE-KLASSIFIZIERUNG
CWE-94: Code Injection
Handlungsempfehlung: Sicherheits-Update des Herstellers zeitnah einspielen und Netzwerksegmentierung prüfen.
Im CVE-Radar öffnen
↗ Quelle (dev.to)
🔬 IoC Intelligence (1 Indikatoren erkannt)
CVE-2026-25223
🗣️ Stimme:
📑 Inhaltsübersicht

This is a submission for the
Small refactor
~10
Baseline: clean code, no real issues



Small refactor
~15
Different file, different style







Final scorecard






CODE
PR #1 (express#6190):    +0  −0   Model agreed: no issues
PR #2 (fastify#6414): +3 −0 3 hits, 0 hallucinations
PR #3 (express#6100): +0 −0 Model agreed: no issues
──────────────────────────────────────────────────────────────
Total: +3 −0 Zero false positives.









What it caught — the headline



PR #2 is the one that mattered. Fastify pull #6414 rewrote the entire content-type parser to fix a security flaw (CVE-2026-25223) where attackers could bypass body validation by appending a tab character to Content-Type (e.g. application/json\tx). The fix introduced a new ContentType class and replaced the old loose string-matching logic.



This is exactly the kind of high-stakes, security-sensitive refactor where an automated reviewer either earns its place or doesn't.



The model flagged three issues. Here's each one, verified against the actual code.






Hit 1: inconsistent variable use in existingParser




MEDIUM · logic — The existingParser method checks contentType === "application/json" and this.customParsers.has(contentType) using the original contentType string instead of the newly calculated, normalized ct variable.




Looking at the new code in lib/content-type-parser.js:




CODE
ContentTypeParser.prototype.existingParser = function (contentType) {
if (typeof contentType === 'string') {
const ct = new ContentType(contentType).toString()
if (contentType === 'application/json' && this.customParsers.has(contentType)) {
return this.customParsers.get(ct).fn !== this[kDefaultJsonParse]
}
if (contentType === 'text/plain' && this.customParsers.has(contentType)) {
return this.customParsers.get(ct).fn !== defaultPlainTextParser
}
}
return this.hasParser(contentType)
}






The model is right. ct is the normalized version, but the conditional guards still test the raw contentType. Since customParsers only holds normalized keys (see line 85: this.customParsers.set(normalizedContentType, parser)), any header with a different case or trailing parameters silently skips the fast path. Subtle, easy to miss in review.






Hit 2: a regex missing its end anchor




HIGH · security — The subtypeNameReg regular expression is missing a trailing $ anchor. Consequently, any string starting with a valid subtype will match successfully.




This one is the headline. In the brand new file lib/content-type.js, the patch defines two parallel regexes:




CODE
const typeNameReg     = /^[\w!#$%&'*+.^`|~-]+$/      // has $
const subtypeNameReg = /^[\w!#$%&'*+.^`|~-]+\s*/ // no $






The subtype regex anchors at the start but not at the end. Inputs like application/json/extra pass the validation gate where they shouldn't. In a PR whose entire purpose is fixing a validation-bypass CVE, a senior reviewer would put this in red on the first pass. The model put it in HIGH on the first pass.



I am not claiming this is itself exploitable at the same severity as the original CVE — the downstream parsers may not be reachable in a way that materializes the bug. But the pattern is exactly the class of issue that did materialize as CVE-2026-25223. Pattern-recognition of dangerous shapes is half of what code review is.






Hit 3: stateful global regex




MEDIUM · bug — The keyValuePairsReg regex is defined globally with the /g flag. Because of this, it is stateful and relies on lastIndex. If parsing throws an exception or future modifications exit the loop early, lastIndex will not reset to 0.




Confirmed at the top of lib/content-type.js:




CODE
const keyValuePairsReg = /([\w!#$%&'*+.^`|~-]+)=([^;]*)/gm






Used inside a class constructor with .exec() in a loop. In healthy execution, lastIndex resets to 0 when exec returns null. But the failure mode — exception inside the loop body, or any future break — silently corrupts every subsequent parse for the lifetime of the process. The model's suggested fix (use matchAll instead) is exactly the JavaScript-idiomatic answer.



This is a latent footgun, not a live bug. Severity MEDIUM is arguably high. But it's a real thing the model saw.






What it didn't catch — the honest part



Two failure modes worth being honest about.



Cross-file context. The model only sees the diff. It can't tell whether a function called by the changed code is safe, whether a removed branch was load-bearing somewhere else, or whether tests actually cover the new behavior. For PR #6414 in particular, the upstream callers of the new ContentType class are not in the diff, and the model never reasoned about them.



Severity calibration is rough. The regex-without-anchor is HIGH. The stateful /g is MEDIUM. In practice, those probably want to swap — the regex one is a clear pattern with security relevance, the global-regex one is a latent footgun unlikely to fire. Junior-reviewer instincts.



I also can't conclusively measure what the model missed without reviewing every comment thread on the PR by hand. The merged commit went through multiple rounds of feedback (commits like "address feedback", "refactor algorithm", "appease coverage"), so reviewers did catch things, but how many of those are in-diff issues a tool could have seen versus broader design decisions — I'd need another afternoon to know.






What I'd actually use this for



Three takeaways after running this on real code:





  1. It earns a place as a first-layer pre-review. Specifically: PRs that touch parsers, validators, or anything that consumes external input. The cost is around $0.003 per PR. The cost of not running it is shipping a regex without an anchor on a security-sensitive code path.


  2. It does not replace human reviewers. It cannot reason about distributed state, concurrency, transactions, or anything that requires understanding multiple files in concert.


  3. Hallucination rate was zero in this sample — but the sample is tiny. The literature on similar models suggests false positives in the 15-25% range on real-world PRs. Three out of three being valid is great but is not a benchmark.



The 80 lines of TypeScript that produced this run are on GitHub. Two things that are non-obvious about the setup:





  • @google/genai v2 uses responseJsonSchema, not responseSchema. Easy to get wrong if you're translating tutorial code from an older Gemini.

  • Public GitHub PRs expose a .diff endpoint that requires no auth. You don't need octokit for an MVP.



If you try it on PRs with shapes I didn't test — concurrency-heavy, multi-file, generated code — tell me what you find. The interesting question is where the model breaks, not where it works.






Built and tested in May 2026 with Gemini 3.5 Flash, GA two days before publication.

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:
Community Threat-Level Barometer
Live Votum

Wie stufst du das Risiko dieser Schwachstelle / Bedrohung für dein Unternehmen ein?

Noch keine Stimmen — schätze das Risiko als Erster ein.

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Modify Windows Support Phone Number with PowerShell
1 Quelle
Die Zukunft des Einkaufens: Warum wir ein neues Kapitel aufschlagen (und wie du es mitschreiben kannst)
1 Quelle
ZDE Podcast 251: Wie sieht digitales Instore Marketing 2026 aus, Amit Chatterjee?
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten I gave Gemini 3.5 Flash a CVE-fix PR to review. It found another bug in the same file.

Thematisch verwandte Begriffe: gave, Gemini, Flash, CVEfix · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...