Lesson Plan Title: How to Perform a SQLInjection

Concept / Topic To Teach:
SQL injection attacks represent a serious threat to any database-driven site. The methods behind an attack are easy to learn and the damage caused can range from considerable to complete system compromise. Despite these risks, an incredible number of systems on the internet are susceptible to this form of attack.

Not only is it a threat easily instigated, it is also a threat that, with a little common-sense and forethought, can easily be prevented.

It is always good practice to sanitize all input data, especially data that will used in OS command, scripts, and database queiries, even if the threat of SQL injection has been prevented in some other manner.

General Goal(s):
For this exercise, you will perform SQLInjection attacks. You will also implement code changes in the web application to defeat these attacks.

Solution:
To prevent a SQLInjection you can use "Parametreized Queries". This kind of query makes it possible to use every input of an user as a parameter. In this lesson you have to change org.owasp.webgoat.lessons.SQLInjection.Login.java The query execution in the method login looks like this:

String query = "SELECT * FROM employee WHERE userid = " + userId + " and password = '" + password + "'";
// System.out.println("Query:" + query);
try
{
  Statement answer_statement = WebSession.getConnection(s)
      .createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
  ResultSet answer_results = answer_statement.executeQuery(query);
  etc...

To paramerize the Query you have to replace the userinput with questionmarks:
String query = "SELECT * FROM employee WHERE userid = ? and password = ?";

Now follows the try block with the getConnection method:
try
{
  Connection connection = WebSession.getConnections(s);

The next step is to do a so called "PrepareStatement":
PreparedStatement statement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

Now that the query is prepared we have to add the parameters to the query:
statement.setString(1, userId);
statement.setString(2, password);

We are ready to execute the query!
ResultSet answer_results = statement.executeQuery();

Putting everything together results in:


String query = "SELECT * FROM employee WHERE userid = ? and password = ?";
try
{
  Connection connection = WebSession.getConnections(s);
  PreparedStatement statement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
  statement.setString(1, userId);
  statement.setString(2, password);
  ResultSet answer_results = statement.executeQuery();
  etc...