scattering clouds

The dangers of blindly copying and pasting code.

I became interested in learning about how WordPress works under the hood, and decided to study some WordPress code snippets to see what I can garner from someone else’s work. It is always good to learn from my betters!

One of the code snippets I happened across looked to be extremely useful: It is meant to prevent repeated failed login attempts into a WordPress site.

The code is supposed to protect your website from a brute force attack, where hackers will attempt to log in with as many password variations as possible, hoping to gain access to your WordPress website by guessing your credentials correctly.

The code snippet in question.

My search on Google for “limit wordpress login with code” returned a very specific piece of PHP code. One that had been shamelessly copied and pasted over and over again across a number of websites on the first page of Google.

And the code looks a little something like this:

function check_attempted_login($user, $username, $password) {
    if (get_transient("attempted_login")) {
        $datas = get_transient("attempted_login");
        if ($datas["tried"] >= 3) {
            $until = get_option("_transient_timeout_" . "attempted_login");
            $time = time_to_go($until);
            return new WP_Error( 'too_many_tried',  sprintf( __( '<strong>ERROR</strong>: You have reached authentication limit, you will be able to try again in %1$s.' ) , $time ) );
        }
    }
    return $user;
}

add_filter("authenticate", "check_attempted_login", 30, 3);

function login_failed($username) {
	$timeout = 300;
    if (get_transient("attempted_login")) {
        $datas = get_transient("attempted_login");
        $datas["tried"]++;
        if ($datas["tried"] <= 3) {
            set_transient("attempted_login", $datas, $timeout);
        }
    } else {
        $datas = [
            "tried" => 1,
        ];
        set_transient("attempted_login", $datas, $timeout);
    }
}

add_action("wp_login_failed", "login_failed", 10, 1);

function time_to_go($timestamp) {
    // converting the mysql timestamp to php time
    $periods = ["second", "minute", "hour", "day", "week", "month", "year"];
    $lengths = ["60", "60", "24", "7", "4.35", "12"];
    $current_timestamp = time();
    $difference = abs($current_timestamp - $timestamp);
    for (
        $i = 0;
        $difference >= $lengths[$i] && $i < count($lengths) - 1;
        $i++
    ) {
        $difference /= $lengths[$i];
    }
    $difference = round($difference);
    if (isset($difference)) {
        if ($difference != 1) {
            $periods[$i] .= "s";
        }
        $output = "$difference $periods[$i]";
        return $output;
    }
}

Author’s note: I too have shamelessly copied the above code snippet from phppot. But at least I also have the common decency to fix some formatting and indentation issues in their code to make it more readable on desktop.

The code snippet itself is fairly easy to use: All you need to do is copy the code into your WordPress functions.php file, or apply the code to some kind of code snippets plugin for WordPress, and voilà! You can greatly reduce the chances of malicious hackers brute-forcing their way into your WordPress website.

The issue I have with this, is that none of the copy-pasters bothered to truly explain what the code actually does, especially since there is a glaring issue hidden within its implementation. A glaring issue anybody would have noticed if they bothered to try out the code themselves on an actual WordPress website.

I would venture to guess that some of those knuckleheads didn’t even bother to test and verify whether their code actually works, because at least TWO of those copy-pasting websites failed to provide a proper, executable copy of the code.

You guys had ONE JOB, Melinda Bartley from malcare.com and the FixRunner Team from fixrunner.com. Find a working code snippet, copy, and then paste.

I don’t know who copied whose work here, since the code in both of your articles are formatted in pretty much the same exact manner, right down to the missing line break and an erroneous lack of closing curly brackets at the very end of your code.

Either way, I have taken the liberty to immortalize both of your silly mistakes on the Wayback Machine / Internet Archive for the rest of the world to see:

But I digress.

The issue with the aforementioned code.

When I tried out the code snippet on a test WordPress website, it did not behave the way I expected. Upon reading through the code, I realized the snippet only records a cumulative number of failed login attempts in the past 300 seconds.

Once the number of failed login attempts reaches or exceeds the number 3, the code would simply return an error that disables ANY further login attempts. This error will persist until another 300 seconds had elapsed since the last failed login.

I did some digging, and I believe the code snippet above is a modification of the class-based solution posted by Etienne Tremel on Coderwall. At least, that was the earliest variation I could find based on a StackOverflow question asked in 2014.

Unlike the shameless copy-pasters who dominated the first page of Google, Etienne actually had something useful to say about his own code.

And that something is quite important: The code is designed to lock down your system if someone attempted and failed to login after 3 consecutive tries.

Anyone who fails to login thrice will cause your website to lock down for however long you set the timeout to be. And in Etienne’s implementation, the timeout is set to 1800 seconds or 30 minutes! During the lockdown, nobody will be able to log in until the timeout ends (or until the code snippet gets disabled or removed).

This includes even the website owner / administrator!

So if your website is targeted by a malicious user, they can create an automated script to trigger this timeout on repeat, effectively preventing everyone else from logging into your website. That’s a pretty massive oversight if you ask me.

An oversight that was only briefly mentioned in passing by the original author, and was completely overlooked by everybody else who copied and modified, or copied a modification of the original code.

Granted, this timeout issue isn’t much of a problem when you are the only person with login credentials to your own WordPress website.

But if you have multiple users logging into your WordPress site, good luck removing the code snippet when you get locked out of your WordPress admin dashboard.

You would either have to dive in and edit your functions.php file, or disable / delete whatever code snippet plugin you might be using. This is usually ill-advised because you can easily create a whole host of other problems if you’re not careful.

Not everything can be resolved by copying in a random piece of code that claims to help with your problem.

In some cases, it might be more prudent to shell out some money for purpose-built solutions, such as custom software or premium paid plugins. Or to hire an experienced professional who specializes in dealing with your specific issue.

At the very least, you should always try to understand and resolve the problem on your own, instead of taking whatever pieces of code you managed to find, and hoping that it will serve your purpose well with no unexpected consequences.

Closing words.

I started out attempting to highlight why it is bad to blindly copy and paste code, but got distracted somewhere down the road. Then I pivoted back to my original topic, and talked about why some piece of code written 8 years ago that is being perpetuated and tossed around by everyone and their mothers is actually highly flawed, and probably should NOT be used on actual, real-life websites.

Is this going to stop anyone from blindly copying and pasting bad, or even potentially malicious code?

Probably not. Most likely not. Definitely not.

But hopefully, I have managed to impart in you the importance of risk-aversion.

ESPECIALLY when it comes to grabbing random bits and pieces of code from unknown online sources. If you are unable to fully comprehend what the code does in the background, it can easily cause more harm than good.

Recommendations from a bunch of random websites on the first page of Google don’t mean jack shit if all they do is steal from or echo each other’s content, without adding any original input that is actually valuable or helpful.

Copying code might make your life easier, but failing to understand how it works is guaranteed to cause you grief in the future. Always do your own research, and always test things out in a safe environment, well-isolated from anything that is remotely important, like a live website. You’ll thank yourself for it.

back to top