SQL injection, a code injection method, has the potential to compromise your database integrity.
Among the prevalent web hacking techniques, SQL injection stands out.
SQL injection involves embedding malicious code within SQL statements, often through user-input on web pages.
SQL injection typically arises when soliciting user input, such as a username or user ID, where instead of legitimate data, the user submits an SQL statement. This SQL statement is then unwittingly executed on the database.
Consider the following instance: a SELECT statement is constructed by concatenating a variable (txtUserId) with a select string. This variable is obtained from user input (getRequestString).
txtUserId = getRequestString(“UserId”); txtSQL = “SELECT * FROM Users WHERE UserId = ” + txtUserId; |
The subsequent section outlines the risks associated with incorporating user input into SQL statements.
In revisiting the example provided, the initial intent of the code was to generate an SQL statement for selecting a user based on a specified user ID.
However, in the absence of any safeguards against incorrect input, users can input cleverly crafted data, as illustrated below:
User ID:
105 OR 1=1 |
Subsequently, the SQL statement will appear as follows:
SELECT * FROM Users WHERE UserId = 105 OR 1=1; |
The above SQL query is valid and will return all rows from the “Users” table because “OR 1=1” is always TRUE.
Does the example above seem dangerous? What if the “Users” table contains names and passwords?
The SQL statement provided is analogous to this:
SELECT UserId, Name, Password FROM Users WHERE UserId = 105 or 1=1; |
Below is an illustration of a user login process on a website:
Username:
John Doe |
Password:
myPass |
uName = getRequestString(“username”); uPass = getRequestString(“userpassword”); sql = ‘SELECT * FROM Users WHERE Name =”‘ + uName + ‘” AND Pass =”‘ + uPass + ‘”‘ |
SELECT * FROM Users WHERE Name =“John Doe” AND Pass =“myPass”
|
By inserting ” OR “”=” into either the username or password text box, a hacker could potentially gain access to user names and passwords stored in a database.
User Name:
” or “”=” |
Password:
” or “”=” |
The code on the server will generate a SQL statement that is valid, similar to the following:
SELECT * FROM Users WHERE Name =“” or “”=“” AND Pass =“” or “”=“”
|
This SQL statement is valid and will retrieve all rows from the “Users” table because the condition “OR “”=”” is always TRUE.
Many databases offer support for batched SQL statements, which are groups of two or more SQL statements separated by semicolons.
The following SQL statement will first retrieve all rows from the “Users” table and then proceed to delete the “Suppliers” table.
SELECT * FROM Users; DROP TABLE Suppliers |
Consider the example below:
txtUserId = getRequestString(“UserId”); txtSQL = “SELECT * FROM Users WHERE UserId = ” + txtUserId; |
Take a look at the input provided below:
User id:
105; DROP TABLE Suppliers |
Here’s how the valid SQL statement would appear:
SELECT * FROM Users WHERE UserId = 105; DROP TABLE Suppliers; |
To safeguard a website from SQL injection, employing SQL parameters is advisable.
SQL parameters refer to values incorporated into an SQL query during execution, in a carefully controlled manner.
txtUserId = getRequestString(“UserId”); txtSQL = “SELECT * FROM Users WHERE UserId = @0”; db.Execute(txtSQL,txtUserId); |
txtNam = getRequestString(“CustomerName”); txtAdd = getRequestString(“Address”); txtCit = getRequestString(“City”); txtSQL = “INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)”; db.Execute(txtSQL,txtNam,txtAdd,txtCit); |
Below is an example illustrating how to construct parameterized queries in some commonly used web languages.
ASP.NET SELECT STATEMENT:
txtUserId = getRequestString(“UserId”); sql = “SELECT * FROM Customers WHERE CustomerId = @0”; command = new SqlCommand(sql); command.Parameters.AddWithValue(“@0”,txtUserId); command.ExecuteReader(); |
INSERT INTO STATEMENT IN ASP.NET:
txtNam = getRequestString(“CustomerName”); txtAdd = getRequestString(“Address”); txtCit = getRequestString(“City”); txtSQL = “INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)”; command = new SqlCommand(txtSQL); command.Parameters.AddWithValue(“@0”,txtNam); command.Parameters.AddWithValue(“@1”,txtAdd); command.Parameters.AddWithValue(“@2”,txtCit); command.ExecuteNonQuery(); |
INSERT INTO STATEMENT IN PHP:
$stmt = $dbh->prepare(“INSERT INTO Customers (CustomerName,Address,City) VALUES (:nam, :add, :cit)”); $stmt->bindParam(‘:nam’, $txtNam); $stmt->bindParam(‘:add’, $txtAdd); $stmt->bindParam(‘:cit’, $txtCit); $stmt->execute(); |