DEV Community

ANIRUDDHA ADAK
ANIRUDDHA ADAK

Posted on

SQL Injection: A Deep Dive into a Persistent Vulnerability

DISCLAIMER:

THIS CONTENT IS FOR EDUCATIONAL PURPOSES ONLY.
IT DOES NOT ENDORSE OR ENCOURAGE ANY ILLEGAL ACTIVITY.

SQL Injection remains a significant threat in the world of web security. Today, we'll explore how this vulnerability works and demonstrate two common payload types that can exploit a basic login form. Understanding these techniques is crucial for developers and security professionals to build more resilient applications.

How a Login Form Interacts with a Database

When you submit a login form on a website, the application typically constructs a SQL query to verify your credentials against its database. This query might look something like this:

SELECT * FROM users WHERE username='your_username' AND password='your_password';
Enter fullscreen mode Exit fullscreen mode

If the provided username and password match an entry in the users table, the login is successful.

Exploiting the Vulnerability: The Power of Strings and Queries

The core of a SQL Injection vulnerability lies in how user input is handled. In programming languages, a sequence of characters enclosed in quotes (single or double) is treated as a string. Any characters outside these quotes are interpreted as part of the SQL query itself. If an application directly inserts user input into a SQL query without proper sanitization, an attacker can manipulate the query's logic.

Consider what happens if we input a single quote into a username field. For example, if we type admin' (username: admin followed by a single quote) and a password like password123, the database might attempt to execute a malformed query like:

SELECT * FROM users WHERE username='admin'' AND password='password123';
Enter fullscreen mode Exit fullscreen mode

This will likely result in a "Syntax error." This error message, while seemingly a failure, is actually a crucial indicator of a SQL Injection vulnerability. It tells us that the application isn't properly escaping or validating input, and we can inject additional SQL code into the query.

SQL Injection Payload 1: The OR Payload

Our goal is to make the login query evaluate to TRUE regardless of the actual stored credentials. The OR payload is a classic way to achieve this.

The original query logic requires both the username AND the password to match for a successful login. If either part is FALSE, the entire AND condition becomes FALSE.

However, if we inject an OR condition that is always TRUE, we can bypass the initial AND condition.

Let's try injecting the following into the username field:
admin' OR '1'='1

With a dummy password like password123, the resulting SQL query becomes:

SELECT * FROM users WHERE username='admin' OR '1'='1' AND password='password123';
Enter fullscreen mode Exit fullscreen mode

SQL evaluates AND operations before OR operations. So, it first checks ('1'='1' AND password='password123'). While the password='password123' part might be false, '1'='1' is always TRUE. Therefore, username='admin' OR TRUE will always evaluate to TRUE, regardless of whether username='admin' is true or false.

This effectively bypasses the password check, granting access.

SQL Injection Payload 2: The Comment Payload

Another powerful and often surprisingly simple technique is the Comment payload. In many SQL dialects (like MySQL), two consecutive hyphens followed by a space (--) denote a comment. Any text after this sequence on the same line is ignored by the database.

If we input the following into the username field:
admin' --

With a dummy password like password123, the resulting SQL query becomes:

SELECT * FROM users WHERE username='admin' -- AND password='password123';
Enter fullscreen mode Exit fullscreen mode

Because of the -- comment delimiter, the database parser will ignore everything that comes after it, including the AND password='password123' part of the original query. The query effectively reduces to:

SELECT * FROM users WHERE username='admin';
Enter fullscreen mode Exit fullscreen mode

If an 'admin' user exists in the database, the query will return a match, and the login will be successful without requiring any password. This is a particularly dangerous method because it simplifies the bypass significantly.

Preventing SQL Injection

Despite being an old technique, SQL Injection remains a top vulnerability. This is often due to legacy codebases or a lack of awareness regarding secure coding practices. Fortunately, preventing SQL Injection is straightforward with the right measures:

  • Use Prepared Statements with Parameterized Queries: This is the most effective defense. Instead of directly concatenating user input into the SQL query string, placeholders are used. The input is then passed as separate parameters, ensuring it's treated as data and not as executable code.
  • Use Stored Procedures: Similar to prepared statements, stored procedures are pre-compiled SQL code that can accept parameters. This separation of code and data helps prevent injection.
  • Implement Input Validation (Allow-listing): Validate all user input against a strict "allow-list" of acceptable characters, formats, and lengths. Reject anything that doesn't conform.
  • Escape User Input: If prepared statements or stored procedures aren't feasible (e.g., with legacy systems), manually escaping special characters in user input before inserting them into a query can help. However, this method is less robust and more prone to errors than parameterized queries.

By adopting these security measures, developers can significantly reduce the risk of SQL Injection attacks and safeguard their applications and sensitive data. Understanding how these attacks work is the first step towards building secure software.

Top comments (0)