
Scans WordPress Forminator for CVE-2026-15748 unauthenticated RCE. Detects vulnerable sites, crawls forms, extracts nonces, runs safe upload tests.
A Python-based security research and vulnerability assessment scanner for identifying WordPress installations that use the Forminator plugin and assessing version-related exposure.
For Educational & Authorized Testing Only
Run this project only against systems that you own or have explicit permission to assess.
CVE-2026-15748 is a vulnerability associated with the Forminator plugin for WordPress.
This project provides a scanner for security research and authorized testing. It performs a sequence of passive and application-level checks to identify WordPress, locate Forminator, determine the installed version when possible, inspect relevant pages and forms, and report the resulting assessment.
The scanner is intended to help security researchers understand the exposure of authorized WordPress environments without treating a scanner result as absolute proof of exploitability.
The scanner follows this general workflow:
Target
|
v
Normalize URL
|
v
Detect WordPress
|
+---- not detected ----> NOT WORDPRESS
|
v
Crawl relevant pages
|
v
Detect Forminator
|
v
Detect Forminator version
|
v
Compare version
|
v
Inspect forms
|
v
Generate result
| Feature | Description |
|---|---|
| WordPress Detection | Detects whether the target appears to use WordPress. |
| Forminator Detection | Searches for indicators of the Forminator plugin. |
| Version Detection | Attempts to identify the installed Forminator version from available sources. |
| Version Check | Compares the detected version with the configured VULN_MAX value. |
| Website Crawling | Collects relevant pages and internal links for further inspection. |
| Sitemap Detection | Checks common WordPress sitemap locations. |
| Form Detection | Looks for relevant Forminator forms and form elements. |
| Nonce Detection | Attempts to identify a Forminator nonce in detected form data. |
| Multi-threading | Supports processing multiple targets concurrently. |
| Retry Handling | Retries failed requests according to the configured limit. |
| Request Delay | Adds a configurable random delay between requests. |
| Detailed Results | Writes collected assessment results to a detailed result file. |
requestspackagingurllib3Install the required packages:
pip install requests packaging urllib3
Or:
python -m pip install requests packaging urllib3
Clone the repository:
git clone https://github.com/yora1928/cve-2026-15748.git
Enter the project directory:
cd cve-2026-15748
Install the dependencies:
pip install requests packaging urllib3
Verify the Python installation:
python --version
The scanner configuration is defined directly in the source code:
TIMEOUT = 15
THREADS = 8
VULN_MAX = "1.56.1"
MAX_RETRIES = 3
DELAY_MIN = 1.0
DELAY_MAX = 2.5
CRAWL_DEPTH = 2
| Variable | Default | Description |
|---|---|---|
TIMEOUT | 15 | HTTP request timeout. |
THREADS | 8 | Number of worker threads used for scanning. |
VULN_MAX | 1.56.1 | Maximum version treated as affected by the scanner's version assessment. |
MAX_RETRIES | 3 | Maximum number of retry attempts for failed requests. |
DELAY_MIN | 1.0 | Minimum request delay. |
DELAY_MAX | 2.5 | Maximum request delay. |
CRAWL_DEPTH | 2 | Maximum crawling depth. |
The values above describe the scanner's current source-code configuration.
The scanner accepts either a single target URL or a text file containing multiple target URLs.
python cve-2026-15748.py -u https://target.com
-u and --url specify one target URL.
Use this mode when performing an assessment against a single authorized environment.
Create a file such as targets.txt:
https://target1.example
https://target2.example
https://target3.example
Then run:
python cve-2026-15748.py -f targets.txt
-f and --file specify the target list.
Each non-empty line is treated as a target.
The default configuration uses 8 threads.
For example:
python cve-2026-15748.py -f targets.txt -t 10
Or:
python cve-2026-15748.py -f targets.txt -t 5
-t changes the number of worker threads used by the scanner.
The scanner also provides an optional --upload mode:
python cve-2026-15748.py -u https://lab.example.com --upload
For multiple authorized targets:
python cve-2026-15748.py -f authorized-targets.txt -t 5 --upload
This mode can perform a POST/upload request against a Forminator endpoint when the relevant conditions are met.
Only use --upload on systems where this testing is explicitly authorized.
| Command | Purpose |
|---|---|
-u, --url | Scan a single target URL. |
-f, --file | Read multiple targets from a file. |
-t | Set the number of scanning threads. |
--upload | Enable the upload test mode for an authorized target. |
Single target:
python cve-2026-15748.py -u https://target.com
Multiple targets:
python cve-2026-15748.py -f targets.txt
Multiple targets with custom concurrency:
python cve-2026-15748.py -f targets.txt -t 10
Authorized lab upload test:
python cve-2026-15748.py -u https://lab.example.com --upload
The scanner performs several stages during an assessment.
The target URL is normalized before requests are made so that subsequent checks use a consistent URL format.
The scanner checks common WordPress indicators and endpoints, including:
/wp-login.php
/wp-json
/xmlrpc.php
/wp-content
It also searches responses for indicators such as:
wp-content
wp-includes
If WordPress cannot be identified, the scanner reports:
[NOT WORDPRESS]
The scanner builds a list of pages from common paths, sitemap locations, and internal links discovered from the target.
Examples of paths checked include:
/contact
/kontak
/hubungi-kami
/form
/forms
/formulir
/upload
/unggah
/submit
/kirim
/gallery
/kontribusi
/daftar
/pendaftaran
/registration
/register
/file-upload
/submit-document
/unggah-berkas
/upload-file
Common sitemap locations include:
/sitemap.xml
/sitemap_index.xml
/wp-sitemap.xml
The crawler is limited by CRAWL_DEPTH.
The scanner searches for Forminator identifiers such as:
forminator-form-<ID>
For detected forms, it checks for relevant elements such as:
type="file"
and:
<select>
It also attempts to obtain:
form_id
nonce
from the form HTML.
The scanner attempts to determine the Forminator version from information exposed by the target.
One source is an asset path similar to:
/wp-content/plugins/forminator/...
with a version parameter:
?ver=X.X.X
The scanner also has a fallback that searches for:
Stable tag:
in HTML or readme.txt.
The reported detection method can include:
html-source
or:
readme.txt
The configured assessment boundary is:
1.56.1
The detected version is compared with VULN_MAX.
Possible assessment states include:
VULNERABLE
PATCHED
If Forminator is detected but its version cannot be determined, the scanner can report:
INSTALLED (unknown version)
A scanner classification should be treated as an assessment result, not absolute proof that the target is exploitable.
The main output follows this general structure:
[STATUS] URL VERSION (METHOD) [PAGES] [FORM STATUS] [VULNERABILITY STATUS] [UPLOAD STATUS]
Example:
[FOUND] https://target.com v1.56.0 (html-source) [25 pages] [HAS UPLOAD FORM] [VULNERABLE]
When no upload form is detected:
[FOUND] https://target.com v1.56.0 (html-source) [25 pages] [VULNERABLE]
FOUNDForminator was detected and relevant information was successfully collected.
NOT FOUNDForminator could not be detected.
Example:
[NOT FOUND] https://target.com [17 pages]
NOT WORDPRESSThe target was not detected as a WordPress installation.
Example:
[NOT WORDPRESS] https://target.com
INSTALLED (unknown version)Forminator appears to be installed, but the scanner could not determine its version.
VULNERABLEThe detected version is at or below the configured boundary:
1.56.1
PATCHEDThe detected version is above the configured boundary:
1.56.1
After scanning the targets, the tool displays a summary similar to:
========== SUMMARY ==========
VULNERABLE : 10
PATCHED : 5
UNKNOWN VERSION : 3
NOT FOUND : 20
NOT WORDPRESS : 2
TOTAL SCANNED : 40
[+] HAVE UPLOAD FORM: 2
The values represent the results collected during the current scan.
After scanning completes, the tool creates:
scan_results_detailed.txt
The result file is organized into sections such as:
=== VULNERABLE (with upload form) ===
=== VULNERABLE (no upload form) ===
=== UNKNOWN VERSION (assume vulnerable) ===
Example:
=== VULNERABLE (with upload form) ===
https://target.example - v1.56.0 (html-source) - form_data: ...
=== VULNERABLE (no upload form) ===
https://target.example - v1.55.0 (html-source)
=== UNKNOWN VERSION (assume vulnerable) ===
https://target.example
Do not commit scan results to a public repository if they contain target information or other sensitive data.
cve-2026-15748/
|
├── cve-2026-15748.py
├── README.md
├── targets.txt
└── scan_results_detailed.txt
| File | Purpose |
|---|---|
cve-2026-15748.py | Main scanner implementation. |
README.md | Project documentation. |
targets.txt | List of targets to process. |
scan_results_detailed.txt | Automatically generated scan results. |
The source code is organized into several functional areas:
cve-2026-15748.py
|
├── CONFIG
| ├── TIMEOUT
| ├── THREADS
| ├── VULN_MAX
| ├── MAX_RETRIES
| ├── DELAY_MIN
| ├── DELAY_MAX
| └── CRAWL_DEPTH
|
├── HTTP / REQUEST
| ├── get_headers()
| └── safe_get()
|
├── URL
| └── normalize()
|
├── VERSION
| ├── is_vulnerable()
| └── extract_version_from_html()
|
├── WORDPRESS
| └── check_wordpress()
|
├── CRAWLING
| └── get_all_pages()
|
├── FORM DETECTION
| └── extract_form_data_advanced()
|
├── FORMINATOR
| └── check_forminator_full()
|
├── TESTING
| └── upload_test()
|
├── SCANNING
| └── scan_target()
|
└── MAIN
└── main()
The scanner uses:
The configured request behavior is:
TIMEOUT = 15 seconds
MAX_RETRIES = 3
DELAY = 1.0–2.5 seconds
The scanner has several limitations:
UNKNOWN results require manual verification.For WordPress administrators:
Before running the scanner:
[ ] Confirm that the system is in scope.
[ ] Confirm that you have permission to test it.
[ ] Prefer a testing or laboratory environment when possible.
[ ] Avoid using real user data during testing.
[ ] Do not test systems outside the authorized scope.
[ ] Store assessment results securely.
For Educational & Authorized Testing Only.
This project is intended for:
Do not use the scanner against systems that you do not own or do not have explicit permission to test.
The user is responsible for the way this tool is used. The author is not responsible for damage, data loss, service disruption, or legal consequences resulting from misuse.
Yora
GitHub:
https://github.com/yora1928
Repository:
https://github.com/yora1928/cve-2026-15748
If this project is useful for legitimate educational or security research, you can support the repository by giving it a star.
MIT License