Ir al contenido

La API REST de WordPress muestra públicamente los plugins que usa

Aviso Todo el dominio Seguridad

Instrucciones generales. Abre este artículo desde tu informe de PageCheck para verlo con los plugins que nombra el índice de tu sitio y cuáles de ellos usan los navegadores de tus visitantes.

Qué es

La API REST de WordPress permite a los scripts leer y modificar el sitio a través de direcciones bajo /wp-json/: la usan el editor de bloques, las aplicaciones y muchos plugins. Su índice enumera cada «espacio de nombres» que registra el sitio —un grupo de direcciones—, y WordPress en sí solo posee unos pocos. Cualquier otro espacio de nombres pertenece a un plugin.

Qué falla

El índice responde a cualquiera que lo pida, y sus espacios de nombres nombran los plugins del sitio. Con esa lista, un atacante no adivina: a continuación lee la versión de cada plugin en sus propios archivos y la coteja con las listas públicas de fallos de seguridad conocidos. La página en sí solo muestra los plugins que cargan archivos en ella; el índice también nombra los que no lo hacen: plugins de SEO, formularios, copias de seguridad, seguridad y administración.

Cómo arreglarlo

La API se mantiene; solo su mapa y las partes que los visitantes nunca usan se ocultan a quien no ha iniciado sesión como personal del sitio. Las direcciones ocultas deben responder «no encontrado» (404), no «no autorizado» (401): un 401 sigue confirmando que el plugin está ahí.

1. Averigua qué espacios de nombres usan tus páginas. Abre el sitio en una ventana de navegación privada, abre las herramientas para desarrolladores del navegador (F12) → Red, filtra por wp-json y usa el sitio como un visitante: envía un formulario, añade algo al carrito, abre el pago, busca. Cada petición que aparezca nombra un espacio de nombres que debes conservar.

Los más habituales:

  • Contact Form 7 envía sus formularios a través de la API REST.
  • El carrito, el pago y el minicarrito basados en bloques de WooCommerce leen la Store API (wc/store).
  • Los contadores de visitas como WP Statistics y WordPress Popular Posts registran las visitas a través de ella.
  • Los plugins de comunidad, donaciones y consentimiento (BuddyPress, GiveWP, Complianz) la usan en las páginas.

2. Oculta el resto a los visitantes. Guarda esto como wp-content/mu-plugins/hide-rest-map.php (puede que haya que crear la carpeta; los archivos que hay ahí siempre están activos). Pon en la lista los espacios de nombres del paso 1: cada uno se conserva con todo lo que hay debajo.

wp-content/mu-plugins/hide-rest-map.php

<?php
/* Hide the REST API's map from visitors who are not logged in. */
add_filter( 'rest_endpoints', function ( $endpoints ) {
	if ( current_user_can( 'edit_posts' ) ) {
		return $endpoints; // staff keep everything
	}
	// Namespaces your pages call. Everything else answers 404 to visitors.
	$keep = array( 'wc/store', 'contact-form-7/v1' );
	foreach ( array_keys( $endpoints ) as $route ) {
		$kept = false;
		foreach ( $keep as $namespace ) {
			if ( 0 === strpos( $route, '/' . $namespace . '/' ) ) {
				$kept = true;
				break;
			}
		}
		if ( ! $kept ) {
			unset( $endpoints[ $route ] );
		}
	}
	return $endpoints;
}, 5 );

// No pointer to the API in the pages' head and headers.
remove_action( 'wp_head', 'rest_output_link_wp_head' );
remove_action( 'template_redirect', 'rest_output_link_header', 11 );

Quien puede editar contenido conserva toda la API, así que el editor de bloques, las pantallas de administración de WooCommerce y de otros plugins y Salud del sitio funcionan como antes. Los plugins de seguridad ofrecen lo mismo como ajuste («Desactivar la API REST para visitantes» o similar); asegúrate de que admite una lista de excepciones y responde 404, no 401.

No recomendado: el fragmento habitual que niega toda la API a los visitantes mediante rest_authentication_errors. Rompe los formularios y el carrito de bloques, y sigue respondiendo 401 en todas las direcciones, lo que confirma que cada plugin existe.

3. Compruébalo. Abre https://example.com/wp-json/ en una ventana privada: debe responder «no encontrado» (404, rest_no_route). Después envía un formulario y usa el carrito o lo que hagan tus páginas, y vuelve a ejecutar esta comprobación.

Hide my WordPress site's REST API map from visitors who are not logged in, without breaking the features that use the API. https://example.com/wp-json/ currently answers anyone and lists every namespace, i.e. every plugin.

Do this:
1. Find which namespaces the public pages call (forms, cart, checkout, view counters): grep the theme and plugins for wp-json / rest_url / apiFetch, and check the browser's network tab as a visitor.
2. Add a must-use plugin (wp-content/mu-plugins/hide-rest-map.php) with a rest_endpoints filter: when the user cannot edit_posts, unset every route except those under the kept namespaces (match '/<namespace>/' as a prefix of the route), so the index '/', every namespace index and the other routes answer 404 rest_no_route, never 401. Also remove_action wp_head rest_output_link_wp_head and template_redirect rest_output_link_header (priority 11).
3. Do not use rest_authentication_errors to refuse the whole API: it breaks visitor-facing features and answers 401, which confirms the plugins.
4. Verify: /wp-json/ and /wp-json/wp/v2 answer 404 for a visitor and still work for an editor; the kept features work in a private window; no <link rel="https://api.w.org/"> and no Link header on the pages.
Tell me exactly which file you added and which namespaces you kept.

Revisa tu sitio para ver si tiene este problema. Revisar un sitio web