Injection attacks occur when a user inputs values that contain special characters into a web form. The most common example is SQL injection. For example when checking that a password is correct, you could write code which concatenates the username and password into a string of SQL, then executes it.
String sql = "Select * from users where username = '" + username + "' and password = '" + password + "'";
What happens if someone enters this as a password:
' OR 1==1 --
The sql string becomes:
select * from users where username=' ' OR 1=1 --' and password=''
The -- is an SQL comment, so the SQL will always return the user details, regardless of whether the correct password is used.
The best way to deal with injection attacks is to use a parameterised API, such as JDBC. This escapes the single quote character, so it is not interpreted as SQL.
String sql = "Select * from users where username = ? and password = ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, username); ps.setString(2, password);
If there is no parameterised API then escape any special characters from user data before using them.
You should validate all request parameters, for example by comparing the values against a white list. This is especially important when the user can specify ordering of the SQL data:
Map<String, String> validOrderBys = new HashMap<String, String>(); validOrderBys.put("poDate", "PO_DATE"); validOrderBys.put("poNumber", "PO_NUMBER"); validOrderBys.put("lastName", "LAST_NAME"); String validatedOrderBy = validOrderBys.get(orderByFromRequestParam);
The validOrderBys map in the example validates the value from the request parameter and also conceals the name of the column in the database.
Also see the section on making your web app log into the database with a different schema than the one that owns the tables. This can be used to limit the damage that a successful SQL injection attack can cause.