Security researchers at Wordfence identified an Arbitrary User Password Change vulnerability in LearnDash LMS plugin, a WordPress plugin that is actively installed on more than 100,000 WordPress websites.

This vulnerability makes it possible for any user with an existing account to reset arbitrary user passwords, including user accounts with administrative-level access.

The LearnDash LMS plugin provides the shortcode ‘[ld_reset_password]‘ to embed a password reset form into a page on a WordPress site. The form allows users to submit their username or email address to receive an email with a password reset link containing a user activation key.

Examining the code reveals that the plugin checks that the user activation key belongs to the given user with the learndash_reset_password_verification() function only when displaying the new password form, where the new password can be entered.

f ( isset( $_GET['action'] ) && 'rp' === $_GET['action'] ) {
    $key        = ( isset( $_GET['key'] ) ? sanitize_text_field( wp_unslash( $_GET['key'] ) ) : '' );
    $user       = ( isset( $_GET['login'] ) ? get_user_by( 'login', sanitize_text_field( wp_unslash( $_GET['login'] ) ) ) : '' );
    $key_verify = learndash_reset_password_verification( $user, $key );
    if ( 'WP_Error' === get_class( $key_verify ) ) {
        $status['message'] = esc_html__( 'Invalid key, please check your reset password link and try again.', 'learndash' );
        $status['type']    = 'warning';
        $status['action']  = 'prevent_reset';

Verifying the key at the ‘rp’ action

Buy Me A Coffee
if ( isset( $_GET['action'] ) && 'rp' === $_GET['action'] && ! isset( $status ) ) {
    <form action="" method="POST">

Display the ‘rp’ form if the status is not an error

However, there is no user activation key check when processing this form. This makes it possible for any authenticated user who has accessed the password reset form via the link sent in the email to modify the password of another user by changing the value of the username hidden input field.

if (
    isset( $_POST['user_login'] )
    && isset( $_POST['reset_password'] )
    && ! empty( $_POST['learndash-reset-password-form-post-nonce'] )
    && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['learndash-reset-password-form-post-nonce'] ) ), 'learndash-reset-password-form-post-nonce' )
) {
    $new_password = sanitize_text_field( wp_unslash( $_POST['reset_password'] ) );
    $user         = get_user_by( 'login', sanitize_text_field( wp_unslash( $_POST['user_login'] ) ) );
    learndash_reset_password_set_user_new_password( $user, $new_password );

Processing the new password setting form

As with any Arbitrary User Password Change that leads to a Privilege Escalation vulnerability, this can be used for complete site compromise. Once an attacker has gained administrative user access to a WordPress site they can then manipulate anything on the targeted site as a normal administrator would. This includes the ability to upload plugin and theme files, which can be malicious zip files containing backdoors, and modifying posts and pages which can be leveraged to redirect site users to other malicious sites.

Hackers Continued to Use Malware, Tools in Q1 that Let Their Operations Go Undetected: Report

The vulnerability has been fully addressed in version of the plugin.

We encourage WordPress users to verify that their sites are updated to the latest patched version of LearnDash LMS.