WordPress Error Fix: “Call to undefined function get_header()”
I’m seeing a big increase in bot attacks targeting theme files directly. First they get the URL to your theme directory. There are numerous ways for a bot to get this information. For example most themes include assets like CSS and JavaScript files, and the link includes the full URL. So then once they have the theme URL, bad bots will make direct requests for well-known theme template files, like index.php
and header.php
. Requesting template files directly may reveal possible security vulnerabilities, which apparently is an increasingly popular attack vector. It also triggers the “Call to undefined function get_header()” (and similar) errors. Fortunately there is an easy fix.
Is your site targeted?
To find out if your site is getting hit with direct requests for theme files, you can check your site’s access/error logs. Here are some examples from my own logs that should help show what to look for:
<pre>
tags no less.2018-12-30 17:54:07 Error
AH01071: 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:1
Stack trace: #0 {main} thrown in https://example.com/wp-content/themes/digwp/index.php on line 1'
2018-12-30 12:53:55 Error
AH01071: 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:1
Stack trace: #0 {main} thrown in https://example.com/wp-content/themes/digwp/404.php on line 1'
2018-12-30 12:53:55 Error
AH01071: 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:8
Stack trace: #0 {main} thrown in https://example.com/wp-content/themes/digwp/header.php on line 8'
So if your site is targeted with direct-template attacks, you’ll see LOTS of these types of errors. In these examples, the requests are for index.php
, 404.php
, and header.php
. From my analyses, most of the template requests are for these three files, but you may also find them scanning for other well-known WordPress files, such as:
/archive.php
/wp-includes/rss-functions.php
..various theme template files
..various files in the WP Media Library
Basically, any direct request for a WordPress core, theme, or plugin file most likely will trigger an error, unless proper measures are taken beforehand. For example, later we’ll look at an easy way to stop the “undefined function” error, which in turn will help conserve precious server resources and improve overall site security.
Understanding the error
So what’s with the “call to undefined function” fatal errors? They happen because WordPress core is not loaded for directly loaded template files.
For example, if you request header.php
directly, any core functions such as esc_url()
are not available because the file is requested outside of WordPress.
What happens if you do nothing? Well, your theme may already have implemented a similar technique, or maybe not. What’s the risk? Depending on how your theme is coded, it may be possible for bad actors to execute code out of context, which may expose potential attack vectors.
How to fix
The easiest way to prevent this type of error is to simply exit the script if WordPress is not available. This is an ancient yet effective PHP technique used to prevent direct file access:
<?php if (!defined('ABSPATH')) exit; ?>
It simply says: If the ABSPATH
constant is not defined, then exit the script. This works because ABSPATH
is only defined when WordPress is loaded. So when a bad bot comes along and starts requesting your theme templates, it will simply get a blank page (empty response) from the server.
You may have seen similar code during your WordPress travels. Preventing direct script access is an important part of PHP security. You don’t want attackers/bots running scripts out of context, when not authorized, and so forth.
Example
To implement this technique, open any theme files that are targeted, and include the line at the top of the file. For example, many theme templates include the header before any other code, looks like this:
<?php get_header(); ?>
After adding the “no direct access” snippet, you’ll have something like:
<?php
if (!defined('ABSPATH')) exit;
get_header();
?>
However you decide to format the code is fine, the point is to include the ABSPATH line before any other functions are called.
Bonus
To go further, you can protect sensitive file information by disabling directory views. For example, if you visit your theme parent directory in a browser, what do you see? If directory views are enabled, you’ll get a linked list of all the files. Not good. What you should see is either a blank white screen or some other server response. You know, to help keep your file information safe and secure.
There are numerous ways to disable directory views. The WordPress way is to create a new (empty) index.php
file in whichever directory you want to protect.
index.php
file if one does NOT already exist in the directory. That is, don’t overwrite any existing index files.Then in index.php
, add the following code:
<?php
// Silence is golden.
WordPress core uses this technique in various directories. By disabling open directory views, we prevent attackers from obtaining information about which files exist on the server. So it benefits security and is recommended practice for all public directories, unless you’ve got it covered with .htaccess, or maybe have reason to do otherwise and leave views enabled for a specific directory.
Closing thoughts
The simple techniques described in this article are proven security measures that will prevent unsafe code execution and stop errors from filling up your logs. That means better performance and security for your site. Even if you’re not experiencing the type of errors described in this article, protecting your theme and plugin files from direct access is good for security.