The number of cyber crimes carried out against online businesses and applications has been increasing in recent years. Attackers can take advantage of businesses with poorly built systems to inflict data and monetary losses.
MySQL is one of the most popular open source relational database management systems out there, and it is used to store data for websites and web servers. Most popular web frameworks and web servers use MySQL as their default database.
MySQL has some vulnerabilities we have to look out for in order to secure our data and in this article, we are going to explore these various vulnerabilities and find a fix.
SQL Injection – Database Nightmare
SQL Injection is one of the most dangerous cyber attacks targeted at databases in order to steal sensitive information or inflict data loss. It’s a type of injection attack that makes it possible to run malicious SQL queries that could lead to data theft or data loss.
SQL Injections are a nightmare for web developers as they are being targeted most due to known loopholes available on their servers and applications. Malicious users can make use of SQL Injection vulnerabilities to bypass application security and authentication procedures.
A successful attacker can access authenticated and authorized sections of a web application or web server, retrieve records of the database, or add, modify and delete records in the database.
Let’s assume we have an application and we are trying to authenticate a user called John. We’d send the his login details in the query below to the server for authentication:
SELECT * FROM users WHERE username='john' AND password='john123*'
Your application basically builds the query above with the user inputs in order to know if a user exists with such a username and password.
Now let’s assume we have a malicious user that enters a malicious password–*’ OR ‘1’=’1′. When your application builds the database query, it would be:
SELECT * FROM users WHERE username='john' AND password='*' OR '1'='1'
Running this query would always return true and assumes the user password is correct. The first part will try to find a user – john who has password – * and that’s definitely going to return no result or false. However, the second part will always return true, thereby making the query pass.
This will basically bypass any authentication in place as the query will return true and any matching user with username john.
Now, let’s look at another scenario where malicious users will be able to retrieve other tables in database.
SELECT * FROM users where username='john' UNION (SELECT 1, TABLE_NAME, TABLE_SCHEMA FROM information_schema.tables); -- %'
With the above query, the user would be able to retrieve all tables from the database. Now that the attacker knows all tables where you store your data, they can query the columns of each table as well as each data in each table.
The attacker is going to use the query below to query the user columns:
SELECT * FROM users where username='john' UNION (SELECT 2, COLUMN_NAME, 3 FROM information_schema.columns WHERE TABLE_NAME = 'users'); -- %'
Then this to query all data in the users table:
SELECT * FROM users where username='john' UNION (SELECT id, username, password FROM users); -- %'
The attacker can end up making john an admin in the database without even using the right password for the account like below:
SELECT id FROM users WHERE username = 'john';
INSERT INTO group_membership (id, group)
VALUES (SELECT id FROM users WHERE username='john', 'Administrator'); -- %'
All this can be avoided and fixed by sanitizing every user input that comes in and also using SQL prepared statement to create parameterized query.
The best way to prevent SQL injection is not to trust user inputs and use prepared statement since inputs are being sanitized before it generates the final query.
Cross Site Scripting(XSS) – Client Hijacking
Cross-Site Scripting(XSS) is one of the most common and dangerous cyber attacks targeting web applications. It’s usually carried out on the client side of the application(usually browser) by using malicious scripts embedded on a web page in web applications in order to take control of the current page.
This exploits website vulnerability by injecting malicious scripts that will run on the client’s side. The idea is to embed and run a script in a web page of a web application and execute it in the pattern desired by the attacker.
The script can be executed every time the page is loaded, or whenever an associated event is performed.
Let’s assume you have an application that takes in user comments and displays them. You would need to take in the user comment as a string and save it in the database. Then on the client side, you can output to the comments section.
However, if a malicious user puts in a comment that has a script, if the comment is displayed on the web page without sanitizing and escaping the comment when saving it, the script will be seen as an html element that will be executed.
Let’s assume you entered this in the comment box:
<script>alert('This is XSS Injection')</script>
And let’s say we want to render a list of comments like below:
If the comments were saved into the database without escaping them and we try to render it on a webpage, it would output the comment the way it is and execute any script:
To fix this, you will need to escape all the inputs before saving and before rendering on the web page or stripe out all html content or prevent users from entering any html content. Depending on your web application stack and tech, there are many ways you can escape any html content.
If you escape the above script, you will get something like this in your database:
Denial of service attacks are one of the most popular and dangerous cyber attacks targeted at web servers or server instances like MySQL. The aim is to make the service, network resource or instances unavailable temporarily or indefinitely disrupting the whole system or a host the resource or instance is connected to.
In the MySQL case, it can cause the MySQL instance to crash thereby making it temporarily unusable by any service connected to it for data source.
This vulnerability allows remotely authenticated users to cause a denial of service(MySQL crash) through a malicious SELECT command with an UpdateXML command containing an intentional XML with a large number of unique, nested elements.
This makes MySQL prone to a denial-of-service vulnerability. A malicious user can exploit this vulnerability to crash the database, denying access to the right users.
Running the SQL query below is gonna crash your database:
SELECT UpdateXML(‘<a>$a<b>ccc</b><d></d></a>’,‘/a’,‘<e>fff</e>’) AS val1
To fix this vulnerability, ensure you are using MySQL version greater than 5.5.* as 5.1.67 and earlier, 5.5.29 and earlier are affected by the vulnerability.
Race condition is an unwanted situation or scenario that occurs when a device, system or software tries to run two or more operations simultaneously, however, due to the nature of the system or device, the operations must be executed in the right sequence or timing due to other uncontrollable events to ensure its done efficiently.
In the MySQL case, this vulnerability can cause a race condition, which can be very severe. It can let a local user that has access to a database escalate their privileges and run arbitrary code as the database local user.
Race condition is present in Oracle MySQL before 5.5.52, 5.6.x before 5.6.33, 5.7.x before 5.7.15, and 8.x before 8.0.1; MariaDB before 5.5.52, 10.0.x before 10.0.28, and 10.1.x before 10.1.18 and allows local users with certain permissions to gain privileges by leveraging use of my_copystat by REPAIR TABLE to repair a MyISAM table.
Malicious users can exploit this vulnerability to bypass certain security restrictions and run unauthorized actions. This may help in launching further malicious attacks.
The issue has been fixed and patched in the affected versions stated earlier and the following new versions, Oracle MySQL 5.5.x, 5.6.x, 5.7.x and so on.
This is a very unique vulnerability that only occurs when user generated inputs are not well sanitized before being passed to the database query. This is a type of attack that is targeted at a remote User Enumeration vulnerability in MySQL server database.
The aim here’s for the attacker to validate if a particular user or username is valid or exist in your database and find away around it to access its sensitive information by using the generated error messages. A malicious user can take advantage of this vulnerability to enumerate valid usernames and gain unauthorized access to sensitive data.
So with this vulnerability, a malicious user can confirm if a particular username is in use by the SQL db instance. It responds with“Access denied” error messages if the account does not exist. However if it returns another response, the attacker can then confirm the user really does exist.
This vulnerability affects the following versions: Oracle MySQL 5.5.38 and earlier, 5.6.19 and earlier.
To avoid this, you need to sanitize user–generated inputs and upgrade to later versions after the ones mentioned.