Misuse of WordPress WP-CLI could leak user passwords.


Jerome Bruandet

WP-CLI is a command line interface for WordPress. It is a nice and very helpful tool if you want to manage a lot of WordPress installations from a Unix shell.

A few days ago, after cleaning-up a hacked WordPress website, I was checking the HTTP server logs in order to find out how hackers gained access to the site. It didn't take long to find this suspicious entry: - - [02/Apr/2018:18:04:11 +0200] "GET /wp-content/plugins/site-editor/editor/extensions/pagebuilder/includes/ajax_shortcode_pattern.php?ajax_path=../../../../../../../../.bash_history HTTP/1.1" 200 3922 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)" "-"

It shows that someone exploited a recent vulnerability known as Local File Inclusion (or LFI) in the Site Editor plugin. This kind of exploit lets you download files from the remote server. The downloaded file was ".bash_history", which is used to store the user commands entered at the command prompt, and is located in the user home folder.
Inside the file, among many other commands, I found this interesting one:

wp user create support [redacted]@gmail.com --role=administrator --user_pass=[redacted]  

Our customer, who's an avid WP-CLI user, used it to create a WordPress administrator account but he forgot one important detail: shell commands are saved to the ".bash_history", and thus the whole command leaks its login name (support) and password as well! Obviously, after downloading this file, it wasn't difficult for hackers to gain access to the admin dashboard.

Inserting credentials or any confidential data in a shell command (be it WP-CLI or MySQL for instance) is extremely insecure:

  • The command is saved to the ".bash_history" file; it can also be viewed by running the history shell command.
  • On a shared host, other users could view the whole command, including the credentials, simply by using the Unix ps command.

Fortunately, WP-CLI has a --prompt option which can be used to ask for the password (and basically any other options) rather than leaking it to the whole world. In this example, I'm creating an "alice" admin account:

$ wp user create alice alice@wonderland.com --role=administrator --prompt=user_pass 

WP-CLI will prompt for the password:

4/16 [--user_pass=]:  


A powerful antivirus
scanner for WordPress.


Website Monitoring
for just .99 per month.


Web Application Firewall
for PHP and WordPress.


Malware removal
and hacking recovery.

Table of contents