Four CVEs in a week, all the same shape: when agents execute LLM-generated code

Dev.to / 5/7/2026

💬 OpinionDeveloper Stack & InfrastructureSignals & Early TrendsIndustry & Market MovesModels & Research

Key Points

  • NVDは2026-05-04〜2026-05-06にかけて、LLM(エージェント)が出力を生成し、それを検証せず特権的な実行先に投入して実行することで成立する同型の脆弱性が4件(CVE)報告されたことを明らかにした。
  • 対象はSQLBot、PPTAgent、Evolver、Difyで、いずれもOWASP LLM05(Improper Output Handling)に該当し、プロンプト側の対策だけでは検知・抑止が難しい構造になっている。
  • 具体的には、PostgreSQLのCOPY FROM PROGRAMによるRCE、Pythonのeval()、シェルコマンド文字列連結によるexecSync()、未認証SVGアップロードによるDOMでのアクティブコンテンツ実行など、出力の扱いが攻撃面となっている。
  • 記事は「LLM安全策はプロンプト注入だけに偏りがちだが、出力処理(シンク側)の構造的ガードが本質的」と主張し、単一のプローブでこれらを検出できると述べている。

Between 2026-05-04 and 2026-05-06, NVD published four CVEs against AI/agent projects that share a single shape: an LLM produces output, the application drops that output into a privileged execution sink without re-validation, and the sink runs it.
Affected: SQLBot ≤1.7.0 (text-to-SQL → PostgreSQL COPY FROM PROGRAM RCE), PPTAgent < commit 418491a (Python eval() of LLM-generated code), Evolver < 1.69.3 (shell command construction via string concat), Dify < 1.13.1 (unauthenticated SVG XSS upload). All four are detectable by a single probe class — improper output handling, OWASP LLM05 — yet the framing in most "LLM safety" tooling still concentrates on the prompt side.
Read the full piece on the canonical: https://www.at-helper.com/blog/four-cves-in-a-week-all-the-same-shape-when-agents-execute-llm-generated-code
Why I'm cross-posting an excerpt instead of the full article
Dev.to's renderer doesn't handle base64-inlined SVG diagrams cleanly, and the canonical version has a 2-row control-placement diagram that carries the central argument visually. Rather than paste a degraded copy here, I'm leaving the full version (with figure, full code samples, and the per-CVE breakdown table) on the canonical URL. Below is the argument in compressed form, plus the reproduction steps so you can run the probe yourself.

The structural similarity
Four projects, four maintainer teams, four codebases, four review processes — and the same defect:

CVE Project Sink LLM-side trigger
CVE-2026-33324 SQLBot ≤ 1.7.0 PostgreSQL COPY FROM PROGRAM → RCE Text-to-SQL emits SQL that runs unvalidated
CVE-2026-42079 PPTAgent < 418491a eval() of LLM output with builtins in scope LLM asked to produce Python expression for slide layout
CVE-2026-42076 Evolver < 1.69.3 execSync() of curl ${corpus_param} LLM-driven function constructs shell command from corpus param
CVE-2026-42138 Dify < 1.13.1 Unauthenticated SVG upload renders inline Upload accepts unrestricted file type; SVG renders with active content in DOM
All four are OWASP LLM05 (Improper Output Handling) — distinct from LLM01 (Prompt Injection) precisely because the failure mode is downstream of the model. A prompt-side guardrail tuned to flag injection attempts produces zero alerts on these four, because the user's prompt isn't malicious. The output is the attack surface, and the attack only lands at the sink.

What "right placement" looks like
For each sink, the control is structural, not statistical:

SQL sink: parameterized queries plus an allowlist of statement types. COPY FROM PROGRAM shouldn't be reachable from the LLM-driven path under any circumstances; that's a database-role decision.
Python eval sink: there is no safe eval() of untrusted input. The PPTAgent fix is the right shape (ast.literal_eval + a small whitelist of expression types). If the agent genuinely needs to execute LLM-generated code, run it in a sandbox with separate process boundary, no network, no filesystem.
Shell sink: execFile/spawn with arg arrays, not exec/execSync with concatenated strings. This is a 1990s-era bug class; the LLM is just a new way to inject the metacharacter.
DOM sink: server-side sanitization of LLM-influenced content before render, plus CSP headers. SVG specifically should be processed through a sanitizer like DOMPurify configured with USE_PROFILES: { svg: true }.
None of these are AI-specific. They're the application security playbook from before LLMs existed, applied at the seam where LLM output meets a privileged sink.

Reproduce the probe class against your own agent
Single command sequence for any Anthropic-API-compatible target:

curl -fsSL https://github.com/gy15901580825/at_helper_cli/releases/download/v0.1.1/athelper-probe-linux-x86_64 \
-o athelper-probe && chmod +x athelper-probe
./athelper-probe init --kind anthropic_native --out target.json
./athelper-probe run --target target.json --probes owasp_05_improper_output_handling
Other supported --kind values: openai_compat, custom_http, grpc, browser_use. The browser_use kind exposes the browser_os_cmd_* probe set, which exercises the agent's shell-tool path against synthetic command payloads (no real exfiltration).

Probe yamls are open-source under Apache-2.0 at https://github.com/gy15901580825/probes (transferring to athelper-research/probes once that org is provisioned).

Read the full version
The canonical includes the full "what we tried that didn't work" section (4 failed defenses with engineering rationale), the control-placement diagram, and a 15-probe sample run against Claude Sonnet 4.6 with all 39 results visible:

https://www.at-helper.com/blog/four-cves-in-a-week-all-the-same-shape-when-agents-execute-llm-generated-code

Sample report (raw output, no commentary): https://media.at-helper.com/samples/redteam-claude-sonnet-4-6-owasp-top10.html

If you find a fifth CVE this month with the same shape, I'd genuinely like to hear about it — DM or comment.

Yang Gao runs ATHelper, a reliability and security platform for AI agents. The probe set referenced is part of ATHelper's open-source library; ATHelper itself is the runner that loads them.