Wordfence and Saturday Drive Provide Hackers With Critical Info to Exploit Unfixed Vulnerability in Ninja Forms
When we discover vulnerabilities, we have always warned our customers only at the same time we were publicly disclosing them, since doing otherwise would allow hackers an ability to have information that the public doesn’t. Other companies are okay with giving hackers a possible leg up and possibly profiting off them. One of those being the developers of the Wordfence Security plugin.
As a practical example of what that means, currently hackers can exploit an unfixed authenticated information disclosure vulnerability in the plugin Ninja Forms, which has 1+ million installs, because of Wordfence. Making things easier for hackers, the developer of Ninja Forms, Saturday Drive, has disclosed even more information on the vulnerability in a form easily accessible by hackers, but unlikely to be noticed by the public, but has yet to provide users of the plugin with a fix.
Yesterday the free rules that Wordfence provides for their firewall plugin were updated with the following rule:
if (match(‘/ninja-forms-submissions/i’, request.path, request.md5Body[‘c98d48a702d2fb75df0353af9c222655’], request.md5QueryString[‘c98d48a702d2fb75df0353af9c222655’]) and currentUserIsNot(‘administrator’, server.empty)):
block(id=387, category=’auth-bypass’, score=100, description=’WAF-RULE-387′, whitelist=0)
Any hacker paying $99 a year already had access to that same information 30 days before then.
Part of that rule is looking for a request path that contains “ninja-forms-submissions”. Even if a hacker couldn’t figure out that refers to something related to Ninja Forms directly, using the website WPdirectory they could quickly identify that.
If you look at the changelog for the plugin, you can see that there hasn’t been a new release since July 5 and no recent update mentions a security update, which would indicate that there likely is unfixed vulnerability in the plugin, otherwise why would Wordfence be adding a rule now.
From there a hacker could see that the plugin registers to REST routes involving “ninja-forms-submissions” in the file /includes/Routes/Submissions.php:
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | register_rest_route('ninja-forms-submissions', 'export', array( 'methods' => 'POST', 'args' => [ 'form_ids' => [ 'required' => true, 'description' => esc_attr__('Array of Form IDs we want to get the submissions from.', 'ninja-forms'), 'type' => 'JSON encoded array', 'validate_callback' => 'rest_validate_request_arg', ], 'start_date' => [ 'required' => true, 'description' => esc_attr__('strtotime($date) that represents the start date we will retrieve submssions at.', 'ninja-forms'), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ], 'end_date' => [ 'required' => true, 'description' => esc_attr__('strtotime($date) that represents the end date we will retrieve submssions at.', 'ninja-forms'), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ], ], 'callback' => [ $this, 'bulk_export_submissions' ], 'permission_callback' => [ $this, 'permission_callback' ], )); register_rest_route('ninja-forms-submissions', 'email-action', array( 'methods' => 'POST', 'args' => [ 'submission' => [ 'required' => true, 'description' => esc_attr__('Submission ID', 'ninja-forms'), 'type' => 'int', 'validate_callback' => 'rest_validate_request_arg', ], 'action_settings' => [ 'required' => true, 'description' => esc_attr__('Email Action Settings', 'ninja-forms'), 'type' => 'object', 'validate_callback' => 'rest_validate_request_arg', ], ], 'callback' => [ $this, 'trigger_email_action' ], 'permission_callback' => [ $this, 'permission_callback' ], )); |
From there a hacker might have had trouble figuring out what was at issue, but the developer of the plugin provides a big assist. On August 17, a new version of the plugin was submitted to the Subversion repository underlying the WordPress Plugin Directory labeled as 3.5.8-a2. That was submitted in a way that doesn’t provide it as an update to those already using the plugin.
There were two changes made to the file /includes/Routes/Submissions.php in that. The first spells out there is a vulnerability that currently exists in the plugin:
Security disclosure regarding <=3.5.7 showed that any logged in user could export form data, possibly exposing personally identifiable information. Permissions changed such that only admin can export submission data; a filter enables one to override that permission if desired.
Again, that has been out there since August 17.
The other change matches that description, as the following code was removed:
88 89 | //Check Capability of logged in users $allowed = is_user_logged_in(); |
And replaced with this:
95 96 97 | // Allow only admin to export personally identifiable data $permissionLevel = 'manage_options'; $allowed= \current_user_can($permissionLevel); |
With that information, it is trivial to exploit the vulnerability. All you need is to copy the request format for that from the admin page it is intended to be executed from and understand of how to get the relevant nonce needed for that type of request (which isn’t hard).
Protecting Your Website
The insecure code was introduced in version 3.5.5, so a significant portion of the user base isn’t at risk if the WordPress Plugin Directory’s stats are accurate:
(At the same time, it is concerning that so many websites are not keeping their plugins up to date, even if in this case that provides them with protection.)
If you are using a vulnerable version of the plugin and allow untrusted individuals access to WordPress accounts, we would recommend making the code change in the file /includes/Routes/Submissions.php as shown above or disabling the plugin until a new version of the plugin is released. Any of our customers that need help modifying that please get in touch with us. For those wanting to be extra cautious, reviewing the log files for the website to make sure there haven’t been any requests for the relevant path would be a good idea.
For anyone using the plugin, we would recommend considering whether you should keep using the plugin, since the developer has been aware of the vulnerability for weeks, if not at least month, and did not promptly release a fix for it, despite that being easy to do.
What Wordfence has done here is also troubling, as they have attempted to protect their customers while leaving others unaware that they are at risk, while providing hackers info needed to exploit an unfixed vulnerability.