In this article
  1. What happened
  2. How the attack works
  3. Who is exposed
  4. Exploitation status
  5. What to do
  6. Updates

Ninja Forms, a WordPress form plugin on more than 500,000 sites, had a stored cross-site scripting (XSS) flaw, CVE-2026-94504, in versions up to and including 3.15.3. The CVE record, published by Wordfence on September 22, 2026, says anyone can save script in a form’s text box without logging in. That script runs in WordPress’s admin area when an administrator opens the submission. Wordfence rates it CVSS 3.1 7.2 (High); Patchstack rates it 7.1. Ninja Forms 3.15.4, released September 21, fixed it.

The security firm Patchstack says attackers have used the flaw since October 5 to install a fake plugin and hidden administrator accounts. Updating closes the hole but does not remove anything an attacker already installed.

What happened

  • September 21, 2026: Ninja Forms 3.15.4 shipped. Its changelog says it “strengthen[s] output escaping in admin submission edit screen.”
  • September 22: the flaw was disclosed publicly as CVE-2026-94504. The same flaw is also listed as CVE-2026-92438 by WPScan and in Wordfence’s database (see the note below).
  • September 28: Ninja Forms 3.15.5 fixed a separate stored XSS in Paragraph Text (rich text) fields, CVE-2026-90438, which affects versions up to 3.15.4.
  • October 4: Patchstack saw a payload hosted on imgcdn1[.]com sent through CVE-2026-93836 in WPC Product Bundles for WooCommerce (8.6.6 and earlier).
  • October 5: Patchstack saw the same payload sent through CVE-2026-94504 in Ninja Forms.

How the attack works

According to Patchstack, the attacker sends a normal form submission to the plugin’s public AJAX endpoint (admin-ajax.php with action=nf_ajax_submit). The malicious code waits in the stored submission. When a logged-in administrator views that submission, the code uses the administrator’s session to:

  1. install a fake plugin called “WP Smart Thumbnails” 1.2.4 by “MediaPress Labs” (folder wp-smart-thumbnails);
  2. create a visible administrator account;
  3. create a hidden administrator that does not appear under Users → All Users;
  4. set up a secret login URL (/wp-login.php?_wplogin=) that logs the holder in as the site’s oldest administrator.

The fake plugin also contains a file manager that anyone can reach without a password. Patchstack says the hidden admin and the login URL live in “must-use” plugins, which the Plugins screen does not list. Those files have their timestamps backdated so they look like the oldest files on the site. Deleting the fake plugin, or Ninja Forms itself, leaves them in place.

Who is exposed

Sites running Ninja Forms 3.15.3 or earlier are exposed. The attack needs no login, but it only works once an administrator opens the poisoned submission. Ninja Forms has fixed more stored XSS flaws since then. CVE records for CVE-2026-109997 and CVE-2026-110899 list versions through 3.15.5 as affected, and the CVE-2026-110899 record marks 3.15.6 as fixed. Version 3.15.5 is not the end of the patching. The latest release on WordPress.org is 3.16.0 (November 2).

Exploitation status

The exploitation reports come from Patchstack. It says it has seen “active exploitation” but that volume “remains limited in our telemetry,” and that the same implant could be delivered through other plugins. The Ninja Forms changelog does not mention exploitation. As of CISA’s KEV feed dated November 4, 2026 (UTC), neither CVE-2026-94504 nor CVE-2026-90438 is in the Known Exploited Vulnerabilities (KEV) catalog.

Note on CVE numbers and how the flaw is described: WPScan’s CVE-2026-92438 describes the same 3.15.3 submission-screen flaw and rates it 8.8. BleepingComputer wrote that the flaws “require an authenticated session to exploit.” Patchstack and the CVE record both say the submission itself needs no login; only the trigger needs an administrator’s view.

What to do

  1. Update Ninja Forms to the latest version (3.16.0 at the time of writing). At minimum, go past 3.15.5, since later CVEs affect it. Do this under Plugins → Installed Plugins, or run wp plugin update ninja-forms.
  2. Then check whether you were already hit. Updating does not clean a site.
    • Look for the folder wp-content/plugins/wp-smart-thumbnails/ (a plugin named “WP Smart Thumbnails” by “MediaPress Labs”).
    • Look in wp-content/mu-plugins/ for class-wp-token-validate.php or class-wp-query- followed by eight characters and .php. Ignore file dates, because they are backdated.
    • List administrators with a direct SQL query (Patchstack’s), via wp db query. Do not rely on wp user list --role=administrator or on Users → All Users: both use WordPress’s user query, and the implant hooks pre_user_query to hide the account from them. Compare the SQL result with the Users screen. Look for accounts that appear only in the database, accounts named like support, updater or maintenance, and local accounts with an @wordpress.org email.
      wp db query "SELECT u.user_login, u.user_email, u.user_registered FROM wp_users u JOIN wp_usermeta m ON m.user_id = u.ID WHERE m.meta_key = 'wp_capabilities' AND m.meta_value LIKE '%administrator%';"
      If your table prefix isn’t wp_ (check wp config get table_prefix or $table_prefix in wp-config.php), replace wp_users, wp_usermeta and wp_capabilities with it.
    • Check the wp_options table for fz_emer_done_v1 and fz_emer_login_tokens.
    • Search web logs for imgcdn1.com, /fz/x.js, requests to wp-login.php that carry _wplogin, and direct requests to wp-smart-thumbnails.php.
  3. If you find any of these, treat the site as compromised. Patchstack’s steps are:
    • remove the fake plugin, the mu-plugin files and the unknown admin accounts;
    • delete both fz_emer_ options;
    • change every administrator’s password, including the oldest admin’s;
    • rotate the WordPress salts;
    • review the files and database for other changes.
  4. Do the same check for WPC Product Bundles if you use it. Update it to 8.6.7 or later.

Sources

Last checked: Nov 5, 2026, 8:23 p.m. Manila (UTC+8). Method: We read the Ninja Forms changelog on WordPress.org, the CVE records for CVE-2026-94504, -90438, -92438, -109997 and -110899 (Wordfence is the CNA for 94504; the Wordfence threat-intel page returned 403 to our fetcher), Patchstack’s Oct 6 campaign analysis (including its SQL admin-enumeration query), CISA’s KEV feed and BleepingComputer’s Oct 6 report by Bill Toulas. Versions and fixes are quoted from the vendor and the CVE records; exploitation details and indicators come from Patchstack. The thumbnail is an original OneSignalDesk topic graphic. No affiliate links. How we work.

Updates

  • Nov 5, 2026, 8:31 p.m. Manila: First published.

Spotted an error? See our corrections policy and tell us.