La REST API de WordPress expone por defecto los usuarios, IDs, slugs y metadatos del sitio sin pedir ninguna autenticación. Para proteger la REST API de WordPress en 2026 necesitás tres capas: restringir endpoints públicos, implementar autenticación robusta y activar rate limiting. Sin eso, cualquier bot de reconocimiento lo detecta en minutos.
La REST API de WordPress es la interfaz que permite a aplicaciones externas, plugins y el editor Gutenberg interactuar con el sitio mediante peticiones HTTP. Disponible por defecto desde WordPress 4.7, expone endpoints bajo /wp-json/ que cualquiera puede consultar sin autenticación. El endpoint más problemático: /wp/v2/users, que lista todos los usuarios registrados con sus nombres, slugs e IDs sin requerir ningún login.
En 30 segundos
/wp-json/wp/v2/usersdevuelve la lista completa de usuarios del sitio sin autenticación: nombre, slug e ID, los datos exactos que necesita cualquier ataque de fuerza bruta.- CVE-2025-24000 en el plugin Post SMTP permitió que un suscriptor escalara a administrador porque el
permission_callbackdevolvíatruepara cualquier usuario sin verificar capacidades. - La medida más urgente es eliminar el endpoint
/wp/v2/users; la más completa es requerir autenticación para todas las peticiones anónimas. - Application Passwords (nativo desde WP 5.6) y JWT son los métodos de autenticación más recomendados en 2026 para integraciones externas.
- Wordfence puede bloquear
/wp-json/*para usuarios no autenticados sin tocar código, pero no reemplaza configurar bien lospermission_callbackde tus propios endpoints.
¿Qué es la REST API de WordPress y por qué representa un riesgo de seguridad?
Ponele que instalás un WordPress nuevo hoy. Sin tocar nada, sin activar ningún plugin de seguridad, la URL tusitio.com/wp-json/wp/v2/users ya está activa y responde con el nombre, slug, ID y URL de avatar de todos tus usuarios registrados. Cualquier persona con acceso a internet puede consultarla ahora mismo.
No es un bug. Es una decisión de diseño de WordPress 4.7 (2016) que tiene diez años y no cambió por defecto. La lógica original era que esa información es «pública» en muchos sitios. El problema es que para un atacante, esos datos son el primer paso de un ataque de fuerza bruta: ya tiene los nombres de usuario, solo le falta la contraseña.
Más allá del endpoint de usuarios, la REST API expone por defecto:
/wp/v2/postsy/wp/v2/pages: contenido publicado, revisiones y metadatos de estructura accesibles sin ninguna autenticación./wp/v2/media: listado de archivos subidos al sitio, con URLs directas a cada archivo./wp/v2/typesy/wp/v2/taxonomies: información sobre la estructura del sitio que sirve para reconocimiento automatizado.- Endpoints de plugins: cada plugin que usa la REST API agrega los suyos propios, y no todos los implementan con los controles necesarios (ahí entran los CVEs más graves).
¿Por qué los atacantes la usan? Porque es cómoda, rápida y discreta. Un escaneo con curl o cualquier herramienta automatizada tarda segundos en mapear toda la estructura del sitio. No genera errores 404 visibles, y es el tipo de reconocimiento que muchos administradores no monitorean activamente en sus logs.
La enumeración de usuarios: cómo los atacantes obtienen nombres de usuario desde wp-json
Una petición GET a https://tusitio.com/wp-json/wp/v2/users devuelve algo así:
[
{
"id": 1,
"name": "ariel.blanco",
"slug": "ariel-blanco",
"description": "",
"link": "https://tusitio.com/author/ariel-blanco/",
"avatar_urls": { "24": "...", "48": "...", "96": "..." }
}
]
Con eso el atacante tiene el nombre de usuario exacto. A partir de ahí arma una lista de credenciales, la combina con contraseñas comunes y ataca el formulario de login o el endpoint /wp-login.php con diccionario. Si el usuario no tiene una contraseña fuerte, la probabilidad de éxito sube bastante. Tema relacionado: defensa en capas de tu infraestructura.
El caso más ilustrativo de 2025 en este contexto fue CVE-2025-24000 en el plugin Post SMTP. Un atacante con cuenta de suscriptor (el nivel más bajo de acceso) podía escalar a administrador completo porque el plugin registraba un endpoint en la REST API con 'permission_callback' => '__return_true'. Eso significa que el callback devolvía true para cualquier usuario, sin verificar ninguna capacidad real. El atacante mandaba la petición directamente, sin pasar por ninguna interfaz del plugin, y podía manipular logs de email para modificar credenciales de administrador.
¿Alguien lo verificó de forma independiente antes de que saliera el parche? No a tiempo. Según el reporte de Solid WP de agosto de 2025, una parte significativa de las vulnerabilidades de plugins de ese período involucraba endpoints de la REST API con controles de autenticación insuficientes. El patrón se repite: el desarrollador registra el endpoint pero implementa el permission_callback de forma incompleta o directamente no lo implementa.
Cómo restringir la REST API sin romper tu sitio
Acá viene la parte donde más gente se equivoca. Deshabilitar la REST API «completamente» suena bien en el papel, pero rompe el editor Gutenberg, los plugins de formularios, los widgets dinámicos y prácticamente cualquier integración moderna. La opción nuclear no es la solución.
Hay tres enfoques que zafan bien, de menor a mayor agresividad:
Opción 1: bloquear solo el endpoint de usuarios
La medida más quirúrgica. Elimina el endpoint que expone usuarios sin tocar nada más:
add_filter( 'rest_endpoints', function( $endpoints ) {
if ( isset( $endpoints['/wp/v2/users'] ) ) {
unset( $endpoints['/wp/v2/users'] );
}
if ( isset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] ) ) {
unset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] );
}
return $endpoints;
} );
Esto va en functions.php o en un plugin personalizado. No rompe nada relevante. Para cubrir también la enumeración vía parámetro de autor (?author=1), combinalo con una redirección de esas peticiones en functions.php.
Opción 2: requerir autenticación para todas las peticiones anónimas
Más amplia, más completa. Los usuarios no logueados no pueden acceder a ningún endpoint:
add_filter( 'rest_authentication_errors', function( $result ) {
if ( ! empty( $result ) ) {
return $result;
}
if ( ! is_user_logged_in() ) {
return new WP_Error(
'rest_not_logged_in',
'Solo los usuarios autenticados pueden acceder a la API REST.',
array( 'status' => 401 )
);
}
return $result;
} );
Ojo con esto: puede romper integraciones legítimas que usan la API sin autenticación, como temas que cargan datos de posts vía REST en el frontend anónimo. Antes de activarlo en producción, revisá qué peticiones hace tu sitio a /wp-json/ en el log de accesos del servidor.
Opción 3: deshabilitar la REST API completamente
Todavía hay guías que recomiendan esto. La realidad es que deshabilitar la REST API por completo rompe Gutenberg, el sistema de administración moderno de WordPress, y la mayoría de los plugins que usan bloques. Tiene sentido solo en instalaciones muy específicas que no usan ninguna funcionalidad moderna del core. Para casi todos los sitios, no es el camino.
Autenticación JWT y Application Passwords: cuál usar en cada caso
Si permitís acceso autenticado a la REST API (lo que casi siempre necesitás), el método de autenticación que elegís importa. WordPress tiene varias opciones con características bien distintas. Te puede servir nuestra cobertura de vulnerabilidades que afectan a WordPress.
Application Passwords (nativo desde WP 5.6)
Los generás desde el perfil del usuario en el admin de WordPress, y los usás en las peticiones con Basic Auth en el header: Authorization: Basic base64(usuario:app-password). Cada integración tiene su propio password, podés revocarlos individualmente sin afectar el login principal del usuario, y quedan registrados con nombre y fecha en el perfil. Si una integración se compromete, revocás ese password específico. No requieren plugins.
JWT Authentication
JSON Web Tokens son la opción cuando necesitás tokens con expiración automática o integraciones con apps móviles y SPAs que no quieren guardar credenciales de usuario. El flujo: el cliente se autentica con usuario y contraseña, recibe un JWT con expiración (típicamente 1 a 4 horas), y lo incluye en cada petición como Authorization: Bearer TOKEN. Cuando expira, usa un refresh token para obtener uno nuevo sin pedir credenciales de vuelta.
Para WordPress, el plugin más mantenido en 2026 es JWT Authentication for WP REST API. Requiere configurar una clave secreta en wp-config.php y modificar el .htaccess para que Apache pase el header de autorización a PHP (spoiler: ese último paso lo olvida casi todo el mundo y después no entienden por qué los tokens no funcionan).
La siguiente tabla compara los métodos principales:
| Método | Seguridad | Implementación | Expiración | Caso de uso ideal |
|---|---|---|---|---|
| Application Passwords | Alta | Nativa (sin plugin) | No expira (revocación manual) | Integraciones internas, scripts de servidor |
| JWT | Alta | Plugin externo | Sí (configurable, típico 1-4h) | Apps móviles, SPAs, integraciones externas |
| Nonce | Media | Nativa | 24 horas | Solo peticiones desde el navegador logueado |
| Basic Auth con credenciales | Baja | Sin plugin extra | No expira | Solo entornos de desarrollo local |
| OAuth 2.0 | Muy alta | Compleja (plugin + config) | Token de acceso + refresh | Aplicaciones públicas de terceros |

Rate limiting y bloqueo de fuerza bruta en la REST API
Un sitio con la REST API expuesta sin rate limiting puede recibir miles de peticiones por minuto a /wp-json/wp/v2/users sin que pase absolutamente nada. Los bots de escaneo, muchos de ellos distribuidos en redes de IPs, hacen reconocimiento continuo. No les importa si el endpoint devuelve 404 o 200 en la primera prueba.
Las opciones que realmente funcionan en 2026:
- Wordfence Security: tiene reglas de firewall para bloquear
/wp-json/*a IPs que superen un umbral de peticiones. La configuración está en el panel de reglas del WAF, y podés combinarlo con bloqueo por país o rangos de IP conocidos como maliciosos. - Rate limiting a nivel servidor: si tu hosting (como donweb.com) te da acceso a la configuración de Nginx o Apache, limitá peticiones por IP a nivel del servidor antes de que lleguen a PHP. Más eficiente porque no carga el stack completo de WordPress para cada petición descartada.
- Cloudflare WAF: si usás Cloudflare como proxy, sus reglas filtran tráfico de scanners conocidos antes de que toquen tu servidor. La versión gratuita incluye protección básica; las reglas avanzadas de WAF requieren el plan Pro.
¿Vale la pena implementar CAPTCHA en la REST API? Para endpoints de login, sí. Para endpoints de datos, no: los CAPTCHAs rompen las integraciones programáticas. La solución ahí es autenticación obligatoria, no CAPTCHA.
Validar y sanitizar las solicitudes a la REST API
CVE-2025-24000 en Post SMTP es el ejemplo más claro de lo que pasa cuando no validás bien. Arrancás el día con un plugin instalado, seguís la documentación oficial para conectar tu formulario de contacto, y sin saber estás exponiendo un endpoint que cualquier suscriptor puede usar para convertirse en administrador.
La regla más importante: el permission_callback de cualquier endpoint tiene que verificar capacidades explícitamente. No alcanza con verificar que el usuario está logueado: Esto se conecta con lo que analizamos en implementar un WAF para la REST API.
// Mal: cualquier usuario puede acceder
'permission_callback' => '__return_true',
// Bien: solo administradores
'permission_callback' => function() {
return current_user_can( 'manage_options' );
},
// Bien: autores y niveles superiores
'permission_callback' => function() {
return current_user_can( 'edit_posts' );
},
Según la documentación oficial de WordPress, cada endpoint personalizado debe tener un permission_callback que evalúe las capacidades del usuario en el contexto de la operación específica. WordPress rechaza el registro de endpoints sin este callback desde la versión 5.5.
Lo que también hay que cubrir:
- Validación de parámetros en el schema: usá el campo
argsal registrar el endpoint para definir el tipo, formato y función de sanitización de cada parámetro. WordPress tienesanitize_text_field(),absint()y callbacks de validación propios. - Nonces para peticiones desde el navegador: si tu JavaScript llama a la REST API desde el frontend de WordPress, incluí el nonce (
wp_rest) en cada petición. Protege contra CSRF sin afectar las integraciones externas. - Validación siempre en el servidor: lo que venga del cliente hay que validarlo de nuevo en el backend. Siempre. Sin excepción.
Monitoreo: detectar intentos maliciosos contra la API
Los logs de WordPress por defecto no registran accesos a la REST API. Después de implementar las restricciones, necesitás saber si alguien intenta saltárselas, porque sin monitoreo las restricciones son ciegas.
- Wordfence Activity Log: registra peticiones a
/wp-json/, intentos de autenticación fallidos y bloqueos por IP. La versión gratuita es suficiente para la mayoría de los sitios. - WPVulnerability (plugin): cruza tu lista de plugins activos contra la base de datos de CVEs conocidos. Si aparece un nuevo CVE que afecta un plugin que tenés instalado, te avisa. Es el tipo de monitoreo que ayudaría a detectar problemas como el de Post SMTP antes de que los exploten.
- Logs de acceso del servidor: buscá picos de peticiones GET a
/wp-json/wp/v2/users. Un bot de escaneo típico hace decenas de peticiones en pocos segundos desde la misma IP o desde un rango reducido de IPs.
Una alerta concreta que vale configurar: Wordfence permite notificarte cuando un endpoint específico supera X peticiones por hora desde la misma IP. No es configuración avanzada, y captura el grueso de los escaneos automatizados.
Qué está confirmado y qué todavía hay que verificar
- Confirmado:
/wp-json/wp/v2/usersexpone usuarios sin autenticación en cualquier instalación de WordPress 4.7 o superior que no haya modificado ese comportamiento. Podés verificarlo ahora mismo con una petición GET a tu sitio. - Confirmado: CVE-2025-24000 afectó versiones del plugin Post SMTP anteriores al parche. Si actualizaste, estás cubierto; si no, es urgente.
- Confirmado: Application Passwords es nativo desde WP 5.6 y no requiere ningún plugin adicional para funcionar.
- A verificar según tu entorno: la compatibilidad de JWT Authentication for WP REST API con tu versión exacta de WordPress y PHP. Revisá el repositorio del plugin antes de instalarlo en producción; los valores de expiración por defecto no siempre son los más seguros.
- A verificar con tu hosting: si tu plan permite configurar rate limiting a nivel de Nginx o Apache, o si dependés solo de plugins para eso. No todos los planes de alojamiento compartido dan ese nivel de acceso.
Errores comunes al proteger la REST API de WordPress
Deshabilitar la REST API completa y después no entender por qué el editor no guarda
Gutenberg usa la REST API para guardar posts, cargar media, buscar usuarios y renderizar bloques dinámicos. Si la deshabilitás sin excepciones, el admin empieza a fallar de formas poco obvias: peticiones que no responden, bloques que no cargan, guardados que silenciosamente no se ejecutan. La solución no es deshabilitar todo, es restringir lo que no tiene que ser público.
Usar ‘__return_true’ en permission_callback porque «solo el admin va a usar ese endpoint»
El frontend no es una barrera de seguridad. CVE-2025-24000 lo demostró sin dejar dudas: el plugin asumía que solo el admin iba a llamar ese endpoint porque solo el admin tenía la interfaz para hacerlo. Cualquier atacante con una cuenta básica mandó la petición directamente sin pasar por la UI y saltó el control. El permission_callback se valida en el servidor. Siempre.
Instalar JWT sin configurar la expiración ni los refresh tokens
JWT sin expiración bien configurada es casi tan problemático como no usar JWT. Un token sin fecha de vencimiento sirve para siempre si lo roban. La configuración mínima sensata: tokens de acceso con expiración corta (1 a 4 horas) más refresh tokens con expiración media (7 a 30 días). Los valores por defecto del plugin no siempre son los más seguros, así que revisalos antes de mandarlo a producción (sí, en serio, revisalos).
No auditar qué endpoints agrega cada plugin instalado
Cada plugin que usa la REST API agrega sus propios endpoints. La mayoría de los administradores nunca revisan qué hay disponible en su instalación. Con una petición GET a /wp-json/ obtenés el índice completo de todos los endpoints activos, incluidos los de plugins. Si ves algo que no reconocés o que no debería ser público, investigalo antes de que lo haga otra persona.
Si querés profundizar en esto, tenemos un artículo sobre Cómo proteger la REST API de WordPress en 2026.
Preguntas Frecuentes
¿Qué vulnerabilidades tiene la REST API de WordPress?
La vulnerabilidad más extendida es la exposición de usuarios vía /wp-json/wp/v2/users sin autenticación, que permite enumeración de cuentas para ataques de fuerza bruta. El segundo vector más común son los endpoints de plugins con permission_callback mal implementados, como CVE-2025-24000 en Post SMTP, donde la ausencia de verificación de capacidades permitía escalada de privilegios de suscriptor a administrador. Los exploits más serios combinan ambos vectores. Sobre eso hablamos en proteger tu API contra ataques DDoS.
¿Cómo bloqueo el acceso no autenticado a wp-json?
Usá el filtro rest_authentication_errors en functions.php para devolver un error 401 cuando is_user_logged_in() retorne false. Si no querés bloquear todo el API, enfocate en los endpoints más sensibles: eliminá /wp/v2/users con el filtro rest_endpoints. Para una protección sin modificar código, Wordfence tiene una opción en su firewall para bloquear /wp-json/* a usuarios anónimos con un par de clics.
¿Cuál es el mejor método de autenticación para la REST API de WordPress?
Para integraciones internas y scripts de servidor, Application Passwords (nativo desde WP 5.6) son la opción más práctica: no requieren plugins, se revocan por integración, y funcionan con Basic Auth en el header. Para apps móviles o SPAs donde los tokens deben expirar automáticamente, JWT es la mejor alternativa. Basic Auth con credenciales directas del usuario solo tiene sentido en entornos de desarrollo local, nunca en producción.
¿Cómo evito la enumeración de usuarios en WordPress?
Tres pasos: primero, eliminá el endpoint /wp/v2/users con el filtro rest_endpoints en functions.php. Segundo, bloqueá la enumeración vía parámetro de autor (?author=1) con una redirección condicional. Tercero, usá nombres de usuario que no sean predecibles: evitá «admin», «administrador» o cualquier variante del nombre de dominio. Wordfence activa la protección de enumeración de usuarios con una opción en su panel de configuración que cubre ambos vectores.
¿Qué plugins de seguridad protegen la REST API de WordPress?
Wordfence Security es el más completo: bloquea endpoints por IP, limita peticiones y tiene un firewall que filtra tráfico malicioso dirigido a /wp-json/. Solid Security (antes iThemes) tiene opciones específicas para la REST API. WPVulnerability monitorea CVEs activos en los plugins instalados y te avisa cuando aparece una vulnerabilidad que afecta tu instalación. Ningún plugin reemplaza implementar correctamente el permission_callback en tus propios endpoints, pero cubren bien los vectores externos.
Conclusión
La REST API de WordPress es una superficie de ataque que en 2026 los bots escanean de forma rutinaria y automatizada. Si tu sitio tiene el endpoint de usuarios abierto, cualquier herramienta de reconocimiento lo detecta en segundos. No es una amenaza teórica.
El mínimo que deberías implementar hoy: eliminá /wp/v2/users con el filtro rest_endpoints, revisá que ningún plugin activo use 'permission_callback' => '__return_true' en sus endpoints, y activá el log de accesos de Wordfence para saber qué tráfico llega a tu /wp-json/. Eso no lleva más de una hora y cierra el grueso de la exposición típica.
Si querés el nivel siguiente: implementá Application Passwords para tus integraciones, configurá rate limiting a nivel servidor, y hacé una petición GET a /wp-json/ para auditar todos los endpoints activos en tu instalación. Sabés lo que tenés expuesto antes de que lo sepa otra persona.
Fuentes
- WordPress Developer — Autenticación en la REST API (documentación oficial)
- Análisis técnico de CVE-2025-24000: escalada de suscriptor a administrador en Post SMTP
- WPThrill — Cómo proteger la REST API de WordPress del abuso
- Exposición de datos sensibles vía wp-json en WordPress
- Solid WP — Reporte de vulnerabilidades WordPress (agosto 2025)