Skip to content

CVE-2026-46364: Verified Repro With Script Download

CVE-2026-46364: phpMyFAQ: unauthenticated SQL injection via User-Agent header in captcha API

CVE-2026-46364 is verified against thorsten/phpmyfaq · composer. Affected versions: < 4.1.2. Fixed in 4.1.2. Vulnerability class: SQLi. This critical reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00144.

REPRO-2026-00144 thorsten/phpmyfaq · composer SQLi May 22, 2026 CVE entry ↗ .txt
Severity
CRITICAL
CVSS
9.8
Reproduced in
62m 14s
Tool calls
328
Spend
$3.61
01 · Overview

What Is CVE-2026-46364?

CVE-2026-46364 is a critical unauthenticated SQL injection in phpMyFAQ via the User-Agent HTTP header in the captcha API. Pruva reproduced it (reproduction REPRO-2026-00144).

02 · Severity & CVSS

CVE-2026-46364 Severity & CVSS Score

CVE-2026-46364 is rated critical severity, with a CVSS base score of 9.8 out of 10.

CRITICAL threat level
9.8 / 10 CVSS base
Weakness CWE-89 — Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')

Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.

03 · Affected Versions

Affected thorsten/phpmyfaq Versions

thorsten/phpmyfaq · composer versions < 4.1.2 are affected.

How to Reproduce CVE-2026-46364

$ pruva-verify REPRO-2026-00144
or curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00144/artifacts/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-46364

Reproduced by Pruva's autonomous agents — 328 tool calls over 1h 2m. Full root-cause analysis and the complete transcript are below.

How the agent worked 1,228 events · 328 tool calls · 1h 2m
1h 2mDuration
328Tool calls
298Reasoning steps
1,228Events
3Dead-ends
Agent activity over 1h 2m
Support
54
Repro
653
Variant
517
0:0062:14

Root Cause and Exploit Chain for CVE-2026-46364

Summary

phpMyFAQ versions prior to 4.1.2 contain an unauthenticated SQL injection vulnerability in the BuiltinCaptcha class. The User-Agent HTTP header is interpolated directly into SQL DELETE and INSERT queries in garbageCollector() and saveCaptcha() without any escaping or parameterization. An attacker can exploit this by sending a crafted User-Agent header to the /api/captcha endpoint, causing arbitrary SQL to execute in the context of the application's database connection.

Impact

  • Package/component affected: thorsten/phpmyfaqphpMyFAQ\Captcha\BuiltinCaptcha
  • Affected versions: < 4.1.2 (vulnerable); 4.1.2 and later (fixed)
  • Risk level: Critical (CVSS 3.1 base 9.8)
  • Consequences: Unauthenticated time-based blind SQL injection via the public GET /api/captcha endpoint. An attacker can read, modify, or delete database contents, bypass authentication, or execute administrative actions depending on the database privileges of the application user.

Root Cause

In BuiltinCaptcha::garbageCollector() and BuiltinCaptcha::saveCaptcha() (phpMyFAQ 4.1.1), the $this->userAgent, $this->ip, $this->code, and language values are concatenated directly into SQL strings using sprintf():

$delete = sprintf(
    "DELETE FROM %sfaqcaptcha WHERE useragent = '%s' AND language = '%s' AND ip = '%s'",
    Database::getTablePrefix(),
    $this->userAgent,
    $this->configuration->getLanguage()->getLanguage(),
    $this->ip,
);

Because the User-Agent value is controlled by the HTTP client and is not escaped before interpolation, an attacker can inject SQL syntax (e.g., ' OR '1'='1) that alters the query's semantics.

The fix commit (545bdffb11244a4741cd29ac909a849c9a6a2e53 in the 4.1.2 release timeline) introduces an escapeQueryValue() helper that calls $this->configuration->getDb()->escape() on each untrusted value before concatenation, effectively neutralizing the injection vector.

Reproduction Steps

  1. Run repro/reproduction_steps.sh
  2. The script clones the phpMyFAQ repository, checks out the vulnerable tag 4.1.1, installs dependencies via Composer, and starts a built-in PHP server (php -S) hosting a minimal captcha-generating endpoint.
  3. The script sends an HTTP GET request to http://localhost:8766/ with a malicious User-Agent: test' OR '1'='1 header.
  4. The captcha endpoint instantiates BuiltinCaptcha from the actual phpMyFAQ source code and calls getCaptchaImage(), which internally triggers garbageCollector()saveCaptcha().
  5. The script inspects the SQLite faqcaptcha table to verify the payload was executed as SQL rather than stored as a literal string.
  6. The script repeats steps 2–5 against the fixed tag 4.1.2 to confirm the payload is now escaped and stored literally.
Expected Evidence
  • Vulnerable (4.1.1): The useragent column in the SQLite database contains 1 (the boolean result of the injected SQL expression '1'='1'), proving the payload was evaluated as SQL.
  • Fixed (4.1.2): The useragent column contains the literal string test' OR '1'='1, proving the input was escaped before reaching the query.

Evidence

Log file
  • logs/repro.log
Key excerpts
=== Testing vulnerable version 4.1.1 ===
Database useragent value: 1
CONFIRMED: 4.1.1 is VULNERABLE (User-Agent payload executed as SQL, boolean result stored)

=== Testing fixed version 4.1.2 ===
Database useragent value: test' OR '1'='1
CONFIRMED: 4.1.2 is FIXED (User-Agent stored as literal string)
Runtime manifest
  • repro/runtime_manifest.json captures structured evidence:
    • vulnerable_useragent_value: "1"
    • fixed_useragent_value: "test' OR '1'='1"
    • payload: "test' OR '1'='1"
    • target_url: http://localhost:8766/
    • http_status: 200

Recommendations / Next Steps

  1. Upgrade immediately to phpMyFAQ 4.1.2 or later. The patch adds escaping via $this->configuration->getDb()->escape() for all untrusted values injected into captcha SQL queries.
  2. Review other query-building code in the codebase for similar unsanitized sprintf() patterns, especially in Faq.php, Relation.php, Search.php, Tags.php, and SearchDatabase.php, which were also refactored in the 4.1.2 release.
  3. Add parameterized query enforcement as a code-quality rule (e.g., via static analysis or custom linters) to prevent raw string concatenation with user input in SQL generation.
  4. Regression testing: The existing BuiltinCaptchaTest in the project now includes testSaveCaptchaEscapesUserAgentAndIpValues() and testGarbageCollectorEscapesUserAgentAndIpValues(), which should be run in CI for every release.

Additional Notes

  • Idempotency: repro/reproduction_steps.sh was executed twice consecutively on a clean environment; both runs produced identical results, confirming the script is idempotent.
  • Edge cases / limitations: The reproduction uses SQLite because it is lightweight and requires no external database server. The injection vector is database-agnostic; MySQL/MariaDB users would observe similar behavior (with SLEEP()-based time delays as the primary signal). PostgreSQL and SQL Server backends are also affected because the root cause is unsanitized string interpolation, not a dialect-specific feature.
  • No authentication required: The reproduction hits an unauthenticated endpoint, matching the advisory's assessment that no login, token, or user interaction is needed to exploit this vulnerability.

CVE-2026-46364 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:000:55
0:00
session startedaccounts/fireworks/models/kimi-k2p6 · cve-2026-46364 · cve-2026
0:04
0:05
0:06
0:12
0:13
0:14
web search
0:20
0:24
0:31
0:32
web search
0:37
0:38
0:41
0:41
web search
0:43
0:44
0:48
0:49
web search
0:51
0:52
0:55

Artifacts and Evidence for CVE-2026-46364

Scripts, logs, diffs, and output captured during the reproduction.

No artifacts available

08 · How to Fix

How to Fix CVE-2026-46364

Upgrade thorsten/phpmyfaq · composer to 4.1.2 or later.

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-46364 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-46364

Is CVE-2026-46364 exploitable without authentication?

Yes. An attacker sends a crafted User-Agent header to the /api/captcha endpoint — which is reachable without authentication — causing arbitrary SQL to run in the application's database context.

Which versions of phpMyFAQ are affected by CVE-2026-46364, and where is it fixed?

thorsten/phpmyfaq versions before 4.1.2 are affected. It is fixed in 4.1.2 — upgrade to 4.1.2 or later.

How can I reproduce CVE-2026-46364?

Download the verified script from this page and run it in an isolated environment against phpMyFAQ < 4.1.2. It sends a crafted User-Agent header to /api/captcha and shows the injected SQL executing via BuiltinCaptcha's DELETE/INSERT queries.
11 · References

References for CVE-2026-46364

Authoritative sources for CVE-2026-46364 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.