18 Apr 2025

You Don’t Need to Sanitize User Input Before Casting as an Integer in a WordPress Plugin

A basic rule of security is to not trust user input. Many vulnerabilities exist because software developers assume that only legitimate and valid data will be submitted to the software. So the developers of WordPress plugins should do some combination of sanitization, validation, and escaping with user input. Developers can overdue on those things. We ran across an example while working on a security review of a plugin chosen by our customers.

Here is the relevant code in the plugin (plenty of other plugins, it turns out, have similar code): [Read more]

6 Aug 2024

WordPress Generated Nonces Don’t Generally Provide CSRF Protection for Those Not Logged In

We were recently looking into a somewhat convoluted situation with a vulnerability in a WordPress plugin. Part of investigating that involved checking on something involving usage of a nonce for those not logged in to WordPress. Nonces are used to protect against cross-site request forgery (CSRF) vulnerabilities. It turns out that if you do a web search looking to see if those can be used those for those not logged in, you can get some pretty poor information. Part of the problem is that there are people handing out security advice that don’t know what they are talking about. That includes the moderators of WordPress Support Forum. Here was the long winded non-answer one of them gave to someone asking a specific question about nonces with those not-logged in to WordPress:

There are few absolutes in security. A trade off between difficulty and benefits gained. It’s “better” to use a nonce to help ensure the data is coming from your own form. In some cases the security gained would be so minimal that it wouldn’t matter much. If you make the effort anyway, there’s no harm in it. Rather than following “rules” you read here and there, it’s better to actually understand the security implications and consequences and act accordingly to a specific situation. Granted, easier said than done. Security is an ever evolving topic. Lacking such understanding, better safe than sorry is a reasonable approach. [Read more]

29 Jan 2024

What to Do If Someone is Claiming There is a Vulnerability in Your WordPress Plugin

In the work we do to keep track of vulnerabilities in WordPress plugins for our customers, we see a lot going wrong with the handling of vulnerabilities in them. While a lot of that involves plugin developers, it also involves others as well, and is leading to frequent problems that could be better handled. Below we have touched on our advice on dealing with a claim that a vulnerability in your WordPress plugin based on our experience helping to address those.

If there is something more to be noted, leave a comment below. [Read more]

26 Jan 2024

How to Use the sanitize_callback When Using the WordPress register_setting() Function

One of the many issues we now check for when doing security reviews of WordPress plugins is proper usage of the sanitize_callback when using register_setting() to register settings. That helps to make sure that settings of the plugin don’t contain input that they shouldn’t. After finding that a plugin we were doing a review of lacked of usage of that, we couldn’t find good documentation written specifically on implementing that to send them a link to. Their attempt to implement it went wrong, suggesting even more need for having better documentation on that. We have provided the basics on that below, but if there is more that needs to be added, please let us know in the comments.

Registering the sanitize_callback

The format of the register_settings() function is this: [Read more]

25 Jan 2024

The Right Way for WordPress Plugins to Secure Order By Clauses in SQL Statements

Recently, one of our competitors in keeping track of vulnerabilities in WordPress plugins, Patchstack, very vaguely claimed there was an unfixed SQL injection vulnerability in a plugin used by at least one of our customers. As the developer noted, Patchstack didn’t “say anything specific about where the supposed vulnerability is, or how it can be reproduced.” So not all that helpful. Someone pointed out code that might be at issue. The developer didn’t take their advice in trying to fix it, leading to a new version that is still vulnerable.

What really stands out about this is the alternative suggested is much simpler than what the developer is doing instead. The issue involves properly handling inserting user input into the order by clause of an SQL statement. Here is the developer’s code before they made an attempt to fix it: [Read more]

24 Jan 2024

WordPress Plugin Developers Need to Make Sure Their Nonce Checks Both Work if a Nonce Isn’t Sent or if the Nonce is Wrong

Yesterday, we released the results of a security review we did of a WordPress plugin. What we found while reviewing the changes made to address the problems we had found is a good reminder that security fixes need to be checked over carefully. It turned out that not all the fixes had been properly implemented. That led to a vulnerability still being in the plugin. One of those was a logic failure in a nonce check to prevent cross-site request forgery (CSRF). Developers need to make sure their nonce checks work if either a nonce isn’t sent or if it is wrong. Otherwise, there still can be CSRF vulnerability, as a valid nonce needs to sent and validate to prevent that type of vulnerability.

Here was a nonce check that was added: [Read more]

23 Jan 2024

The WordPress Function maybe_unserialize() Won’t Prevent PHP Object Injection

Recently, an update was released for a WordPress plugin that had a changelog that said the new version addressed a PHP object injection vulnerability by using the WordPress function maybe_unserialize(). That function doesn’t accomplish that. The developer then made a second attempt to address the vulnerability, which did fix it. To better understand why maybe_unserialize() won’t address that, let’s look at how they managed to fix it.

The code passes user input to the function unserialize(): [Read more]

22 Jan 2024

WordPress Plugin Developers Are Still Creating Vulnerabilities by Improperly Using the permission_callback for WordPress Rest API Endpoints

Back in November, the Automattic owned WPScan claimed there had been a vulnerability in a plugin that extends the very popular ecommerce plugin WooCommerce, which is also owned by Automattic. WPScan only got around to releasing any information about the claimed vulnerability this month. When we went to check on that, we found that the relevant code is still vulnerable, though less vulnerable than it was before. If the developer of the plugin was properly implementing the built-in security when using WordPress’ REST API they wouldn’t still have the vulnerability.

We are now four years in with the REST API being available in WordPress, but plugin developers are still not implementing a basic security element it introduced correctly. So it seems worth going through what is going wrong and how it can be fairly easily be fixed. [Read more]

15 Jan 2024

The WordPress Function sanitize_text_field() Function Doesn’t Sanitize User Input for SQL Statements

As we warned our customers about last week, a recent update to a WordPress plugin that extends WooCommerce, with 300,000+ installs, tried to fix a SQL injection vulnerability. The developer failed to accomplish that, in part because they were using the WordPress function sanitize_text_field() in an apparent attempt to sanitize user input to be used in a SQL statement. That doesn’t work.

The developer was using a prepared SQL statement, which would address this, if used properly, but it wasn’t used properly. Here is the statement: [Read more]

10 Jan 2024

WordPress Nonces Can Not Be Used for Authentication

Last week we looked at a situation where very popular security plugins are using a security function in a way that the documentation explicitly states it shouldn’t be used. That turns out to not be a one-off problem. WordPress’ documentation for usage of nonces states clearly that they should not be used for authentication:

Nonces should never be relied on for authentication, authorization, or access control. Protect your functions using current_user_can(), and always assume nonces can be compromised. [Read more]