Understanding the Wordpress vulnerability Understanding the Wordpress vulnerability wordpress wordpress

Understanding the Wordpress vulnerability


So $key is an array in the querystring with a single empty string ['']

http://DOMAIN_NAME.TLD/wp-login.php?action=rp&key[]=

reset_password gets called with an array, and then preg_replace gets called:

 //$key = [''] $key = preg_replace('/[^a-z0-9]/i', '', $key); //$key = [''] still

because preg_replace accepts either a string or an array of strings. It regex replaces nothing and returns the same array. $key is not empty (it's an array of an empty string) so this happens:

 $user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->users       WHERE user_activation_key = %s", $key));

Now from here, I need to go read the wordpress source for how prepare behaves...

More:

So prepare calls vsprintf which produces an empty string

$a = array('');$b = array($a);vsprintf("%s", $b);//Does not produce anything

So the SQL is:

SELECT * FROM $wpdb->users WHERE user_activation_key = ''

Which will apparently match the admin user (and all users without activation_keys I suppose).

And that's how.


I have a related question on how to patch this vulnerability - line 190 on the wp-login.php should now look like this;

if ( empty( $key ) || is_array( $key ) )