Multiple critical security vulnerabilities were discovered in the Ninja Forms plugin for WordPress. If you are using a version less than 2.9.42, update immediately!
Ninja Forms is a very popular WordPress plugin to easily build forms for WordPress. The WordPress.org repository claims there are 500,000+ active installs and ninjaforms.com claims there have been over 2.38 million downloads of the plugin as of May 4th 2016. The plugin is currently listed as the 35th most popular plugin in the WordPress.org repository.
Multiple critical security vulnerabilities were discovered while doing a cursory investigation before deciding to use a plugin and disclosed to the WP Ninjas team. I did not do a full audit of the code base but I recommended the team do a complete audit before releasing an update. After they were patched, I recommended they contact the WordPress.org plugin security team to get help with forcing an automatic security update.
Version 2.9.36 to 2.9.42 are vulnerable to all of the following critical security vulnerabilities. The most sever vulnerability allows unrestricted uploading of files which could allow remote code execution on a typical webserver setup. The only condition required on a site to attack it is to already have a form enabled, which if this plugin is installed the chances of a form being in use are very high.
For quite some time the WP Ninjas team has been busy doing a complete rewrite of the codebase to provide more flexibility in the future. Starting with version 2.9.36, a preview of the 3.0 code base has been included in the main plugin download and typically requires an administrator to manually enable that code for testing.
All of the following vulnerabilities are in the 3.0 code base and any version before 2.9.36 are NOT affected in any way. I really appreciate that the Ninja Forms team wanted to make the release candidate available to users without doing a separate download, especially with the Konami code, unfortunately even skilled players are able to take down Red Falcon without the code (I could never beat the game without the cheat code).
Manually calling 3.0 code
If a site has not manually enabled the 3.0 code for testing, it is trivial for an attacker to bypass this and execute the 3.0 code. For all of the following vulnerabilities a site admin does NOT need to have enabled the 3.0 codebase.
Originally, I had a full disclosure here on how to bypass the 3.0 code check. Due to the severity of the vulnerability, I’ve removed that specific information.
The 3.0 codebase uses only the ‘ninja_forms_ajax_nonce’ nonce check as security for many actions. This nonce is leaked on every form regardless if a user is logged in or not.
Arbitrary File Uploading
The following vulnerable code was, according to Kyle Johnson of the WP Ninjas team “not a live feature of Ninja Forms, but was more of a proof of concept for a future free feature.” Unfortunately, even proof of concept code that is accessible is still vulnerable to attack. This is the most critical vulnerability here because it potentially allows an attacker to execute arbitrary php code on a site.
As shown, the upload() function can be called by a logged in user or not logged in user.
The function is only protected by the ‘ninja_forms_ajax_nonce’, which as shown above is leaked on any form request. The following validate() function appears to be incomplete, though it is perfectly functional any will happily accept any uploaded file and place it in the configured upload directory. Through directory traversal, the file can be placed anywhere the php process has write permissions for.
Updating plugin settings
Simply by sending over settings via HTTP POST ‘update_nina_forms_settings’ an un-authenticated user can update any of the Ninja Forms settings.
There is no authorization checks at all here so any settings can be changed.
On the ‘pluings_loaded’ action the function to import and export forms and fields are called. These functions do not call require any further authorization, so any un-authenticated user can call them.
The export_fields_listener() and export_form_listener() functions are called to export forms or fields. While this data might not be very useful to an attacker, they could then take this data and modify it and import it to allow hijacking the existing forms.
The import_form_listener() and import_fields_listener() allows unrestricted access of importing forms and fields. An attacker could modify existing forms and import them to include XSS or even hijack the form output.
All of the above links go directly to the listed site. If you are inclined, here is an affiliate link to ninjaforms.com. If you are interested in purchasing any products and supporting my security research.
- 4/16/2016 7:45pm Initial form submission to discover security contact
- 4/17/2016 10:46am Received contact information
- 4/17/2016 10:59am Initial disclosure of primary issue
- 4/18/2016 9:53pm Disclosure of further issues discovered
- 4/22/2016 6:57am PR posted on github.com to resolve issues
- 4/25/2016 7:37am PR merged into master branch
- 4/28/2016 7:00am Version 2.9.43 released to public
- 5/3/2016 WordPress.org plugin repository began plugin automatic security update