SQL injection is a technique to attack web applications by inserting malicious code (user supplied data) into strings which are passed to an instance of Database Server for parsing and execution. SQL injection vulnerabilities allow an attacker to inject (or execute) SQL commands within an application. It is one of the dangerous application vulnerability. One way for avoiding SQL Injection, the user supplied data should be validated in both client side and server side before parsing & executing the SQL statement so that it should not accept the potentially harmful characters.
Example of SQL injection:
The primary form of SQL injection consists of direct insertion of code into the input box which is assigned to a variable that is concatenated with SQL queries and executed.
Simple SQL injection Exampe 1 :
String empCode="";
empCode = request.getParameter ("EmpCode");
strQuery = " select * from Employee where empId= '" + empCode+ "'";
Assume that the user enters
NKN5251'; drop table user--
as input in the EmpCode text box. The text box value is assigned to the variable empCode.
In this case, the above query is assembled as select * from Employee where empId= 'NKN5251'; drop table user--'
The semicolon (;) is the end of one query and the start of another. The double dash (--) indicates that the rest of the current line is a comment and should be ignored. As the assembled query is valid and syntactically correct, it will be executed by the server. When Database Server processes this statement, it will first select all records in Employee where empId is NKN5251. Then, it will drop user table.
Simple SQL injection Exampe 2 :
The following simplest SQL injection technique is bypassing form-based login. The Java servlet code given below is a sample code which is used to login, that illustrates the vulnerability by accepting user input without performing adequate input validation or escaping meta characters:
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("<html>");
out.println("<body>");
conn = CoonetionFactory.getConnection( );
String loginId="";
String passwd="";
loginId = req.getParameter ("loginName");
passwd = req.getParameter ("password");
String strQuery = "select * from user where loginname='" + loginId +"' and password='" + passwd + "'";
stmt = conn.createStatement();
rs = stmt.executeQuery(strQuery);
if (rs.next())
out.println("Login Successfull");
else
out.println("Invalid Username or Password ");
out.println("</body>");
out.println("</html>");
out.close();
}
a) Consider the above code. For example, attacker may provide a login name of : admin' or '1'='1 and any password, the generated SQL statement becomes select * from user where loginname='admin' OR '1'='1' and password='xyz'
b) For example, even attacker may provide a login name of : ' OR ''='' and password of ' OR ''=', the generated SQL statement becomes select * from user where loginname= '' OR ''='' and password='' OR ''=''
This above examples allows an attacker to log in to the site without giving the correct password, since the ‘OR’ expression is always true. Using the same technique attackers can inject other SQL commands which could extract, modify or delete data within the database.
To prevent SQL injection:
-> Validate all user Input especially server side validation.
-> Always use parameterized query ( Prepared Statements , Stored Procedures )
-> Dynamic data should be explicitly bound to parameterized queries.
-> Never use string concatenation to create dynamic SQL.
-> Escape all user input.
-> Escape all user input.
Validating user input :
Validate user input by testing type, length, format, and range
Use stored procedures to validate user input
Reject input that contains the harmful characters (Query delimiter ; ), (Character data string delimiter ') ,
( Comment delimiter //)
Prepared Statements:
Variables passed as arguments to prepared statements will automatically be escaped by the JDBC driver.
Safe:
String strQuery = "SELECT * FROM User WHERE loginName = ? ";
PreparedStatement pstmt = con.prepareStatement(strQuery);
pstmt.setString(1, loginId);
ResultSet rs = pstmt.executeQuery();
Using PreparedStatement with Bind variables avoids SQL Injection attacks and improves the performance. Although Prepared Statements helps in defending against SQL Injection, there are also possibilities of SQL Injection attacks through inappropriate usage of Prepared Statements. The example below explains how SQL Injection attacks when using PreparedStatement
UnSafe:
String userName = req.getParameter("loginName");
PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM user WHERE loginname = '+strName+'");
0 comments:
Post a Comment