Every time you add additional code to a WordPress plugin (or any other software) you are adding more potentially insecure code. That includes third party libraries and other third party code. Earlier this week we looked at the details of a local file inclusion (LFI) vulnerability in the Booking Calendar plugin caused by its use of a file from another plugin (interestingly the vulnerability doesn’t look like it was every exploitable directly in the other plugin). In that case the file had not been updated in Booking Plugin after it was initially introduced in to it, so while the original plugin’s code had been fixed 5 years ago, Booking Calendar remained vulnerable until weeks ago, which seems like a good reminder to keep third party code up to date.
Two weeks ago there was discussion on our post detailing a vulnerability in the plugin Gallery – Video Gallery over the escaping method being used to fix a SQL injection vulnerability in the plugin. While the changes made look to have fixed the issue, they were less than ideal. Part of the issue was that instead of using a prepared statement to prevent the possibility of SQL injection the function esc_sql() was used. That is despite documentation for that that function making a pretty clear suggestion that it is not recommend in most situations:
One of the ways we see plugin developers try to stop improper access to files generated by their WordPress plugin is to restrict direct access to the files over the Internet through the use of access restrictions placed in a .htaccess file (as the was the case with a vulnerability we disclosed last week). The problem with this is that this only works if the website is hosted on a web server that utilizes .htaccess files. While they are used by the most popular web server Apache, they are not used by the Nginx, which along with Apache is recommended for use with WordPress, or Microsoft’s IIS, which WordPress supports with its own release of WordPress.
One of the items we check for during our security reviews of plugins selected by our customers is to see if the plugin’s .php files can be accessed directly when they are not intended to. While being able to access them directly when that isn’t necessary usually doesn’t have any security impact, it is easy to prevent that from happening and it could in some cases prevent serious issues, like a remote code execution (RCE) vulnerability we found being exploited in a security plugin last year.
One common cause of security issues with WordPress plugins that we continue to see happening is a failure to properly check on whether a user should be able to use admin AJAX functions they are sending requests to. Since the wp_ajax_ hook makes the AJAX function accessible to any logged in user, without checking their capabilities even a Subscriber level users can access functions meant only for Administrators.
One reoccurring cause of security issues in WordPress plugins is the misuse of the function is_admin(). Based on its name you might reasonably assume that it checks if someone is Administrator level user in WordPress and that seems to have tripped up lots of plugin developers. In reality it just “checks if the Dashboard or the administration panel is attempting to be displayed”. It will also “return true when trying to make an ajax request (both front-end and back-end requests)”.