Como forzar contraseñas fuertes con filtros de WordPress en WordPress

Contents

Introducción

Forzar contraseñas fuertes en WordPress no es sólo una buena práctica: es una necesidad para proteger usuarios, datos y la integridad de tu sitio. WordPress ofrece una arquitectura por hooks (acciones y filtros) que permite validar y bloquear contraseñas débiles en distintos flujos: registro, edición de perfil, restablecimiento de contraseña y creación programática de usuarios. Este artículo describe con detalle las técnicas basadas en filtros de WordPress, ejemplos de implementación y recomendaciones prácticas para asegurar contraseñas en todos los puntos críticos.

Concepto básico: ¿qué son los filtros y por qué usarlos?

Los filtros en WordPress permiten alterar datos antes de su uso o guardado. Cuando validas una contraseña con un filtro, puedes impedir que se complete una operación (por ejemplo, un registro) o agregar mensajes de error consistentes. La ventaja es que tu lógica de validación queda centralizada y se aplica de forma coherente en múltiples flujos.

Estrategia general

  • Detectar todos los puntos donde se puede crear o cambiar una contraseña: registro público, edición de perfil (usuario y administrador), restablecimiento de contraseña y APIs/creación programática.
  • Validar la contraseña con una rutina centralizada que devuelva si es válida y, si no, los errores concretos.
  • Integrar la validación mediante filtros/acciones de WordPress en cada flujo relevante.
  • Proveer validación cliente (opcional) para mejorar UX, pero siempre validar en servidor (imprescindible).

Resumen de hooks útiles

Hook Cuándo Uso típico
registration_errors Durante el registro (wp-login.php) Validar contraseña en registros públicos
user_profile_update_errors Cuando un usuario/botón administra su perfil (wp-admin y pantalla de perfil) Validar al actualizar perfil o al crear usuario desde wp-admin
validate_password_reset Proceso de restablecimiento de contraseña Validar nueva contraseña tras enlace de reset
wp_insert_user_data (filtro) Antes de insertar/actualizar usuario en base de datos Última línea de defensa para creación programática

Reglas de ejemplo para una contraseña fuerte

  • Longitud mínima configurable (p. ej. 12).
  • Al menos una letra mayúscula y una minúscula.
  • Al menos un número.
  • Al menos un carácter especial.
  • Opcional: comprobación de diccionarios o uso de zxcvbn para puntuación de entropía.

Implementación completa (plugin simple)

A continuación tienes un ejemplo de plugin (puedes pegarlo en un archivo PHP dentro de wp-content/mu-plugins o como plugin normal). El plugin centraliza la lógica de validación y la engancha a los hooks principales: registro, perfil y restablecimiento.

 12,
        require_upper => true,
        require_lower => true,
        require_number => true,
        require_special => true,
    )
}

// Función central de validación. Devuelve array(valid => bool, errors => array())
function fcf_check_password_strength( password ) {
    s = fcf_get_settings()
    errors = array()

    if ( strlen( password ) < s[min_length] ) {
        errors[] = sprintf( La contraseña debe tener al menos %d caracteres., s[min_length] )
    }
    if ( s[require_upper]  ! preg_match( /[A-Z]/, password ) ) {
        errors[] = La contraseña debe contener al menos una letra mayúscula.
    }
    if ( s[require_lower]  ! preg_match( /[a-z]/, password ) ) {
        errors[] = La contraseña debe contener al menos una letra minúscula.
    }
    if ( s[require_number]  ! preg_match( /d/, password ) ) {
        errors[] = La contraseña debe contener al menos un número.
    }
    if ( s[require_special]  ! preg_match( /[W_]/, password ) ) {
        errors[] = La contraseña debe contener al menos un carácter especial (por ejemplo: !@#%).
    }

    // Si quieres integrar zxcvbn (mejor entropía), puedes añadir la comprobación aquí.
    // Por ejemplo, usar una librería PHP o validar score desde JS en cliente y repetir en servidor.

    return array(
        valid => empty( errors ),
        errors => errors,
    )
}

/
  1) Validar en registro público
  Hook: registration_errors
  Firma: apply_filters(registration_errors, WP_Error errors, sanitized_user_login, user_email)
 /
function fcf_registration_errors( errors, sanitized_user_login, user_email ) {
    // WordPress por defecto usa campos pass1/pass2 o user_pass intentamos captar ambos.
    password = 
    if ( ! empty( _POST[pass1] ) ) {
        password = _POST[pass1]
    } elseif ( ! empty( _POST[user_pass] ) ) {
        password = _POST[user_pass]
    }

    if ( password !==  ) {
        res = fcf_check_password_strength( password )
        if ( ! res[valid] ) {
            foreach ( res[errors] as msg ) {
                errors->add( weak_password, msg )
            }
        }
    }

    return errors
}
add_filter( registration_errors, fcf_registration_errors, 10, 3 )

/
  2) Validar en perfil/edición (por usuario o admin)
  Action: user_profile_update_errors
  Firma: do_action( user_profile_update_errors, WP_Error errors, update, user )
 /
function fcf_user_profile_update_errors( errors, update, user ) {
    if ( ! empty( _POST[pass1] ) ) {
        password = _POST[pass1]
        // Sólo validar si se está intentando cambiar la contraseña
        if ( password !==  ) {
            res = fcf_check_password_strength( password )
            if ( ! res[valid] ) {
                foreach ( res[errors] as msg ) {
                    errors->add( weak_password, msg )
                }
            }
        }
    }
}
add_action( user_profile_update_errors, fcf_user_profile_update_errors, 10, 3 )

/
  3) Validar en restablecimiento de contraseña
  Action: validate_password_reset
  Firma: do_action( validate_password_reset, WP_Error errors, WP_User user )
  Observación: en esta acción los nuevos passwords suelen venir en _POST[pass1]
 /
function fcf_validate_password_reset( errors, user ) {
    if ( ! empty( _POST[pass1] ) ) {
        password = _POST[pass1]
        res = fcf_check_password_strength( password )
        if ( ! res[valid] ) {
            foreach ( res[errors] as msg ) {
                errors->add( weak_password, msg )
            }
        }
    }
}
add_action( validate_password_reset, fcf_validate_password_reset, 10, 2 )

/
  4) (Opcional) Última línea de defensa: validar antes de insertar usuario programáticamente
  Filtro: wp_insert_user_data (WP 4.4 )
  Firma: apply_filters( wp_insert_user_data, array data, bool update )
 
  En este filtro no podemos devolver WP_Error. En su lugar, podemos lanzar un error por medio de
  wp_die() o registrar el error y evitar la inserción en el código de quien llama.
 
  En este ejemplo sólo bloqueamos si se detecta contraseña inválida y estamos en una operación
  donde la contraseña viene en data[user_pass].
 /
function fcf_wp_insert_user_data( data, update ) {
    if ( isset( data[user_pass] )  data[user_pass] !==  ) {
        res = fcf_check_password_strength( data[user_pass] )
        if ( ! res[valid] ) {
            // Aquí se opta por abortar la operación con wp_die() para dejar claro el problema.
            // Alternativamente, puedes registrar y dejar que el desarrollador maneje el caso.
            msg = implode(  , res[errors] )
            wp_die( Contraseña inválida:  . esc_html( msg ) )
        }
    }
    return data
}
add_filter( wp_insert_user_data, fcf_wp_insert_user_data, 10, 2 )

?>

Notas sobre el plugin de ejemplo

  • La validación en servidor es la única que garantiza seguridad. Validación cliente (JS) mejora la experiencia, pero no sustituye la validación en PHP.
  • Si instalas bibliotecas de puntuación como zxcvbn, úsalas en servidor para evaluar entropía además de las reglas regex.
  • Si usas wp_die() en wp_insert_user_data puedes interrumpir flujos programáticos en entornos donde otras aplicaciones crean usuarios por API, considera devolver errores controlados o disparar WP_Error para que la aplicación llamante los maneje.

Validación en el lado cliente (mejora UX)

Para no frustrar usuarios es recomendable mostrar en tiempo real si la contraseña cumple las reglas. Aquí tienes un ejemplo JS que comprueba reglas básicas (también puedes integrar zxcvbn en frontend).

// Ejemplo simple (añadir en la página de registro o perfil)
document.addEventListener(DOMContentLoaded, function(){
  var pass1 = document.querySelector(#pass1)  document.querySelector(input[name=pass1])
  var msgBox = document.createElement(div)
  if (!pass1) return
  pass1.parentNode.appendChild(msgBox)
  pass1.addEventListener(input, function(){
    var v = pass1.value
    var errors = []
    if (v.length lt 12) errors.push(Mínimo 12 caracteres)
    if (!/[A-Z]/.test(v)) errors.push(Falta mayúscula)
    if (!/[a-z]/.test(v)) errors.push(Falta minúscula)
    if (!/d/.test(v)) errors.push(Falta número)
    if (!/[W_]/.test(v)) errors.push(Falta carácter especial)
    if (errors.length) {
      msgBox.style.color = red
      msgBox.textContent = Contraseña débil:    errors.join(, )
    } else {
      msgBox.style.color = green
      msgBox.textContent = Contraseña válida
    }
  })
})

Compatibilidad con plugins y consideraciones especiales

  • Plugins que gestionan registros (p. ej. WooCommerce, BuddyPress, plugins de membresía) usan sus propias pantallas y hooks. Integra tu validación usando los hooks específicos del plugin además de los hooks de WordPress mostrados.
  • En entornos multisitio revisa los flujos de registro de red y site para engancharte a los hooks correctos.
  • Si permites que un administrador cree usuarios con contraseñas sencillas por motivos operativos, añade una excepción basada en la capacidad: por ejemplo, si current_user_can(manage_options) permitir saltarse la norma (aunque no recomendado).
  • Evita mensajes genéricos. Indica claramente qué regla no se cumple para que el usuario pueda corregir la contraseña.

Recomendaciones finales

  1. Aplica reglas mínimas coherentes con la sensibilidad de los datos del sitio. Para sitios críticos, exige más (longitud mayor, verificación con listas negras, zxcvbn).
  2. Registra intentos repetidos de creación de contraseñas débiles: puede indicar ataques automatizados.
  3. Evita forzar reglas muy complejas que incentiven a los usuarios a reutilizar contraseñas o escribirlas en notas prefiera longitud y frases de paso (passphrases) si es posible.
  4. Complementa con autenticación de dos factores (2FA) para usuarios con permisos importantes.

Conclusión

Forzar contraseñas fuertes con filtros de WordPress es una estrategia sólida y centralizada que mejora la seguridad de tu sitio. Implementando una rutina de validación reutilizable y enganchándola a los hooks adecuados (registro, perfil, restablecimiento y creación programática) cubres la mayoría de puntos de entrada. Añade validación cliente para mejorar la experiencia y, en entornos más exigentes, integra herramientas de análisis de entropía (zxcvbn) y políticas complementarias como 2FA.



Acepto donaciones de BAT's mediante el navegador Brave 🙂



Deja una respuesta

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