Seguridad WordPress

Evitar la enumeración de usuarios en WordPress parte 2

En el artículo anterior veíamos lo que era la enumeración de usuarios y cómo un atacante malintencionado podría conseguir nuestro nombre de usuario a través de la URL amigable del enlace de Autor, o utilizando herramientas como WP Scan.

Otra forma de averiguar el nombre de usuario es intentando acceder al panel de control de nuestro WordPress.

Enumeración de usuarios haciendo login en WordPress

Por defecto para intentar acceder al panel de administración de un sitio basta con escribir en la url misitio.es/wp-admin/ ó misitio.es/wp-login.php. Lo ideal es que protegas el acceso a al archivo wp-login.php como podrás encontrar en este artículo, y el acceso a wp-admin como puedes encontrar en este otro.

Si alguien puede acceder al formulario de login de tu WordPress, en este caso la vulnerabilidad viene dada por los mensajes de error que obtenemos si intentamos acceder al admin con usuario y/o contraseña incorrectos. Es decir, si intentamos acceder con un usuario que no existe obtendremos el mensaje:

Nombre de usuario no válido

y si lo hacemos con un usuario que existe, el mensaje será:

Enumeración de usuario

En el primer caso me está diciendo que el nombre de usuario que estoy utilizando no es válido (por lo tanto puedo descartarlo), y en el segundo caso me está diciendo que existe un usuario llamado admin, pero que la contraseña es incorrecta. Por lo tanto, a través de los mensajes de error podemos saber si un usuario existe o no.

Empresas auditoras de seguridad exponen en sus informes:

«Se recomienda utilizar mensajes genéricos en los procesos de autenticación y recuperación de contraseñas, que no permitan determinar la existencia de un usuario en la base de datos de la aplicación».

Vamos a ver como modificar estos mensajes para utilizar unos más genéricos en su lugar y evitar la enumeración de usuarios. A través del filtro login_errors podemos acceder a estos mensajes. Obtendremos un array y buscaremos los índices invalid_username, invalid_email (recordemos que desde la versión 4.5 podemos logearnos con el e-mail también) e incorret_password, para modificar estos mensajes. Agregamos en el archivo functions.php estas líneas:

<?php

function my_custom_error_login_messages ( $error ) {
    global $errors;

    $err_codes = $errors->get_error_codes();

    // Invalid username.
    // Default: '<strong>ERROR</strong>: Invalid username. <a href="%s">Lost your password</a>?'
    if ( in_array( 'invalid_username', $err_codes ) ) {
        $error = '<strong>ERROR</strong>: Datos incorrectos. <a href="wp-login.php?action=lostpassword">¿Has olvidado tus datos?</a>';
    }

    // Invalid email.
    if ( in_array( 'invalid_email', $err_codes ) ) {
        $error = '<strong>ERROR</strong>: Datos incorrectos. <a href="wp-login.php?action=lostpassword">¿Has olvidado tus datos?</a>';
    }

    // Incorrect password.
    if ( in_array( 'incorrect_password', $err_codes ) ) {
        $error = '<strong>ERROR</strong>: Datos incorrectos. <a href="wp-login.php?action=lostpassword">¿Has olvidado tus datos?</a>';
    }

    return $error;
}
add_filter( 'login_errors', 'my_custom_error_login_messages' );

De esta manera no sabrán si lo que hemos metido mal es el usuario o la contraseña:

mensaje error genérico

¿Te ha resultado útil esta información? 🍺

Si este post te ha resuelto un problema, invítame a un café o a una cerveza. Con este pequeño gesto me animas a seguir escribiendo.

Comentarios

2 comentarios en Evitar la enumeración de usuarios en WordPress parte 2

  1. Con esto evitamos que puedan averiguar nombres de usuario, o correos que estén dados de alta. Pero en el formulario «Has perdido/olvidado tu contraseña?» se pueden averiguar ya que los correos que no están de alta devolverá el error «Datos incorrectos», y al poner un correo válido devolverá «Comprueba tu correo electrónico para el enlace de confirmación y, después, visita la página de acceso.» ¿Es posible evitar esto? Solo se me ocurre no dar la posibilidad de recuperar la contraseña de este modo sino indicando que se haga por correo, pero ya me está fastidiando a los usuarios y a mí.

    1. Buen apunte Juan. No me ha dado tiempo a probarlo, pero parece que el índice de error en este escenario es «invalidcombo», añadiendo un if más en la función my_custom_error_login_messages debería servirte para escribir un mensaje personalizado en el formulario de recuperar contraseña.

      Lo malo es que si metes un correo electrónico que si existe, la pantalla cambia y no te permite seguir probando, es decir, ha encontrado un correo existente y ha enviado un mail para la recuperación de la contraseña. Aunque cambies este mensaje (el índice sería «confirm»), el hecho de haber cambiado de pantalla ya es relevante para saber que ese correo existe.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *:

  • El fin del tratamiento es únicamente la moderación de comentarios para evitar spam
  • La legitimación es tu consentimiento al comentar
  • No se comunicará ningún dato a terceros salvo por obligación legal
  • Tienes derecho al acceso, rectificación y eliminación de los comentarios