[wp-trac] [WordPress Trac] #56141: Enhance installer security
noreply at wordpress.org
Tue Jul 5 08:37:14 UTC 2022
#56141: Enhance installer security
Reporter: smitka | Owner: (none)
Type: enhancement | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Security | Version: 6.0
Severity: normal | Keywords:
The WP installer needs to implement security features to prevent
unauthorized use. If the attacker finds an unfinished installer, he can
finish the installation on behalf of the user and make malicious changes.
It was hard to find these unfinished installers in the past, but from 2018
Google Chrome requires all publicly trusted web certificates to be logged
in Certificate Transparency Log. It is possible to parse CT log in
realtime and target newly created websites. Usually, the SSL certificate
is issued when a new hosting is set up. So, you can learn about most of
the newly created websites from the CT log. The CT log is huge and
reliable parsing should be challenging, but the methods are improving, and
this attack is becoming more common.
With current methods, **it can take less than a minute** for an attacker
to learn of and compromise a new site. The attacker needs **only one HTTP
request to compromise the site** - send valid DB credentials to /wp-admin
/setup-config.php?step=2. In this case, the WP installer creates wp-
config.php with these DB credentials. The user can then install WP into an
external database controlled by the attacker without noticing.
I analyzed a big-scale ongoing attack of this type and got access to the
attacker database to further investigation. He can compromise hundreds of
sites a day. I made an automated system to notify administrators of
compromised sites. During three days, I sent more than 600 notifications
and published the details on https://smitka.me/2022/07/01/wordpress-
Another installer issue, #52544, makes the installer publicly available
too, but the possibility of exploitation is rather accidental and more
I see two ways how to add additional protection without significant
process changes and without bothering the user too much:
1) allow only particular DB hosts
2) add an installation key feature
For the first one, I made a PoC mu-plugin which controls allowed DB hosts
via environment variables or configuration file.
Localhost + 127.0.0.1 is allowed by default, so there is no change for
many users. A web host can use the env variable to define their DB
servers, so the process will be smooth if they use external DB. If the
user wants to use any other server, he has an option to define them via
constant in the wp-dbhosts.php file (it is not possible to use wp-config
because it doesn't exist).
For the second one, you need to modify the installation workflow slightly.
I made a modified setup-config.php as PoC:
It combines the first method - if the DB host is localhost or any server
allowed by an environment variable, there is no change for users. If you
want to use any other DB host, you have to fill "install key". The
"install key" is generated into the install-key.php file, and the user can
read it via FTP (the same way he uploaded the core files).
Demo how it works: https://www.youtube.com/watch?v=A7-Sbbb-cZM
Ticket URL: <https://core.trac.wordpress.org/ticket/56141>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac