Decimos que la enumeración está confirmada cuando una petición del tipo:

  • https://su-dominio.tld/?author=1

produce una respuesta que permite inferir si existe un autor y, además, suele terminar revelando la URL canónica del archivo del autor:

  • https://su-dominio.tld/author/<slug>/

En términos operativos, esto convierte un ID numérico secuencial en un mecanismo para descubrir autores válidos (y, en algunos casos, un identificador reutilizable como el slug del autor).

Este comportamiento se entiende porque WordPress utiliza variables de consulta (query vars) para construir la consulta principal, y la variable author forma parte del ecosistema de query vars que alimentan la lógica de consulta y plantillas.

📌 Guía completa: Seguridad WordPress (checklist + prioridades).

✅ Acción rápida: Iniciar auditoría gratis y recibir evidencias en minutos.


1) Por qué ocurre en WordPress

Hay dos piezas típicas detrás de este patrón:

1.1 La request construye una “consulta de autor”

WordPress dispone de la condición is_author() para determinar si la consulta actual corresponde a un archivo de autor existente.
Si la request /?author=ID se interpreta como consulta de autor, el sistema entra en esa ruta lógica.

1.2 Redirecciones canónicas (SEO) que “corrigen” a la URL correcta

WordPress intenta normalizar URLs “alternativas” hacia una versión canónica mediante redirect_canonical(). Su propia documentación explica que la función intenta encontrar el enlace correcto cuando la URL solicitada no coincide exactamente con la consulta esperada y redirigir al destino correcto.

Traducción: si se solicita una variante de URL basada en query var (?author=ID), WordPress puede redirigirla a la versión “bonita” (/author/slug/) cuando lo considera canónico.


2) Impacto real: cuándo es un riesgo relevante

Por sí sola, la enumeración por /?author=ID rara vez es “crítica”. Lo tratamos como factor de riesgo que facilita reconocimiento y automatización, y su gravedad depende del contexto.

OWASP incluye la enumeración de cuentas como una categoría de pruebas de identidad: el objetivo es verificar si es posible recolectar nombres de usuario válidos interactuando con el sistema.

Escenario de bajo impacto

  • Sitio editorial donde los autores son públicos por diseño.
  • Postura de autenticación madura (2FA, rate limiting, WAF, contraseñas robustas).

Escenario de impacto moderado/alto (riesgo compuesto)

  • Login/administración expuestos públicamente.
  • Sin 2FA o con controles anti-automatización débiles.
  • Autores con slugs “sensibles” (parecidos a logins internos o convenciones corporativas).

En estos casos, enumerar autores reduce el coste de ataque y facilita fuerza bruta/credential stuffing (usuario válido + prueba de credenciales).


3) Cómo verificamos con evidencia (sin asumir)

Recomendamos validar con 3 comprobaciones simples:

  1. Comportamiento de redirección
  • Solicitar /?author=1 y observar si hay:
    • 301/302 hacia /author/<slug>/ (confirmación fuerte de enumeración vía canónica).
  1. Diferenciación de respuesta
  • Probar /?author=1 vs /?author=999999:
    • si la respuesta difiere de forma consistente (redirect/200 vs 404), hay señal útil de enumeración.
  1. Confirmación de tipo de página
  • Confirmar si el destino es realmente archivo de autor (WordPress lo identifica como “author archive” y is_author() aplica).

4) Cómo bloquearlo: opciones por impacto (recomendación profesional)

Aquí proponemos un orden que minimiza roturas.

Opción A — Si el negocio NO necesita páginas /author/: desactivar author archives (solución más limpia)

Si no existe valor editorial/SEO en author pages, lo más robusto es hacer que is_author() devuelva 404, evitando tanto /author/<slug>/ como derivaciones.

El hook template_redirect se ejecuta justo antes de decidir qué plantilla cargar, y es el punto correcto para aplicar lógica con conocimiento de la consulta ya resuelta.

Implementación recomendada (MU-plugin):

<?php
/**
 * Plugin Name: Policy - Disable Author Archives
 */

add_action('template_redirect', function () {
    if (is_author()) { // author archive detectado
        global $wp_query;
        $wp_query->set_404();
        status_header(404);
        nocache_headers();
        include get_404_template();
        exit;
    }
});
  • is_author() define explícitamente si la query es un archivo de autor existente.
  • template_redirect es apropiado para este tipo de control.

Ventaja: elimina la superficie, no solo “tapa” el síntoma.
Riesgo: si su SEO/UX depende de author pages, esto puede afectar.

Alternativa “sin código”: existe un plugin dedicado que desactiva archivos de autor devolviendo 404.


Opción B — Mantener /author/ pero bloquear la vía /?author=ID (quirúrgico)

Si sí queremos author pages, pero no queremos que /?author=ID sirva para enumerar, podemos neutralizar la redirección canónica en ese caso concreto.

  • redirect_canonical() es la función que aplica redirección canónica.
  • En lugar de desactivar canónicas globalmente (no recomendable), aplicamos un filtro/condición solo cuando viene author en la query.

Enfoque recomendado (solo para author):

add_filter('redirect_canonical', function ($redirect_url, $requested_url) {
    if (isset($_GET['author']) && is_numeric($_GET['author'])) {
        return false; // cancelar redirección canónica para /?author=ID
    }
    return $redirect_url;
}, 10, 2);

Notas operativas:

  • Este enfoque busca evitar que WordPress “corrija” /?author=ID a /author/<slug>/. La canónica existe por motivos SEO y duplicados, así que la restringimos solo al caso conflictivo.
  • Tras aplicarlo, debemos verificar que no se introducen URLs duplicadas indexables (si la canónica se usaba para otros casos).

Opción C — Bloqueo en servidor (rápido y eficiente) o WAF (más flexible)

Si queremos cortar el patrón antes de que llegue a WordPress:

Servidor (conceptual):

  • Bloquear requests con query author= (o devolver 404).
  • Esta vía es efectiva y reduce consumo de PHP.

WAF / rate limiting:

  • Si preferimos no bloquear (por posibles usos legítimos), aplicamos rate limiting sobre requests que incluyan author= o sobre /author/.
  • Es especialmente útil cuando el objetivo es frenar bots, no impedir el acceso humano.

5) Recomendación estándar por tipo de sitio

Sitio corporativo / institucional

  • Recomendamos Opción A: desactivar author archives (404).
  • Complemento: retirar sitemap de usuarios/autores si existe (reduce agregación).

Blog multi-autor con estrategia editorial

  • Recomendamos mantener author pages y aplicar:
    • Opción B (bloquear /?author=ID), y/o
    • WAF/rate limiting sobre patrones de enumeración.

6) Checklist de cierre (criterios de aceptación)

Consideramos el hallazgo mitigado cuando:

  • /?author=ID ya no redirige a /author/<slug>/ (o devuelve 404/neutral).
  • Si /author/ no es necesario, is_author() termina en 404 de forma consistente.
  • Si /author/ se mantiene por SEO/UX, existe control compensatorio (rate limiting/WAF) y se evita agregación innecesaria.
  • Se ha verificado que el cambio no rompe navegación ni introduce problemas SEO graves (canónicas y duplicados).

OWASP recomienda tratar la enumeración como un riesgo que puede facilitar recolección de usuarios válidos, especialmente relevante cuando se combina con ataques de autenticación.


7) Preguntas frecuentes

¿Bloquear /?author=ID “arregla” todo?

No. Solo elimina una vía concreta de enumeración. Si los autores son visibles en el frontend, seguirán siendo públicos (por diseño). La mitigación correcta depende del modelo editorial y de la postura de autenticación.

¿Debemos desactivar redirecciones canónicas globalmente?

No lo recomendamos. La canónica es una medida SEO general; WordPress la aplica para normalizar URLs y reducir duplicados. La práctica profesional es desactivarla solo donde genera un riesgo o un efecto no deseado, como en author=ID.