SQL Injection
SQL injection (SQLi) is a code injection technique used to attack data-driven applications by
inserting malicious SQL statements into a user-input field
This vulnerability allows an attacker to interfere with the queries an application makes to its
database, potentially revealing, altering, or deleting sensitive information.
SQL injection is one of the most common web hacking techniques and is a perennial issue.
How an SQL injection works
The vulnerability occurs when an application constructs a dynamic SQL query by
concatenating user input directly into a query string, without proper validation or
sanitization.
An example of a vulnerable login query:
sql
SELECT * FROM Users WHERE Username = '" + username + "' AND Password = '" +
password + "'";
Use code with caution.
An attacker could enter the following into the username field: ' OR '1'='1 . The resulting SQL
query would then become:
sql
SELECT * FROM Users WHERE Username = '' OR '1'='1' AND Password = '';
Use code with caution.
Because '1'='1' is always true, the database returns all rows from the Users table, bypassing
the authentication check.
Types of SQL injection attacks
SQL injection vulnerabilities can be categorized into three main types based on how an
attacker can access the database:
In-band SQLi (Classic): The attacker uses the same communication channel to launch the
attack and retrieve the results. This is the most common and includes:
o Error-based SQLi: The attacker deliberately causes the database to produce error messages
that leak information about its structure.
o Union-based SQLi: The attacker uses the UNION SQL operator to combine a malicious
query with the original query to retrieve data from other database tables.
Inferential SQLi (Blind): The attacker does not receive direct feedback from the database.
Instead, they infer information by observing the application's behavior or response time.
o Boolean-based: The attacker sends queries that evaluate to true or false. They can then tell if
their injected query was successful based on the application's different responses.
o Time-based: The attacker sends a query that includes a command to delay the database's
response. The duration of the delay reveals if the injected query was true or false.
Out-of-band SQLi: This technique is used when an attacker cannot use the same channel to
launch the attack and gather information. It requires the server to be able to make DNS or
HTTP requests to the attacker's system to exfiltrate data.
Impact of a successful SQL injection
If an SQL injection attack is successful, it can have severe consequences for an organization,
including:
Confidentiality breaches: Unauthorized access to sensitive data such as user lists,
passwords, and credit card details.
Data integrity issues: The attacker can modify, delete, or corrupt critical data in the
database.
Authentication bypass: Attackers can gain administrative access to the database or
application by bypassing normal login procedures.
System compromise: In some cases, an attacker can use SQL injection to execute commands
on the underlying operating system.
Reputational damage and fines: Data breaches can lead to a loss of customer trust and
significant regulatory penalties.
How to prevent SQL injection
The most effective defense against SQL injection is to separate SQL code from user-provided
data. Recommended prevention methods include:
Use parameterized queries (Prepared Statements): This is the most reliable defense.
Parameterized queries use placeholders for user inputs, which ensures the database treats the
input as literal data, not as an executable command.
Use Object-Relational Mappers (ORMs): Many ORM frameworks have built-in
protections against SQL injection by using parameterized queries by default.
Implement input validation: Validate and filter all user input to ensure it conforms to the
expected data type, length, and format. However, this should be used as a secondary defense,
as it is not foolproof.
Enforce the principle of least privilege: Restrict the database permissions for application
accounts to the bare minimum required to perform their functions. For example, a read-only
account should not have the ability to drop tables.
Use a Web Application Firewall (WAF): A WAF can provide an additional layer of
security by detecting and blocking malicious traffic patterns, though it is not a substitute for
secure coding.
Avoid detailed error messages: Disable verbose database error messages on production
servers, as attackers can use them to gather information about the database structure.