How Poor Coding Puts WordPress Sites at Risk of Hacking

Published 16 June 2021
Updated 9 October 2024
Table of Contents

WordPress is the world’s most popular content management system. Over 835 million websites use it, and nearly 22% of new U.S. registered domains install WordPress.

In recent years, WordPress has faced some criticism for its use of PHP and potential security risks.

But are these concerns justified?

This article will explore poor coding practices and their security implications, and evaluate whether WordPress is a safe platform.

The dangers of poor coding

According to the Software Engineering Institute at the Department of Homeland Security, 90% of all reported security incidents result from exploits and defects in software design or code. Many of these defects have occurred as a result of poor coding practices

Poor coding practices can lead to various security risks:

  1. Increased Vulnerability to Attacks: Poorly written code often contains security holes that malicious actors can exploit. For instance, improper input validation can lead to SQL injection or cross-site scripting (XSS) attacks.
  2. Data Breaches: Insecure coding practices, such as inadequate encryption or improper access controls, can result in unauthorized access to sensitive data.
  3. Performance Issues: Inefficient code can lead to slow load times and poor user experience, potentially driving users away from the site.
  4. Maintenance Nightmares: Poorly structured code is challenging to update and maintain, increasing the likelihood of introducing new bugs or security vulnerabilities during updates.
The dangers of poor coding

Understanding Poor Coding Practices

Poor coding practices refers to suboptimal programming habits, which can lead to vulnerabilities, maintenance difficulties, and performance issues. These practices often result from insufficient skill, time constraints, or simple oversight.

Let’s explore some common poor coding practices and their potential consequences:

Inconsistent code formatting

Good programmers format their code in a way that is easy to read. Experienced developers maintain a widely used formatting standard throughout their work so other programmers can understand it easily and write code in the same style.

Example of poor formatting:

function calculateTotal($price,$quantity){

if($quantity>10){$discount=0.1;}else{$discount=0;}

return $price*$quantity*(1-$discount);

}

Poor formatting is considered poor coding because it makes code more challenging to maintain, which increases the likelihood of introducing bugs during updates. Many automated linting and refactoring tools can automate this process and ensure that all developers follow one standard format. 

Example of good formatting:

function calculateTotal($price, $quantity) {

    if ($quantity > 10) {

        $discount = 0.1;

    } else {

        $discount = 0;

    }

    return $price * $quantity * (1 - $discount);

}

Lack of input validation

Whenever you accept data from users, you should verify and double-check everything! Good programmers are conscientious about how they process and store the data given to the application by users.

That’s because user data is often a source of cyberattacks, including SQL injections and Cross-site Scripting (XSS).

Let’s take a look at how this works:

SQL injection vulnerabilities

SQL injection occurs when an attacker inserts malicious SQL code into application queries, typically through user input fields. This can trick the database into executing unintended commands.

Unvalidated User Input: Many WordPress plugins and themes fail to properly sanitize user input before using it in SQL queries. For example:

$user_id = $_GET['user_id'];

$query = "SELECT * FROM users WHERE id = $user_id";

This code is vulnerable because it directly uses user input in the query without validation.

Improper Use of WordPress Database Functions: WordPress provides functions like $wpdb->prepare() to help prevent SQL injection, but developers often misuse them:

$user_id = $_GET['user_id'];

$query = $wpdb->prepare("SELECT * FROM users WHERE id = %s", $user_id);

While this looks safer, using %s for an integer value can still lead to injection vulnerabilities.

Best Practices for Developers

  1. Always validate and sanitize user input. WordPress provides several methods to sanitize, validate, and escape user data that you can use to do this correctly.
  2. Use parameterized queries or properly use $wpdb->prepare().
  3. Apply the principle of least privilege to database users.

Cross-Site Scripting (XSS) attacks

Cross-Site Scripting (XSS) is another common vulnerability in poorly coded WordPress sites. It allows attackers to inject malicious scripts into web pages viewed by other users.

Types of XSS Attacks:

  1. Stored XSS: Malicious scripts are permanently stored on target servers.
  2. Reflected XSS: The injected script is reflected off the web server in an error message or search result.
  3. DOM-based XSS: The vulnerability is on the client rather than the server-side code.

Read our in-depth post to learn more about XSS attacks: https://app.asana.com/0/1205509068567309/1207416887435798/f 

Embed image https://patchstack.com/wp-content/uploads/2024/03/Cross-Site-Scripting-XSS-was-the-most-common-vulnerability-in-WordPress-in-2023.png 

Here is an example of vulnerable code that directly outputs user input without sanitization, leaving the website vulnerable to XSS attacks:

<?php

$username = $_GET['username'];

echo "<h1>Welcome, $username!</h1>";

?>

Prevention Techniques

  1. Sanitize all user inputs using WordPress functions such as esc_html() or wp_kses().
  2. Implement Content Security Policy (CSP) headers. If you are unsure how to do this, refer to our previous post, which discussed adding security headers to WordPress.
  3. Use the HttpOnly flag for cookies to prevent access through client-side scripts.

Hardcoding sensitive information

You might already know this one, but you’d be surprised how often developers store sensitive information such as passwords and API keys in the source code itself. One of the most notable examples is when the developers at Rabbit r1 hard-coded the security keys, allowing anyone to view all customers’ conversations!

Poor practice:

$dbPassword = "mySecretPassword123";

The above example shows that the password is stored in the source code, which anyone can read. It is recommended that the passwords be stored in an environment variable and read when necessary.

Good practice:

$dbPassword = getenv('DB_PASSWORD');

Insecure Direct Object References (IDOR)

When you visit a website, you can open the developer tools in any browser to see all the data and code sent to your computer in raw format. Novice developers assume this code is as good as invisible, and normal users will never see it. 

If this code contains direct references to sensitive data, hackers can reverse engineer your code and access the data without any authentication. This is commonly known as the insecure direct object references (IDOR) vulnerability.

IDOR vulnerabilities occur when an application exposes a reference to an internal implementation object, such as a file, directory, or database key. Let’s try to understand this with the help of an example.

Say you are logged in to your Netflix account and watching a movie you enjoyed very much, so you decide to share the direct video link with your friends via email. When your friends click on the link, Netflix first checks if your friends are allowed to watch the movie (by asking them to log in). If there is an IDOR vulnerability present on Netflix, then your friends will be able to watch the movie without paying for Netflix.

IDOR vulnerabilities can be tricky to identify and require rewriting some software parts. Read this article to learn more about IDOR vulnerabilities.

Insufficient error handling

When you write code, it’s easy to make certain assumptions. These assumptions can be as simple as assuming that the user will only send a number when you ask them about their birth year or can be as nuanced as thinking that surely a customer won’t order -1 tomatoes.

When you don’t handle these cases in your code, your code will crash, and poor coding practices will reveal useful error information to hackers. Errors should be handled gracefully and in a way that minimizes application exposure.

Suppose your website shows error messages directly to users. In that case, you might disclose sensitive information that hackers can use to launch attacks such as Stack Overflow, IDOR, or brute force attacks that bypass security firewalls.

WordPress and security: a balanced view

WordPress, as one of the most widely used content management systems (CMS) globally, has been both praised for its flexibility and criticized for certain aspects of its codebase. Let’s explore some of these criticisms and their implications.

Inconsistent naming conventions

One of the most frequent critiques of WordPress is its irregular naming conventions for functions and variables. This inconsistency can confuse developers, especially those new to the WordPress ecosystem.

Examples of naming inconsistencies:

get_the_content() vs. the_content()

get_permalink() vs. the_permalink()

The prefix “get_” typically means retrieving data, while “the_” usually indicates a function that outputs data directly. However, this convention isn’t consistently applied throughout WordPress core functions.

For instance:

$content = get_the_content(); // Retrieves content

the_content(); // Outputs content

$permalink = get_permalink(); // Retrieves permalink

the_permalink(); // Outputs permalink

This inconsistency can be attributed to WordPress’s long history and the need to maintain backward compatibility. While it may seem chaotic, changing these function names now would break countless existing websites and plugins.

Missing core features

WordPress’s philosophy has always been to keep the core lean and extend functionality through plugins. While this approach offers flexibility, it also means that some features considered standard in other CMS platforms are not included in the WordPress core.

Advanced caching is a prime example. Many WordPress sites rely on third-party caching plugins for:

  • Memory caching
  • Disk caching
  • File minification

While this plugin-based approach allows for customization, it also introduces potential security risks, as third-party code may not undergo the same rigorous review process as WordPress core.

Many WordPress sites rely on third-party caching plugins

Legacy coding techniques

WordPress was developed in the early 2000s. It primarily uses procedural programming with some object-oriented concepts rather than fully embracing modern architectural patterns such as Model-View-Controller (MVC).

While the WordPress approach is functional, the MVC pattern offers a better separation of concerns, making the code more maintainable and potentially more secure.

Legacy coding techniques

Plugin and theme security concerns

The WordPress ecosystem’s strength – its vast array of plugins and themes – is also a potential weakness from a security standpoint. With over 50,000 plugins in the official repository, quality and security can vary significantly.

According to our State of WordPress Security In 2024 Report, most WordPress vulnerabilities stem from plugins and themes rather than the core. This highlights the importance of careful plugin selection and regular updates.

Embed image https://patchstack.com/wp-content/uploads/2024/03/In-2023-plugins-were-responsible-for-96.77-of-all-new-WordPress-vulnerabilities.png 

Should you still use WordPress?

Despite the issues with the WordPress core, third-party plugins, and third-party themes, WordPress remains one of the safest content management systems.

Because it is an open-source project, thousands of developers and contributors worldwide are looking for bugs and vulnerabilities in the codebase.

The WordPress development team is very proactive about identifying and repairing bugs and vulnerabilities in the WordPress core.

They have also written extensively about their approach to securing WordPress, and are very fast when patching security issues.

They are continually hardening the application to address common security concerns, including the ones listed by the Open Web Application Security Project (OWASP). These issues include brute force attacks, file injection, and SQL injection.

The true cost of cheap development

Regarding WordPress development, the adage “you get what you pay for” couldn’t be more true. Opting for cheap developers or relying solely on AI-generated code can lead to severe security vulnerabilities and long-term costs that far outweigh the initial savings. 

Risks of low-quality development

If you only hire low-cost developers from unreliable sources, then you can expect the following:

  1. Lack of Security Awareness: Inexperienced or untrained developers may not be aware of the latest security best practices or common vulnerabilities.
  2. Copy-Paste Coding: Cheap developers often copy code from online sources without understanding its security implications.
  3. Poor Code Quality: Rushed or inexperienced development leads to spaghetti code that’s hard to maintain and more likely to contain vulnerabilities.
  4. Inadequate Testing: Thorough security testing is often skipped to cut costs, leaving vulnerabilities undetected.

Popular fast food chain McDonald’s learned this lesson the hard way when hackers hacked its self-service machine to get a free burger.

The true cost of cheap development

The AI code generation trap

While AI tools can be helpful, blindly using AI-generated code without proper understanding and review can be dangerous:

  1. Lack of Context: AI doesn’t understand the full context of your application and may generate inappropriate or insecure code for your specific use case.
  2. Outdated Patterns: AI models might be trained on outdated code patterns that don’t reflect current security best practices.
  3. False Sense of Security: Relying on AI-generated code can create a false sense of security, leading to less scrutiny and review.

If you think we’ve blown this out of proportion, you should read this article to learn how AI code helpers make up non-existent package names or read about when an AI agent promoted itself to sysadmin and then trashed the boot sequence.

The AI code generation trap

Final thoughts

This article discusses how poor coding practices can make your website vulnerable to cyber attacks. It is important to remember that the cost of a security breach far outweighs the cost of proper development. Investing in quality development from the start pays off in the long run in several ways:

  1. Reduced Maintenance Costs: Well-written, secure code is easier to maintain and update.
  2. Lower Risk of Breaches: Properly secured sites are less likely to suffer costly data breaches or hacks.
  3. Better Performance: Quality code often performs better, providing a better user experience and potentially better SEO rankings.
  4. Easier Compliance: With increasing data protection regulations, properly secured sites are easier to bring into compliance.

While WordPress has its quirks and potential security concerns, it remains a popular and powerful platform for web development. As WordPress continues to evolve, we may see improvements in these areas. Still, the need to maintain backward compatibility will likely mean that some of these quirks will remain a part of the WordPress ecosystem for the foreseeable future – this is where Patchstack comes in!

Patchstack offers a robust solution to safeguard your WordPress site against potential threats.

Why Choose Patchstack?

  • Real-time Vulnerability Detection: Stay ahead of potential threats with continuous monitoring.
  • Automatic Security Patches: Keep your site secure without manual intervention.
  • WordPress-specific Protection: Tailored security measures for the WordPress ecosystem.
  • Plugin & Theme Vulnerability Alerts: Get notified about risks in your installed themes and plugins.
  • Comprehensive Security Reporting: Gain insights into your site’s security status with automated reports.

Sign Up for Patchstack Now!

The latest in Security advice

Looks like your browser is blocking our support chat widget. Turn off adblockers and reload the page.
crossmenu