# CVE-2026-126537: Ninja Forms File Uploads add-on for WordPress, detection pack

CybaVerse detection and checking pack for CVE-2026-126537, an unauthenticated arbitrary file deletion flaw in the Ninja Forms
File Uploads add-on for WordPress (slug `ninja-forms-uploads`), versions up to and including 3.3.36.

**Patch now: update the File Uploads add-on to 3.3.37 or above.**

The KQL in this pack has NOT been run against a live tenant. It parses offline against an assumed schema subset. The Sigma
rules convert offline only. Test and tune everything before you rely on it.

Facts checked on 11 Nov 2026, 14:09 to 14:12 GMT, against the primary sources listed at the end.

## Verified facts

| Item | Value | Source |
|---|---|---|
| Product | Ninja Forms, File Uploads add-on (the CVE record names product "Ninja Forms - File Uploads", vendor "SaturdayDrive") | cve.org |
| Affected | versions up to and including 3.3.36 (record: version 0, lessThanOrEqual 3.3.36, default status unaffected) | cve.org |
| Fixed | 3.3.37, dated 2 November 2026 in the add-on changelog | changelog |
| Weakness | CWE-22, path traversal | cve.org |
| Score | CNA rating: CVSS 3.1 base score 9.1, Critical, AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H | cve.org, NVD |
| NVD | status Deferred; the only metric is the CNA's CVSS 3.1 9.1, listed by NVD as type Primary; no CPE configuration | NVD |
| CVE record | reserved 10 Nov 2026 23:59 GMT, published 11 Nov 2026 12:34 GMT | cve.org |
| NVD record | published 11 Nov 2026 13:17 GMT | NVD |
| Timeline in the record | vendor notified 13 Oct 2026 (17:48 GMT); disclosed 11 Nov 2026 (00:01 GMT) | cve.org |
| CISA KEV | not in KEV catalog 2026.11.10 (released 10 Nov 2026 19:03 GMT), which predates the CVE record | CISA KEV |
| Credit | a security researcher | cve.org |

### The CVE description, quoted

The record's description, quoted in full. We replaced its two em dashes with commas; the words are unchanged.

> The Ninja Forms - File Uploads add-on for WordPress is vulnerable to Arbitrary File Deletion (and arbitrary file read via
> S3/Dropbox/Google Drive exfiltration) in versions up to, and including, 3.3.36. The flaw spans NF_FU_Fields_Upload::process()
> in includes/fields/upload.php, which returns early (leaving the client-supplied files[] intact) whenever a public submission
> carries a nonempty extra.saveProgress, and NF_FU_External_Abstracts_Service::process_upload() in
> includes/external/abstracts/service.php, whose authoritative-path reload only fires when the client sends upload_id. By
> omitting upload_id, an attacker's data[file_path] survives into the Background Upload queue and is used by both
> upload_file_to_s3() (as SourceFile) and the maybe_delete_server_file() unlink() call in
> includes/external/abstracts/backgroundupload.php, with no canonicalization or upload-directory containment check (the plugin's
> own is_path_within_upload_dir() helper is only applied on admin paths). This makes it possible for unauthenticated attackers to
> delete arbitrary files on the affected site's server which may make remote code execution possible, specifically, deleting
> wp-config.php forces WordPress into its setup screen, enabling full site takeover.

The CNA's vector has C:N (no confidentiality impact), while the description mentions "arbitrary file read via S3/Dropbox/Google
Drive exfiltration". We quote both as published and do not reconcile them.

The record title also names the parameter `files[].data.file_path` and `extra.saveProgress`. All parameter, function and file
names above come only from the CVE description and title. The add-on's code is not public, so we have not verified them.

### Scope: the add-on, not core Ninja Forms

* The CVE record lists only the File Uploads add-on. Core Ninja Forms (wordpress.org slug `ninja-forms`) is not listed as
  affected. The record does not say core is unaffected; it simply does not list it.
* The sources call it an "add-on". It is sold on ninjaforms.com and is not on wordpress.org (the wordpress.org plug-in API
  returns "Plugin not found" for `ninja-forms-uploads`).
* Slug evidence: the vendor's own site loads `/wp-content/plugins/ninja-forms-uploads/assets/js/nfpluginsettings.js?ver=3.3.37`,
  and core Ninja Forms 3.16.1 code (wordpress.org download) refers to the add-on as `ninja-forms-uploads/file-uploads.php`.
* The vendor's documentation describes Dropbox, Google Drive and Amazon S3 integrations for the add-on, matching the
  external upload code named in the CVE description.

## Advice

### Ninja Forms (vendor)

* Update the File Uploads add-on to 3.3.37 (changelog, 2 November 2026). The 3.3.37 changelog lists security enhancements:
  "harden handling of uploaded file data during form submission", "bind stored uploads to their form and field in merge tags,
  Zapier and submission records" and "protect public external file links with a per-file access key". The changelog does not
  name the CVE.

### CISA

* CVE-2026-126537 is not in KEV catalog 2026.11.10. That catalog was released before the CVE record was published, so its
  absence says nothing either way. Check the current catalog.

### Ours (CybaVerse, OUR ADVICE)

* Inventory every client WordPress site for the File Uploads add-on (`wp-content/plugins/ninja-forms-uploads/`) with the checker
  and the Q1 hunts, and update every copy to 3.3.37 or above.
* Until a site is updated, disable the add-on, or remove forms with upload fields from public pages.
* Keep off-server backups of wp-config.php and the site files, so a deleted wp-config.php can be restored from a copy you trust.
* If wp-config.php is missing on a site that had the add-on at 3.3.36 or below, treat the site as possibly compromised: do not
  complete the WordPress setup screen, restore from a trusted backup, rotate the database credentials and salts, and review
  admin users, plug-ins and recently changed PHP files.

## Pack contents

| Path | What |
|---|---|
| `kql/ninja-forms-uploads-cve-2026-126537-hunting.kql` | 15 KQL hunts for Defender XDR and Sentinel |
| `sigma/*.yml` | 6 Sigma rules (all OUR PATTERN) |
| `sigma/converted/kusto_*.txt` | offline sigma-cli conversions for five pipelines |
| `scripts/check-ninja-forms-uploads.sh` | read-only checker, bash |
| `scripts/Check-NinjaFormsUploads.ps1` | read-only checker, PowerShell (same output as the bash checker) |
| `tests/` | fixtures (FIXTURE_ONLY), cases, bash and Pester tests, KQL parse check, `run_all.sh` gates |

## KQL hunts

Q1 to Q1d are INVENTORY. Q2 onwards are OUR PATTERNS: behaviour around the published weakness and after a possible compromise.
No IOCs have been published and none of these hunts prove exploitation. Web logs: request bodies are usually NOT logged, so
`extra.saveProgress`, `upload_id` and `data[file_path]` will not be visible in IIS, Apache, nginx or most WAF logs.

| ID | Label | Table | Looks for |
|---|---|---|---|
| Q1 | INVENTORY | DeviceFileEvents | file activity under wp-content/plugins/ninja-forms-uploads/, by host and WordPress root |
| Q1b | INVENTORY | DeviceFileEvents | core Ninja Forms (ninja-forms/ninja-forms.php) |
| Q1c | INVENTORY (ingest check) | DeviceTvmSoftwareVulnerabilitiesKB | whether Defender knows the CVE yet; an empty result proves nothing |
| Q1d | INVENTORY | W3CIISLog | add-on asset requests and their ver= values (UNVERIFIED that ver equals the add-on version) |
| Q2 | OUR PATTERN | DeviceFileEvents | wp-config.php deleted by a web server or PHP process |
| Q2b | OUR PATTERN | DeviceFileEvents | WordPress core and config files deleted by a web server or PHP process |
| Q2c | OUR PATTERN | DeviceFileEvents | files outside wp-content/uploads/ deleted by a web server or PHP process (noisy, baseline first) |
| Q3 | OUR PATTERN | DeviceFileEvents | a new wp-config.php written by a web server or PHP process |
| Q3b | OUR PATTERN | W3CIISLog | requests for wp-admin/setup-config.php or install.php |
| Q3c | OUR PATTERN | Syslog | the same in Apache or nginx access logs (parse UNVERIFIED) |
| Q4 | OUR PATTERN | DeviceProcessEvents | web server or PHP processes starting shells or download tools |
| Q5 | OUR PATTERN | W3CIISLog | admin-ajax.php POST followed by a setup or install screen request within an hour |
| Q5b | OUR PATTERN | W3CIISLog | admin-ajax.php POSTs with action=nf_ajax_submit in the query string |
| Q5c | OUR PATTERN | CommonSecurityLog | WAF or proxy: admin-ajax.php POSTs and setup or install requests per source |
| Q5d | OUR PATTERN | AzureDiagnostics | Application Gateway or Front Door: the same per client IP (columns UNVERIFIED) |

Web server and PHP process names in the hunts are a common list (apache2, httpd, nginx, php-fpm, php, php-cgi, lsphp,
litespeed, w3wp.exe, php-cgi.exe, php.exe). Add your own.

Core Ninja Forms handles public form submissions through the admin-ajax.php action `nf_ajax_submit` with a `formData` POST field
(core code, read from the wordpress.org download). That the add-on flaw is reached through that action is our inference and is
UNVERIFIED. The add-on's own upload AJAX action is UNVERIFIED.

## Sigma rules

All rules are OUR PATTERN, status experimental, and pass `sigma check` with 0 issues.

| Rule | Logsource | Looks for |
|---|---|---|
| `web_wp_setup_config_request.yml` | webserver | requests for wp-admin/setup-config.php or install.php |
| `web_wp_admin_ajax_nf_submit_query.yml` | webserver | POST to admin-ajax.php with nf_ajax_submit in the query string |
| `proxy_wp_setup_config_request.yml` | proxy | setup or install screen requests (c-uri) |
| `lnx_file_delete_wp_config.yml` | linux file_delete | wp-config.php deleted |
| `win_file_delete_wp_config.yml` | windows file_delete | wp-config.php deleted |
| `lnx_proc_webserver_shell.yml` | linux process_creation | web server or PHP process starts a shell or download tool |

Conversion with sigma-cli (Kusto backend), offline:

| Pipeline | Result |
|---|---|
| none | all 6 rules convert |
| microsoft_xdr | 3 convert; gaps: both webserver rules and the proxy rule (no table mapping) |
| microsoft_365_defender | 3 convert; same gaps as microsoft_xdr |
| sentinel_asim | 4 convert (the proxy rule maps to imWebSession); gaps: both webserver rules |
| azure_monitor | 3 convert; same gaps as microsoft_xdr |

Conversion quirks to fix by hand before use:

* microsoft_xdr and microsoft_365_defender turn the file_delete rules into DeviceFileEvents queries without
  `ActionType == "FileDeleted"`. Add it, or use Q2.
* sentinel_asim turns the file_delete rules into imFileEvent without an EventType filter. Add `EventType == "FileDeleted"`.
* azure_monitor maps the Linux rules to SecurityEvent, which holds Windows events. Use the KQL hunts instead.
* For the gaps, use the matching KQL hunts (Q3b, Q3c, Q5b, Q5c, Q5d).

## Checker

Strictly read-only: it reads plug-in headers (first 8 KB, as WordPress does) and checks that wp-config.php exists. It does not
run PHP or WP-CLI, opens no network connections and writes nothing.

```
bash scripts/check-ninja-forms-uploads.sh --path /var/www/html
bash scripts/check-ninja-forms-uploads.sh --list plugins.csv      # saved "wp plugin list --format=csv" (or --format=json)
bash scripts/check-ninja-forms-uploads.sh --version 3.3.36
pwsh scripts/Check-NinjaFormsUploads.ps1 --path C:\inetpub\wwwroot\site
```

| Verdict | Meaning | Exit |
|---|---|---|
| PATCHED | add-on 3.3.37 or above | 0 |
| NOT LISTED | add-on not found; core Ninja Forms alone is not listed as affected in the CVE record | 0 |
| VULNERABLE | add-on 3.3.36 or below | 1 |
| UNKNOWN | version missing or unreadable, a non-numeric or pre-release version, a version between 3.3.36 and 3.3.37 (such as 3.3.36.1), or the add-on folder without file-uploads.php | 3 |
| usage or read error | | 4 |
| WP-CONFIG MISSING | no wp-config.php in the root or one folder up (as WordPress looks), and nothing VULNERABLE | 5 |

With `--path` the checker also prints a WP-CONFIG line: found, found one folder up, or MISSING.

## Tests

`bash tests/run_all.sh` runs every gate: ShellCheck, PSScriptAnalyzer, the bash tests, Pester (including parity between the
bash and PowerShell checkers), wording and link guards, sandboxed checker runs (no network, read-only filesystem, pack sha256
unchanged), the offline KQL parse, `sigma check` and the Sigma conversions. `REGEN=1` rewrites `sigma/converted/`.

## Limits and unverified items

* The KQL has not been run against a live tenant; the Sigma conversions have not been run anywhere.
* The add-on's code is not public. Function, file and parameter names come only from the CVE description and title.
* UNVERIFIED: that the flaw is reached through core's `nf_ajax_submit` action, and the add-on's own upload AJAX action.
* UNVERIFIED: that asset `ver=` values equal the add-on version (Q1d), Syslog access log format (Q3c), CommonSecurityLog field
  use (Q5c) and AzureDiagnostics column names (Q5d) in your workspace.
* Web logs rarely hold request bodies, so the web log hunts see URLs and sequences only.
* File event hunts need Defender for Endpoint on the web server. Many WordPress sites are on managed hosting with no EDR.
* This pack makes no claim about whether the flaw is being exploited.

## Sources (primary)

* CVE record: https://www.cve.org/CVERecord?id=CVE-2026-126537
* NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-126537
* Ninja Forms File Uploads changelog: https://ninjaforms.com/extensions/file-uploads/?changelog=
* CISA KEV catalog: https://www.cisa.gov/known-exploited-vulnerabilities-catalog
