Security Through Obscurity — How To Reduce WordPress Attacks

Documentation

Need to send invoices?
Check out my new WordPress plugin HDInvoice
Limited time launch sale

Cute WordPress robot inside an open vault

I have a question, say we get into the cage, and through the security doors there and down the elevator we can’t move, and past the guards with the guns, and into the vault we can’t open…

Something that’s always bothered me in the security community is the dogmatic hatred for any kind of security through obfuscation. It has become a golden and unbending rule, where even mentioning obfuscation makes some people completely dismiss your opinion. But are they right?

What Is Security Through Obfuscation?

Let’s start by answering the question, “What is Obfuscation?”. The answer is: doing anything to obscure your code — to attempt to hide information. Security through obfuscation comes in many forms, but the most common forms can be distilled to hiding your code to make it harder for a hacker to read or understand.

In this article, I’m going to argue that there are, in fact, excellent reasons to use obfuscation in certain circumstances, but before I do, I need to get something out of the way that should be obvious. Obfuscation is just one extra layer. It is not and should never be the only thing you do. I liken it to preventative medical care. Having a cure is fantastic, but I also want to reduce the chances of needing the cure to begin with.

Making your code hard to read

cute robot struggling to read

The idea here is that instead of using best coding practices and naming your functions and variables something natural such as sum_two_numbers(), you instead name it something obscure such as 9sdfmkls(). You can think of this as really bad encryption.

The idea is that for the first example of sum_two_numbers you don’t even need to be a programmer to know what that function does. It sums two numbers! The second function name 9sdfmkls provides no contextual information, thus is harder for a malicious user to comb through your code to find vulnerabilities.

Extreme examples are to obfuscate variables and even use obscure coding patterns. Anything to make your code as hard to understand as possible.

The reason that this type of “security” is discouraged is that:

  • A) It won’t actually prevent a dedicated hacker (a good programmer can still look at the code and figure out what it does). A dedicated hacker will just be inconvenienced, not stopped
  • B) It makes development significantly harder for yourself and your team
  • C) Validation and security audits become far harder than necessary (nothing scarier than seeing a BASE64 string randomly in code)

Masquerading as something else

Robot pretending not to be a robot

Code masking can come in two flavours. Masking the code, and masking the footprint. Both involve pretending to be something else. Let’s start with the former.

Masking Code

Instead of naming a function something random, name it something specific instead. For example, if I have a function called validate_license_key(), I could instead name it something boring like do_my_taxes().

The idea here is that a hacker looking at your code, will begin by skipping the code and reading function names. If they are looking for a way to bypass license validation, they are sure to look for any functions with the word license in it. By naming the function something mundane, the function is less likely to be found.

The reason that this type of “security” is discouraged is that:

  • A) Like with the basic code obfuscation, a dedicated hacker will just be inconvenienced by this, not stopped
  • B) Also makes things harder for you. Will you remember that you renamed those functions in the future?

Masking Footprint

Every website has a footprint, a set of “signals” that lets a hacker know valuable information. For example, this website is a WordPress based website. And All WordPress based sites have their theme and plugin folders inside a wp-content folder. This means that looking at the source code, you can look for any reference to that folder and know that the site is powered by WordPress.

Footprint masking is when you change those “signals” to hide the fact that you are using WordPress (or any other system with a known footprint).

The reason that this type of “security” is discouraged is that:

  • A) Say it with me: “a dedicated hacker will just be inconvenienced by this, not stopped”
  • B) ??

When to Use Obfuscation as Security

So as we’ve seen above, obfuscation does not prevent a knowledgeable and dedicated hacker from doing what they do. But what about hackers that are NOT knowledgeable or dedicated? What about all the bots and scripts?

Types of Obfuscation to avoid:

  • Do not randomly jumble your function or variable names. One could argue that you are increasing security (a hacker might simply decide it’s not worth the extra work), but you are almost certainly hurting yourself more.

Types of Obfuscation that are OK:

  • Masking certain functions (such as renaming an obvious license validator to something else)
  • Footprint masking

Masking the WordPress Footprint

robot leaving footprints in the sand

For WordPress in particular, masking your footprint is extremely advantageous. Sure, it won’t slow down a pro, but it WILL significantly reduce the total number of attempts, and stop most automated scripts in their tracks.

I have been very open about the fact this is very site is built on WordPress, but I’m not worried since my footprint is so well obscured that the knowledge of what CMS I use is no longer an advantage. To be clear, this is not a call to action for any hackers out there, just a point that by obscuring the site footprint, it makes things harder to hack.

With the knowledge that your site is WordPress, a hacker can

  • Access your login portal and attempt a dictionary or brute force login attack (all WordPress login pages are domain.com/wp-login.php
  • Look for any known vulnerabilities in older versions of WordPress
  • Look at your source code to see any active plugins. Look for any known vulnerabilities in those
  • Attempt to access files that may be on your server if popular plugins or themes with known vulnerabilities exist
  • Automate things like comment or user registration spam

Almost all of the above can be accomplished by freely accessible scripts that automate all of the above. It is because of this that the best thing you can do to significantly reduce the number of attempted attacks on your site, is to simply hide (or obfuscate) the fact that you are using WordPress to begin with.

But what if a hacker already knows that you are using WordPress? Obfuscation to the rescue yet again.

Real WordPress Examples

I changed the WordPress admin login link for this site, making it next to impossible for a hacker to attempt brute force logins since they no longer know where the admin login page is. If a hacker gains access to the login portal, I obfuscate the login error messages. No more does WordPress return messages like “username not found”, as that tells the hacker that they need to try a different username. Now it either silently fails or succeeds.

However, remember at the start when I said that obfuscation is just another security layer? The idea is to use obfuscation to reduce the amount of attempts. But once an attempt is ready to be made, you still need more traditional security measures. I make it as hard as possible for a hacker to even find a way to attempt logins, but if they do find one, then a simple brute force protection is there to save me. Too many failed attempts from the same user, and that user is banned. Any attempt from blocked usernames (such as “admin”, “hdplugins”, etc) is insta banned.

Automated scripts cannot look for vulnerabilities in plugins if my plugins are housed in a different location than the traditional wp-content folder.

AND OF COURSE, the best WordPress security you can have is to always stay updated with the latest versions of WordPress, themes, and plugins.

How to Mask Your WordPress Site

So I’ve gone over how masking your footprint can significantly reduce the amount of hack attempts on your site, and I’ve gone over how there is really no downside to this. Now that you are convinced, what can you do?

Remove WordPress Generators

Adding the following code to your theme’s functions.php file (BACK UP THE FILE FIRST) will stop your site from leaking information.

add_filter('the_generator', '__return_false', 99, 1);
remove_action('wp_head', 'wp_generator');
remove_action('wp_head', 'rsd_link');
remove_action('wp_head', 'wlwmanifest_link');

You can of course leave rsd_link or wlwmanifest_link if you need the Really Simple Discovery or WLW manifest respectively (note: WLW has been deprecated in WordPress 6.3.0).

Change and Protect WordPress Login Page

Adding the following code to your theme’s functions.php file (BACK UP THE FILE FIRST) will change the login URL for your site, forcing the addition of a secret URL parameter.

function hdplugins_login_security()
{
	$token = 'secret-login=super-secret-login-token';
	if (strpos($_SERVER['QUERY_STRING'], $token) !== false) {
		// we have a match
	} else {
		// redirect to homepage
		header('Location: https://' . $_SERVER['SERVER_NAME'] . '/');
	}
}
add_action('login_head', 'hdplugins_login_security');

You will need to update $token with a token string that is used as a sort of embedded username and password.

Once done, when the login page loads, we check to see if the path and token are present. If they are not, we automatically redirect to the homepage. A new example login URL might look something like domain.com/wp-login.php?secret-login=super-secret-login-token

You can also go a step further by editing your .htaccess file to add a rewrite rule to make things look more human natural. Something like RewriteRule ^([_0-9a-zA-Z-]+/)?secret-login(.*) /wp-login.php$2?secret-login=super-secret-login-token [QSA,L]

The above would make it so that going to domain.com/secret-login automatically redirects to the full URL of domain.com/wp-login.php?secret-login=super-secret-login-token

Change wp-content folder name and location

Adding the following code to your theme’s functions.php file (BACK UP THE FILE FIRST) will tell WordPress where your wp-content folder is located, and what its name is. I used “assets” here as the name, but you can of course choose any name you want.

function hdplugins_change_wp_content_folder()
{
    define('WP_CONTENT_FOLDERNAME', 'assets');
    define('WP_CONTENT_DIR', ABSPATH . WP_CONTENT_FOLDERNAME);
    define('WP_CONTENT_URL', 'https://domain.com/' . WP_CONTENT_FOLDERNAME);
}
add_action('after_setup_theme', 'hdplugins_change_wp_content_folder');

The problem with the above is that some poorly coded themes or plugins have the path to wp-content hardcoded instead of use native WordPress functions or definitions to get the path. To help with cases like these, you may want to also add a rewrite rule to your .htaccess file, like we did for the login page.

Something like: RewriteRule ^([_0-9a-zA-Z-]+/)?assets/(.*) /wp-content/$2 [QSA,L]

Liked this article? Sharing is caring

Leave a reply

👍 😆 😠 😢 😍
Reply