Blog Post Icon
Blog
03/10/2020

How to sanitize and reset all WordPress user accounts with linux shell scripting and wp-cli

Mass update wordpress user passwords and core files

Hello!

There are several key best practices insofar as how to deal with security intrusions, including but not limited to restoring from backups on a clean server. In this article, I will be going over how to create an automated shell script that completes the following actions across multiple WordPress sites on your linux server :

  • 1. Sanitize user and group permissions
  • 2. Sanitize WordPress core admin and include files
  • 3. Update WordPress Core
  • 4. Update All installed plugins
  • 5. Iterate through all WordPress user accounts and reset the passwords

The above actions can be implemented as part of a broader security policy when dealing with shared hosting environments where you are hosting multiple WordPress sites.

I will touch on each of the above items including the shell script snippets that are required to implement each. At the bottom of this article I will share the entirety of the shell script.

Sanitize user and group permissions for multiple WordPress sites

The purpose of this is to ensure that user and group permissions are sanitized and correct according to what is set on the root folder. First and foremost we want the bash shell script to iterate across all the WordPress sites on your server :

for obj0 in $(find /home/*/public_html/wp-config.php)
do
    root_folder=`echo $obj0 | sed 's/\/wp-config.php//g'`
    USER=$(stat -c '%U' ${root_folder})
    GROUP=$(stat -c '%G' ${root_folder})
    chown -R ${USER}:${GROUP} $root_folder

In the above snippet, we are creating a main for loop that we will use to iterate across all wordpress sites. The above snippet is assuming that all your wordpress sites are in the /home folder. You should be able to easily modify this to other folder structures.

The next few lines within the for-loop are obtaining the full path of the root folder utilizing sed to trim off the trailing part of the path. Then we are getting the user and group that is currently set on the root folder for that particular site, and storing them in respective variables.

The last line in the above snippet is the actual change owner command in linux to recursively set the user/group permissions that we obtained in those variables.

Sanitize the wordpress core files for multiple WordPress sites

For this step we will be taking a clean source of the wordpress core files and replacing each site’s wp-admin and wp-includes folder with the clean files. This in effect will sanitize the WordPress core files.

    echo "Doing ${root_folder} .. "
    cd $root_folder
    rm -rf wp-admin
    rm -rf wp-includes
    mkdir wp-admin
    mkdir wp-includes
    cp -rp /path-to/wpfiles/wp-admin/* ./wp-admin
    cp -rp /path-to/wpfiles/wp-includes/* ./wp-includes

In the above snippet, we are changing into the directory of the particular root folder for the particular site we are iterating within the for-loop. We then completely remove the wp-admin and wp-includes folder outright. We then recursively copy the cleanly downloaded and extracted WordPress core files and copy them into the newly re-created wp-admin and wp-includes folders. This will iterate across all sites within the for-loop.

Update WordPress core and all plugins for multiple WordPress sites

I will combine the next two steps of the shell script into this one section, because its fairly straightforward :

    wp core update
    wp plugin update --all 
    wp core update-db 

This is where we start to use the WordPress command-line interface. Even though we are copying a freshly downloaded template of the WordPress core files, we’ll run through the core update command as the first step.

Next we want to update all installed plugins. If your concerned about compatibility problems with just blindly updating all WordPress plugins, you could focus on a list of known vulnerable plugins that may be installed on your system. This is a bit more tricky to do logistically , not technically.

Lastly we run the database update portion to implement any schema changes that the core update may have required.

Mass update all WordPress users for multiple WordPress sites using wp-cli and bash scripting

This is the more interesting of all the steps. Remember we are still in the first for-loop iteration within that bash shell script (see the first step). We want to create one more nested for-loop that will iterate across all the WordPress users of each WordPress site, and then securely change their passwords :

    for obj1 in $(wp user list --field=user_login --debug=false)
    do
        pass_gen=`pwgen -cny1 25 1`
        echo "Resetting user ${obj1} with pass ${pass_gen} .."
        wp user update $obj1 --user_pass="${pass_gen}" --debug=false
    done

In the above snippet, we are building a nested for-loop to build a list of all WordPress users for a particular site using the wp-cli user list command. Then we iterate across all the results.

In the first command run within the nested for-loop, we are using the PWGen linux command to securely generate random strong passwords 25 characters in length.

Alternatively if you didn’t want to install the PWGen (which is in most package manager / repositories), you could use any number of the following commands to generate random passwords :

date +%s | sha256sum | base64 | head -c 32 ; echo
< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-32};echo;
openssl rand -base64 32
tr -cd '[:alnum:]' < /dev/urandom | fold -w30 | head -n1
strings /dev/urandom | grep -o '[[:alnum:]]' | head -n 30 | tr -d '\n'; echo

You get the idea, right? The last command in the first snippet of this section is the user update wp-cli comamnd. We are essentially using wp-cli to set the randomly generated password during the nested for-loop iteration of each user of each site on your server.

As part of a security or password retention policy on your server, this can easily be implemented to help facilitate and automate the process from start to finish. Alternatively in an intrusion scenario where one or more sites may be compromised, this script could prove to be an effective first response to ensure everything is sanitized and rotated. Obviously more steps need to be taken to ensure an intrusion is mitigated, but this will definitely save time.

I should also note that there is risk of data loss with this script if it is not properly tested in your environment so please take extra care and use caution when implementing on your system.

Find the full bash script below for reference :

#!/bin/sh

for obj0 in $(find /home/*/public_html/wp-config.php)
do
    root_folder=`echo $obj0 | sed 's/\/wp-config.php//g'`
    USER=$(stat -c '%U' ${root_folder})
    GROUP=$(stat -c '%G' ${root_folder})
    cd $root_folder
    echo "Doing ${root_folder} .. "
    echo $USER
    echo $GROUP
    rm -rf wp-admin
    rm -rf wp-includes
    mkdir wp-admin
    mkdir wp-includes
    cp -rp ~/wpfiles/wp-admin/* ./wp-admin
    cp -rp ~/wpfiles/wp-includes/* ./wp-includes
    wp core update --allow-root
    wp plugin update --all 
    wp core update-db 
    chown -R ${USER}:${GROUP} $root_folder
    for obj1 in $(wp user list --field=user_login --debug=false)
    do
        pass_gen=`pwgen -cny1 25 1`
        echo "Resetting user ${obj1} with pass ${pass_gen} .."
        wp user update $obj1 --user_pass="${pass_gen}" --debug=false
    done
done

At Shift8, we cater to all sorts of businesses in and around Toronto from small, medium, large and enterprise projects. We are comfortable adapting to your existing processes and try our best to compliment communication and collaboration to the point where every step of the way is as efficient as possible.

Our projects are typically broken into 5 or 6 key “milestones” which focus heavily on the design collaboration in the early stages. We mock-up any interactive or unique page within your new website so that you get a clear picture of exactly how your design vision will be translated into a functional website.

Using tools like Basecamp and Redpen, we try to make the process simple yet fun and effective. We will revise your vision as many times as necessary until you are 100% happy, before moving to the functional, content integration and development phases of the project.

For the projects that are more development heavy, we make sure a considerable amount of effort is spent in the preliminary stages of project planning. We strongly believe that full transparency with a project development plan ensures that expectations are met on both sides between us and the client. We want to ensure that the project is broken into intelligent phases with accurate budgetary and timeline breakdowns.

Approved design mock-ups get translated into a browse-ready project site where we revise again and again until you are satisfied. Client satisfaction is our lifeblood and main motivation. We aren’t happy until you are.

Need Web Design?

Fill out the form to get a free consultation.

shift8 web toronto – 416-479-0685
203A-116 geary ave. toronto, on M6H 4H1, Canada
© 2023. All Rights Reserved by Star Dot Hosting Inc.

contact us
phone: 416-479-0685
toll free: 1-866-932-9083 (press 1)
email: sales@shift8web.com

Shift8 Logo