SQL Injection

What is SQL Injection?

SQL Injection is a type of cyberattack where the attacker manipulates SQL queries by inserting query code into an application's input fields.

According to this Edgescan report, ~42% of hacker attempts on public-facing systems are SQL injection-based, highlighting the commonality of this attack method in targeting websites and applications that rely on SQL databases​. Even more shocking, ~19% of all applications are susceptible to SQL injection attacks making it one of the most popular kinds of attacks.

Why is SQL Injection Dangerous?

Our favorite XKCD comic at Corgea is about SQL injections:

However, the realities of SQL Injection can be very serious and are multifaceted:

  • Data Breach: Attackers can access and extract sensitive information from the database.

  • Data Manipulation: Unauthorized modifications, deletions, or insertions into the database can occur.

  • System Compromise: it can serve as a gateway for further attacks, leading to a complete system compromise.

  • Reputation Damage: A successful attack can smear a company's reputation and trustworthiness. There's actually a SQL Injection Hall-of-Shame.

This is why SQL injection makes the OWASP Top 10 and the CWE Top 25 throughout the years.

Exploitation Techniques

Exporting this type of attack often involves:

  • Tautology-based Attacks: Manipulating query logic to always return true.

  • Union-based Attacks: Using the UNION SQL operator to retrieve data from other tables.

  • Blind SQL Injection: Inferring data structure and content through boolean or time-based queries.

Example

Here's a simple example of a Tautolog-based attack in an Express.js server that connects a MySQL database. It retrieves user details based on the user ID provided in the query string. However, this code is vulnerable to SQL injection because the userId is directly concatenated into the SQL query without any validation or sanitization.

const express = require('express');
const mysql = require('mysql');
const app = express();

// Database connection
const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'mydatabase'
});

app.get('/user', function(req, res) {
  let userId = req.query.id;
  let query = `SELECT * FROM users WHERE id = '${userId}'`;

  connection.query(query, function(error, results, fields) {
    if (error) throw error;
    res.send(results);
  });
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

An attacker can exploit this vulnerability by passing an SQL segment through the id parameter in the query string. For example, if the attacker navigates to in their browser or API tool:

http://localhost:3000/user?id=' OR '1'='1

The SQL query becomes:

SELECT * FROM users WHERE id = '' OR '1'='1'

This query will return all users in the database because '1'='1' is always true, thus bypassing any intended security measures. You can imagine the different ways this can be exploited across different pages and forms.

How to protect against SQL injections?

To safeguard against SQL Injection, companies must adopt a holistic approach:

  • Input Validation and Sanitization: Ensure all user input is validated and sanitized before processing.

  • Parameterized Queries: Use parameterized queries instead of string concatenation to prevent the execution of malicious code.

  • Regular Security Audits: Conduct regular code reviews and security audits to identify and fix vulnerabilities.

  • Employee Training: Educate developers and security teams about SQL risks and prevention techniques.

Based on the previous example above here's an example of a parameterized query to block this type of attack.

app.get('/user', function(req, res) {
  let userId = req.query.id;
  let query = 'SELECT * FROM users WHERE id = ?';

  connection.query(query, [userId], function(error, results, fields) {
    if (error) throw error;
    res.send(results);
  });
});

In this secure version, the ? in the query is a placeholder that will be replaced by the userId in a manner that prevents SQL injection. The MySQL library automatically handles escaping and ensures that userId is treated as a single parameter to the query, not part of the SQL command itself.

For a more interactive short-video, Ahmad from Corgea discusses solving SQL injection problems with the Vulpy project which is a Flask app with an SQLite database.

SQL Injection Fix Lesson - Watch Video

More resources

For a more in-depth understanding behind SQL injections, here's a video by Rana Khalil, where she covers the theory behind SQL injection vulnerabilities, how to find these types of vulnerabilities from both a white box and black box perspective, how to exploit them and how to prevent them.

Conclusion

SQL Injection is a potent threat that demands vigilant attention. By understanding its mechanics, risks, and implementing robust security measures, companies can significantly reduce their vulnerability. With advancements like Corgea's AI-powered code fixing tool, the future of AppSec in enterprise environments looks more secure and efficient, promising a new era of automated, intelligent cybersecurity solutions.