Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
cve-2026-94504 — Python PoC for CVE-2026-94504, an unauthenticated stored XSS in Ninja Forms <= 3.15.3. Fingerprints vulnerable versions and plants a payload via nf_ajax_submit. | Kitploit
Tools/GitHubGitHub/cflowsec/cve-2026-94504
Vulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityPenetration Testing
GitHubcflowsec/cve-2026-94504

cve-2026-94504

Python PoC for CVE-2026-94504, an unauthenticated stored XSS in Ninja Forms <= 3.15.3. Fingerprints vulnerable versions and plants a payload via nf_ajax_submit.

View Repository
118h 52m agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

cve-2026-94504

Ninja Forms unauth stored XSS POC

Ninja Forms ≤ 3.15.3 — unauthenticated stored XSS. A public non-RTE textarea is saved, then html_entity_decode()'d and written into the legacy submission editor with no esc_textarea(). 3.15.4 escapes it. No login is required to plant the payload. It runs when an editor opens that submission.

For authorized testing only. Do not run this against systems you do not own or have permission to test.

Requires: Python 3, standard library only.

root@kitploit:~
python3 cve-2026-94504-ninja-forms-stored-xss.py -u http://TARGET --test
python3 cve-2026-94504-ninja-forms-stored-xss.py -u http://TARGET --plant
python3 cve-2026-94504-ninja-forms-stored-xss.py -u https://TARGET --test --insecure
python3 cve-2026-94504-ninja-forms-stored-xss.py -u TARGET --test
FlagWhat it does
-u / --urlWordPress base URL (required). http:// or https://. A hostname with no scheme is tried as HTTPS first, then HTTP. http→https redirects keep POST. Bad TLS certs are retried without verify; --insecure skips verify from the start
--testFingerprint only. Reads readme.txt, finds a public non-RTE textarea. Does not submit
--plantUnauthenticated nf_ajax_submit. Fills required fields, puts the payload in the textarea, and prints the edit URL. Does not open a browser
--pagePage that embeds the form. Default crawls /, /contact/, and the REST page/post list
--fieldTextarea field id. Default is the first non-RTE textarea
--payloadTextarea value. Default closes the admin <textarea> with an img onerror. In cmd.exe do not wrap this in single quotes (< is a redirect). Omit --payload, or use double quotes and single quotes inside alert: --payload "</textarea>"
--name / --emailFillers for other required fields (defaults Ada Lovelace / [email protected])
--insecureSkip TLS verify
--timeoutHTTP timeout seconds (default 30)

--test reads /wp-content/plugins/ninja-forms/readme.txt (Stable tag) and a public page whose nfForms JSON has "type":"textarea" with the rich-text editor off. ≤ 3.15.3 plus that field is VULNERABLE. ≥ 3.15.4 is NOT_VULNERABLE. No form on the site is NEED_FORM.

--plant posts /wp-admin/admin-ajax.php action=nf_ajax_submit with the page's ajaxNonce. No WordPress account. Success prints PAYLOAD, SUB, and EDIT /wp-admin/post.php?post=ID&action=edit. The script runs when that submission is opened in wp-admin. The public form page does not.

Rich-text (textarea_rte) paragraphs are a different path and are skipped. The default Contact Me "Message" field is the usual target.

Stdout: VERSION, PAGE, FORM, FIELD, PRESENT, VULNERABLE, NOT_VULNERABLE, NOT_FOUND, NEED_FORM, NEED_NONCE, PLANTED, PAYLOAD, SUB, EDIT.

CVE: CVE-2026-94504. Plugin: ninja-forms. Patched in 3.15.4. Credit: Hippolyte Quéré (Hippie); 3.15.4 changelog also names Venkateswara Reddy Challa for the admin escaping fix.

Command line

Browser

Download Tool