La REST API de WordPress es una potente interfaz que permite a aplicaciones externas, temas y plugins interactuar con los datos de tu sitio. De serie, WordPress expone una serie de endpoints publicos que cualquiera puede consultar sin autenticacion. Aunque esto resulta util para configuraciones headless e integraciones de terceros, tambien abre la puerta a fugas de informacion, especialmente en torno a los datos de usuario.
Que expone la REST API de WordPress por defecto
Cuando la REST API es totalmente accesible, varios endpoints devuelven datos que la mayoria de propietarios de sitios preferiria mantener privados. Los mas abusados son:
/wp-json/wp/v2/users: devuelve una lista de todos los usuarios que han publicado al menos una entrada, incluido su nombre de usuario, nombre publico, ID de usuario, URL del avatar y enlace al archivo del autor./wp-json/wp/v2/users/1: devuelve informacion detallada sobre un usuario concreto por ID. Los atacantes suelen empezar por el ID 1 porque normalmente es la cuenta de administrador./wp-json/wp/v2/posts: lista las entradas publicadas junto con la informacion del autor./wp-json/wp/v2/pages: lista todas las paginas publicadas, lo que puede revelar la estructura interna del sitio./wp-json/: el propio endpoint raiz revela todas las rutas registradas, dando a los atacantes un mapa de las capacidades de tu sitio y los plugins instalados.
El endpoint /wp/v2/users es la mayor preocupacion para la mayoria de sitios. Los atacantes lo usan para enumeracion de usuarios, recopilando nombres de usuario validos que luego utilizan en ataques de fuerza bruta contra el login. Aunque uses contrasenas robustas, exponer los nombres de usuario elimina una capa de defensa.
Por que no deberias deshabilitar por completo la REST API
Puede resultar tentador bloquear la REST API por completo, pero hacerlo rompera varias funciones esenciales de WordPress. El editor de bloques Gutenberg depende mucho de las llamadas a la REST API para cargar datos de bloques, guardar contenido y gestionar medios. Si deshabilitas la API por completo, Gutenberg no cargara y no podras editar entradas ni paginas.
Mas alla de Gutenberg, muchos plugins populares dependen de la REST API para su funcionalidad:
- Contact Form 7: usa endpoints de la REST API para gestionar el envio de formularios en sus versiones mas recientes.
- WooCommerce: depende de rutas de la REST API para operaciones del carrito, procesado del checkout y la interfaz de administracion.
- Yoast SEO: usa llamadas a la REST API para su metabox y las funciones de analisis de contenido en el editor.
- Jetpack: requiere acceso a la REST API para su conexion con los servicios de WordPress.com.
El enfoque correcto es la restriccion selectiva: bloquear el acceso publico a los endpoints sensibles manteniendo la API disponible para usuarios autenticados y para el area de administracion de WordPress.
Restringir la REST API solo a usuarios autenticados
El metodo mas eficaz es exigir autenticacion en todas las peticiones a la REST API. Anade este codigo al archivo functions.php de tu tema o, mejor aun, a un plugin personalizado especifico del sitio:
add_filter('rest_authentication_errors', function($result) {
// Si una comprobacion de autenticacion previa ya paso o fallo, respetala
if (true === $result || is_wp_error($result)) {
return $result;
}
// Bloquear peticiones no autenticadas
if (!is_user_logged_in()) {
return new WP_Error(
'rest_not_logged_in',
'You are not currently logged in.',
array('status' => 401)
);
}
return $result;
});Este enfoque bloquea todo el acceso a la REST API para los visitantes que no estan autenticados. Gutenberg, WooCommerce y otros plugins siguen funcionando con normalidad porque sus peticiones provienen de sesiones de admin autenticadas. Los visitantes que intenten acceder a /wp-json/wp/v2/users recibiran un error 401 en lugar de los datos de usuario.
Una cosa a tener en cuenta: si tu sitio usa un frontend headless o tienes una funcionalidad publica que obtiene datos via REST API (por ejemplo, una busqueda en directo basada en la REST API), este metodo la rompera. En esos casos, el enfoque selectivo de abajo encaja mejor.
Deshabilitar selectivamente solo el endpoint de usuarios
Si quieres mantener la REST API accesible para uso publico pero evitar especificamente la enumeracion de usuarios, puedes eliminar solo los endpoints de usuarios:
add_filter('rest_endpoints', function($endpoints) {
// Eliminar el endpoint de listado de usuarios
if (isset($endpoints['/wp/v2/users'])) {
unset($endpoints['/wp/v2/users']);
}
// Eliminar el endpoint de usuario individual
if (isset($endpoints['/wp/v2/users/(?P<id>[\d]+)'])) {
unset($endpoints['/wp/v2/users/(?P[\d]+)']);
}
return $endpoints;
}); Esto deja todas las demas rutas de la REST API funcionales mientras bloquea especificamente el vector de enumeracion de usuarios. Es un buen compromiso para sitios que necesitan acceso publico a la REST API para busquedas, consultas de contenido u otras funciones, pero quieren proteger los datos de usuario.
Eliminar el enlace de descubrimiento de la REST API del HTML
WordPress imprime una etiqueta <link rel="https://api.w.org/"> en el head del HTML y una cabecera Link en las respuestas HTTP. Indican a las herramientas automatizadas donde encontrar la REST API. Aunque eliminar estas etiquetas no deshabilita realmente la API (los endpoints siguen respondiendo en sus URLs habituales), reduce su descubribilidad:
// Eliminar el enlace a la REST API del head HTML
remove_action('wp_head', 'rest_output_link_wp_head');
// Eliminar el enlace a la REST API de las respuestas XML-RPC
remove_action('xmlrpc_rpc_methods', 'rest_output_link_wp_head');
// Eliminar la cabecera Link de las respuestas HTTP
remove_action('template_redirect', 'rest_output_link_header', 11);Este paso es mejor usarlo junto con uno de los metodos de restriccion anteriores, no por si solo. Eliminar la etiqueta de enlace sin restringir los endpoints reales es seguridad por oscuridad, lo cual proporciona muy poca proteccion real.
Usar un plugin para gestionar el acceso a la REST API
Si prefieres no anadir codigo personalizado, varios plugins ofrecen una interfaz para gestionar el acceso a la REST API:
- Disable WP REST API: bloquea todo el acceso a la REST API para peticiones no autenticadas con un simple interruptor. No requiere mas configuracion que activar el plugin.
- WP REST API Controller: te da un control granular sobre que endpoints son publicos y cuales requieren autenticacion, permitiendote permitir algunas rutas mientras bloqueas otras.
El enfoque por plugin es mas sencillo de gestionar pero anade una dependencia. Si el plugin se desactiva o se elimina durante una actualizacion, tu REST API volvera a ser totalmente publica. El enfoque por codigo es mas fiable para una proteccion a largo plazo.
Probar tus restricciones a la REST API
Despues de aplicar tus cambios, verifica que funcionan correctamente. Abre una ventana de incognito en el navegador (para no estar autenticado) e intenta acceder a estas URLs en tu sitio:
https://yoursite.com/wp-json/wp/v2/usershttps://yoursite.com/wp-json/wp/v2/users/1https://yoursite.com/wp-json/
Si tu restriccion funciona, deberian devolver un error 401 o una respuesta vacia en lugar de datos de usuario. A continuacion, inicia sesion en el admin de WordPress y confirma que el editor Gutenberg, tus formularios y cualquier funcionalidad de WooCommerce siguen funcionando como esperas.
Verifica con InspectWP
Tras implementar tus cambios, ejecuta un nuevo escaneo de InspectWP en tu sitio. La seccion de seguridad de tu informe mostrara si la REST API es accesible publicamente y si el endpoint de usuarios devuelve datos. Si la restriccion funciona correctamente, InspectWP indicara que la API no es accesible o que el endpoint de usuarios esta restringido.