Ninja Forms before 3.4.27.1 — Simple CSRF to RCE
A missing request-origin check in Ninja Forms let one crafted link, clicked by a logged-in administrator, escalate into code execution. Fixed in 3.4.27.1.
This page preserves a historical WPDeeply disclosure at its original URL. The research is credited to its author; remediation information has been kept current by the site’s present operators, who did not discover the vulnerability.
Cross-site request forgery has a reputation as a second-tier vulnerability — the kind that earns a moderate score and a shrug. This disclosure is the counterargument. In Ninja Forms before 3.4.27.1, a CSRF weakness sat in front of functionality powerful enough that abusing it did not stop at unwanted settings changes. It reached code execution.
The vulnerability
- Affected: Ninja Forms 3.4.0 – 3.4.27
- Fixed in: 3.4.27.1
- Type: Cross-site request forgery, chained to remote code execution
- Privileges required: none for the attacker; the victim must be a logged-in administrator
- CVE: none assigned. The issue is catalogued in WordPress vulnerability databases (WPVDB 10424) and referenced by vendor-neutral advisories, but no CVE identifier was issued.
WordPress defends state-changing requests with nonces: a short-lived token tied to the action and the user, checked before the action runs. The pattern only works if every entry point checks it. Ninja Forms exposed administrative form-management functionality — including import handling — without a sufficient origin check on the request, so the plugin could not distinguish a click inside its own admin screen from a request triggered by a page on some other website.
That is the whole trick with CSRF: the attacker never authenticates. The browser does it for them. An administrator who is logged into WordPress in one tab and visits an attacker-controlled page in another sends their session cookies along with whatever request that page triggers. The plugin sees a valid, authenticated administrator.
Why it did not stop at CSRF
The severity comes from what the forged request could reach. Form definitions in a builder like Ninja Forms are not simple data — they describe fields, actions and behaviours, and importing one means accepting a structured definition and acting on it. When an unauthenticated third party can drive that import on an administrator’s behalf, the boundary between “change a setting” and “introduce code that runs” becomes thin.
WPDeeply’s original write-up demonstrated that chain: one crafted request, one administrator visit, and an attacker-supplied payload reaching a context where it executed. Deliberately, then and now, this page does not republish that proof of concept. The plugin has been patched for years, but the pattern is generic and there are still unpatched WordPress installations in the world.
A CSRF flaw is only as serious as the most powerful action it can reach. Judging one by its class rather than its target is how a “moderate” finding turns into a compromised server.
Impact
- Silent creation or modification of form definitions on the victim site.
- Introduction of attacker-controlled behaviour into a component that runs on page load.
- Under the demonstrated chain, execution of attacker-supplied code in the context of the web server.
- No visible sign to the administrator, whose only action was visiting a web page.
The delivery requirement — a logged-in administrator following a link — is a real constraint, but a weak one. Administrators are the people most likely to open a message about their own site: a support request, a “your form is broken” email, a bug report with a link. Targeted delivery to a site owner is not a hard problem.
What to do now
- Update Ninja Forms to 3.4.27.1 or later. Current releases are far beyond this version, so any reasonably maintained site is unaffected.
- If a site has been dormant or restored from an old backup, check the installed version before assuming it is patched.
- On a site that ran an affected version, review your forms and their actions for definitions you do not recognise, and check for administrator accounts and scheduled tasks you did not create.
- Do not stay logged into WordPress in a browser you also use for general browsing. It is a small habit that removes an entire delivery route.
Related reading
- CSRF in WordPress, explained — nonces, why they get skipped, and how to check a plugin uses them.
- Remote code execution in WordPress
- Ninja Forms security and vulnerability history
Research and original disclosure by Slavco Mihajloski (mslavco), published on WPDeeply.