id summary reporter owner description type status priority milestone component version severity resolution keywords cc focuses 56141 Enhance installer security smitka "== Summary 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-installer-attack-race/. Another installer issue, #52544, makes the installer publicly available too, but the possibility of exploitation is rather accidental and more noticeable. == Recommendations 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. https://gist.github.com/lynt-smitka/425e4e97c61cac172e229ffc9ad090e4 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: https://gist.github.com/lynt-smitka/45608ddeb8df19b0820201d066d4b42c 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 " enhancement new high Future Release Security major dev-feedback