Patchstack Weekly #27: How to Update wp_options Securely.

Published 13 June 2022
Updated 24 July 2023
Robert Rowley
Author at Patchstack
Table of Contents

Welcome back to the Patchstack Weekly Security Update! This update is for week 24 of 2022.

This week I will cover two high risk unauthenticated vulnerabilities, one could allow attackers to reset an any user's password (including admin users) and the other could arbitrarily delete files from websites running insecure versions of the plugin.

Thankfully both have been patched, so now it's up to site owners to apply that patch as soon as they can.

In this week's knowledge share, i will talk about a WordPress specific security bug. This security bug only applies to WordPress websites, because it has to do with the risks involved if users are able to update, or change values in the wp_options table.

If you're curious what could go wrong if attackers can update the options table values, stick around for this week's knowledge share.

Vulnerability News

ARMember - Unauthenticated Password Resets

ARMember - WordPress membership plugin

Users of the ARMember plugin should update to the newest release ASAP. The developers patched a security bug recently which could have allowed anyone to reset any user's password on the website. The attackers only need to know the login name for the user they wished to update the password for, so if your sites have left a default "admin" account, or allow username enumeration, then you may be at high risk of attack until you patch this plugin.

Product Configurator for WooCommerce - Unauthenticated Arbitrary File Deletion

Product configurator for WooCommerce - WordPress plugin

The developers of the Product Configurator for WooCommerce plugin released a patch to prevent arbitrary file deletions. This is functionality you certainly do not want to leave available for anyone, even unauthenticated, to perform on your website, so patching this plugin should be a priority.

Weekly Knowledge

Updating wp_options, securely.

What is updating options all about?

The WordPress database structure is complicated, but one table stands alone. The wp_options table is a set of name/value pairs which is used by the WordPress application to set preferences and settings site-wide.

Some default values set in the options table may help you understand the purpose of this table:

  • admin_email
    • The administrator of the website's email address (Did you ever notice WordPress site's do not email all administrator users? That is because WordPress uses the this value in wp_options to as the official WordPress site owner's email address.)
  • users_can_register
    • This enables or disables if the WordPress site allows anyone to register new users.
  • default_role
    • This is the default role for new user registrations. By default this is set to "subscriber".
  • siteurl
    • This is the URL of the WordPress website, useful for building more complete URLs for specific pages.
  • home
    • Much like siteurl, and normally the same value (but it can be different) the home option is the URL of the blog's home page.

I hope these examples show you some of the values you can set in wp_options, and why they are site-wide settings.

Remember to check capabilities.

I have written about checking capabilities before in these Patchstack weekly episodes, and it is important to remember to check capabilities of the user before calling update_option(). The capability you're looking to verify against is 'manage_options'

The code may look something like this:

if( ! current_user_can('manage_options') ) { exit(); }
// or
if(current_user_can('manage_options')) { /*** Your function code here ***/ }

The only default user role with the 'manage_options' capability is the administrator role. If your code needs to allow users with author, or subscriber role permissions to update the data in the options table, then you may want to consider refactoring your code.

Remember, the wp_options table is for site wide settings, which should not be something every user on the web application should be able to update willy-nilly. This could result in users battling over setting and re-setting a site-wide option, so it's best left up to only the administrator users to set wp_option values.

What could go wrong?

If you have followed along thus far you may already have an idea how allowing non-administrators access to updating arbitrary option values may be dangerous. The key word here being "arbitrary", meaning any value.

Most developers who call update_option() do so using hard coded values for the option name they are updating. This should be the norm. However, on occasion, there have been security bugs in plugins that pop up due to developers calling update_option() and they use the value of an HTTP variable for the option name.

This can lead to some disastrous behavior.

An obvious risk would be if the siteurl or home option were changed. WordPress uses these to build URLs as well as a redirect browsers on the initial page load. I have seen attacks in the wild that use arbitrary option table update vulnerabilities to change the siteurl or home values to a malicious website. This effectively steals the insecure web site's traffic, and puts site visitors at risk.

Changing the siteurl or home option leaves a strong indicator of compromise though. Users may complain that they're being redirected, and search engines will detect this malicious redirect and remove the site from search results. This can lead to even more work needing to be done to get the website and it's traffic back to normal.

Patchstack has an article about what to do if your website is flagged for malware - give that article a read and you'll see how much effort it will take to undo the damage done from this sort of attack.

But redirecting visitors is not the worst that can happen due to insecure option table updates. Remember those other options I mentioned earlier? Can you ponder what the risks are manipulating the default_role and users_can_register options? I'll give you a second.

If an attacker can change arbitrary option values, they could set users_can_register to true, and then set the default_role to 'administrator'. Well, then all they need to do is register themselves a new user, and they'll have a band new administrator account they can log in with.

That's pretty bad, so always remember as a developer, never allow arbitrary option updates and always check capabilities before updating options.

As a site owner, you should always patch if there is word of an arbitrary options table update vulnerability on your WordPress website's plugins or themes.

Thanks and Appreciation

This week's thanks goes out to the developers of the ARMember and Product Configurator for WooCommerce plugins. Thank you for applying the security patches for your projects and in turn, securing your users' websites.

A further thank you is extended to the members of the Patchstack Alliance. The Alliance grew it's membership this month, with some highly respected researchers. Specific shout outs are earned by Rasi, Muhammed Daffa and Rotem Bar for winning the top 3 prize pools in May.

I will be back next week with more security tips, tricks, opinions and news on the Patchstack Weekly Security Update!

The latest in Patchstack Weekly

Looks like your browser is blocking our support chat widget. Turn off adblockers and reload the page.