Articles

WordPress Error Fix: «Call to undefined function get_header()»

♦ Publicado por Jeff Starr en PHP, Seguridad
11 de enero de 2019

Estoy viendo un gran aumento en los ataques de bots que apuntan a los archivos del tema directamente. Primero consiguen la URL de tu directorio de temas. Hay numerosas maneras para que un bot obtenga esta información. Por ejemplo, la mayoría de los temas incluyen activos como archivos CSS y JavaScript, y el enlace incluye la URL completa. Así que una vez que tienen la URL del tema, los bots malos harán peticiones directas de archivos de plantillas de temas conocidos, como index.php y header.php. Solicitar directamente los archivos de plantilla puede revelar posibles vulnerabilidades de seguridad, lo que aparentemente es un vector de ataque cada vez más popular. También provoca los errores «Call to undefined function get_header()» (y similares). Afortunadamente hay una solución fácil.

¿Es su sitio el objetivo?

Para saber si su sitio está siendo atacado con peticiones directas de archivos temáticos, puede comprobar los registros de acceso/error de su sitio. Aquí hay algunos ejemplos de mis propios registros que deberían ayudar a mostrar lo que hay que buscar:

Nota: En las siguientes entradas de registro, todas las rutas de archivos se cambian a URLs de ejemplo para evitar que Google rastree e informe de errores. En los archivos de registro reales, los errores contienen las rutas de los archivos, no las URL. P.D., es muy ridículo que Googlebot rastree la información de la ruta en texto plano, nada menos que dentro de las etiquetas <pre>.
2018-12-30 17:54:07 ErrorAH01071: Got error 'PHP message: PHP Fatal error: Uncaught Error: Call to undefined function get_header() in https://example.com/wp-content/themes/digwp/index.php:1Stack trace: #0 {main} thrown in https://example.com/wp-content/themes/digwp/index.php on line 1'2018-12-30 12:53:55 ErrorAH01071: Got error 'PHP message: PHP Fatal error: Uncaught Error: Call to undefined function get_header() in https://example.com/wp-content/themes/digwp/404.php:1Stack trace: #0 {main} thrown in https://example.com/wp-content/themes/digwp/404.php on line 1'2018-12-30 12:53:55 ErrorAH01071: Got error 'PHP message: PHP Fatal error: Uncaught Error: Call to undefined function esc_url() in https://example.com/wp-content/themes/digwp/header.php:8Stack trace: #0 {main} thrown in https://example.com/wp-content/themes/digwp/header.php on line 8'

Así que si su sitio es objeto de ataques de plantilla directa, verá MUCHOS de estos tipos de errores. En estos ejemplos, las peticiones son para index.php, 404.php y header.php. Según mis análisis, la mayoría de las solicitudes de plantillas son para estos tres archivos, pero también puede encontrarlos escaneando otros archivos conocidos de WordPress, como:

/archive.php/wp-includes/rss-functions.php ..various theme template files..various files in the WP Media Library

Básicamente, cualquier solicitud directa para un archivo del núcleo, tema o plugin de WordPress probablemente desencadenará un error, a menos que se tomen las medidas adecuadas de antemano. Por ejemplo, más adelante veremos una forma sencilla de detener el error de «función indefinida», lo que a su vez ayudará a conservar los valiosos recursos del servidor y a mejorar la seguridad general del sitio.

Entendiendo el error

¿Entonces qué pasa con los errores fatales de «llamada a función indefinida»? Suceden porque el núcleo de WordPress no se carga para los archivos de plantilla cargados directamente.

Por ejemplo, si solicitas header.php directamente, cualquier función del núcleo como esc_url() no está disponible porque el archivo se solicita fuera de WordPress.

¿Qué pasa si no haces nada? Bueno, puede que tu tema ya haya implementado una técnica similar, o tal vez no. ¿Cuál es el riesgo? Dependiendo de cómo esté codificado tu tema, puede ser posible que los malos actores ejecuten código fuera de contexto, lo que puede exponer potenciales vectores de ataque.

Cómo solucionarlo

La forma más fácil de prevenir este tipo de error es simplemente salir del script si WordPress no está disponible. Esta es una antigua pero efectiva técnica de PHP utilizada para prevenir el acceso directo a archivos:

<?php if (!defined('ABSPATH')) exit; ?>

Simplemente dice: Si la constante ABSPATH no está definida, entonces salga del script. Esto funciona porque ABSPATH sólo se define cuando se carga WordPress. Así que cuando un bot malo llega y comienza a solicitar las plantillas de su tema, simplemente obtendrá una página en blanco (respuesta vacía) del servidor.

Es posible que haya visto un código similar durante sus viajes de WordPress. Prevenir el acceso directo a los scripts es una parte importante de la seguridad de PHP. No quieres que los atacantes/robots ejecuten scripts fuera de contexto, cuando no están autorizados, etc.

Ejemplo

Para implementar esta técnica, abre cualquier archivo de tema que sea objetivo, e incluye la línea en la parte superior del archivo. Por ejemplo, muchas plantillas de temas incluyen el encabezado antes de cualquier otro código, se ve así:

<?php get_header(); ?>

Después de añadir el fragmento de «no acceso directo», tendrás algo como:

<?php if (!defined('ABSPATH')) exit;get_header(); ?>

Como sea que decidas formatear el código está bien, el punto es incluir la línea ABSPATH antes de que cualquier otra función sea llamada.

Pro Tip: ¿Quieres detener más bots malos? Echa un vistazo a mi plugin gratuito para WordPress, Blackhole for Bad Bots, disponible en el directorio de plugins de WP.

Bonus

Para ir más allá, puedes proteger la información de los archivos sensibles deshabilitando las vistas de directorio. Por ejemplo, si visitas el directorio padre de tu tema en un navegador, ¿qué ves? Si las vistas de directorio están habilitadas, obtendrás una lista enlazada de todos los archivos. No es bueno. Lo que debería ver es una pantalla blanca en blanco o alguna otra respuesta del servidor. Ya sabe, para ayudar a mantener la información de sus archivos a salvo y segura.

Hay numerosas formas de desactivar las vistas de directorio. La forma de WordPress es crear un nuevo archivo index.php (vacío) en cualquier directorio que desee proteger.

¡Importante! Sólo cree un nuevo archivo index.php si NO existe ya uno en el directorio. Es decir, no sobrescribas ningún archivo de índice existente.

Después, en index.php, añade el siguiente código:

<?php // Silence is golden.

El núcleo de WordPress utiliza esta técnica en varios directorios. Al deshabilitar las vistas de directorios abiertos, evitamos que los atacantes obtengan información sobre qué archivos existen en el servidor. Así que beneficia a la seguridad y es una práctica recomendada para todos los directorios públicos, a menos que lo tengas cubierto con .htaccess, o quizás tengas razones para hacer lo contrario y dejar las vistas habilitadas para un directorio específico.

Pensamientos finales

Las sencillas técnicas descritas en este artículo son medidas de seguridad probadas que evitarán la ejecución de código inseguro y evitarán que los errores llenen tus registros. Eso significa un mejor rendimiento y seguridad para su sitio. Incluso si no estás experimentando el tipo de errores descritos en este artículo, proteger tus archivos de temas y plugins del acceso directo es bueno para la seguridad.

Jeff Starr

Acerca del autor
Jeff Starr = Diseñador. Desarrollador. Productor. Escritor. Editor. Etc.