A SQL injection attack consists of insertion or "injection" of a SQL query via the input data from the client to the application. A successful SQL injection exploit can read sensitive data from the database, modify database data (Insert/Update/Delete), execute administration operations on the database (such as shutdown the DBMS), recover the content of a given file present on the DBMS file system and in some cases issue commands to the operating system. SQL injection attacks are a type of injection attack, in which SQL commands are injected into data-plane input in order to effect the execution of predefined SQL commands.
Incorrectly filtered escape characters
This form of SQL injection occurs when user input is not filtered for escape characters and is then passed into an SQL statement. This results in the potential manipulation of the statements performed on the database by the end user of the application.
The following line of code illustrates this vulnerability:
statement = "SELECT * FROM users WHERE name = '" + userName + "';"
This SQL code is designed to pull up the records of the specified username from its table of users. However, if the "userName" variable is crafted in a specific way by a malicious user, the SQL statement may do more than the code author intended. For example, setting the "userName" variable as
' or '1'='1
renders this SQL statement by the parent language:
SELECT * FROM users WHERE name = '' OR '1'='1';
Preventing SQL injection
Parameterized statementsWith most development platforms, parameterized statements can be used that work with parameters (sometimes called placeholders or bind variables) instead of embedding user input in the statement. In many cases, the SQL statement is fixed, and each parameter is a scalar, not a table. The user input is then assigned (bound) to a parameter. This is an example using Java and the JDBC API:
PreparedStatement prep = conn.prepareStatement("SELECT * FROM USERS WHERE USERNAME=? AND PASSWORD=?");
Enforcement at the database levelCurrently only the H2 Database Engine supports the ability to enforce query parameterization.However, one drawback is that query by example may not be possible or practical because it's difficult to implement query by example using parametrized queries.
Enforcement at the coding levelUsing object-relational mapping libraries avoids the need to write SQL code. The ORM library in effect will generate parameterized SQL statements from object-oriented code.
EscapingA straight-forward, though error-prone, way to prevent injections is to escape characters that have a special meaning in SQL. The manual for an SQL DBMS explains which characters have a special meaning, which allows creating a comprehensive blacklist of characters that need translation. For instance, every occurrence of a single quote (
') in a parameter must be replaced by two single quotes (
'') to form a valid SQL string literal. In PHP, for example, it is usual to escape parameters using the function
mysql_real_escape_stringbefore sending the SQL query:
$query = sprintf("SELECT * FROM Users where UserName='%s' and Password='%s'",