SQL Injection

What is SQL Injection?

A SQL injection attack consists of insertion or "injection" of a SQL query, via the input data, from the client to the application.

A successful SQLi exploit can read sensitive data from the database, modify database data (Insert/Update/Delete), execute administration operations on the database (such as shutdown the DBMS), recover the content of a given file present on the DBMS file system and in some cases issue commands to the operating system. SQL injection attacks are a type of injection attack, in which SQL commands are injected into data-plane input in order to effect the execution of predefined SQL commands.


SQL Injection Example

Here is a basic HTML login form with two inputs: username and password.

<form method="post" action="/login">
    <input name="username" type="text" id="username">
    <input name="password" type="password" id="password">

The common way for the /login to work is by building a database query. If the variables $request.username and $request.password are requested directly from the user’s input, this can be compromised.

      SELECT id
      FROM Users
      WHERE username = '$request.username'
      AND password = '$request.password'

For example, if a user inserts admin' or 1=1 -- as the username, he/she will bypass the login form without providing a valid username/password combination.

      SELECT id
      FROM Users
      WHERE username = 'admin' or 1=1--
      AND password = 'request.password'

The issue is that the ' in the username closes out the username field, then the -- starts a SQL comment causing the database server to ignore the rest of the string. As the inputs of the web application are not sanitized, the query has been modified in a malicious way.

How to prevent SQL Injection

The source of the problem of SQL Injection (the most important injection risk) is based on SQL queries that use untrusted data without the use of parametrized queries (without PreparedStatement in Java environments).

First of all, Hdiv minimizes the existence of untrusted data thanks to the web information flow control system, which avoids the manipulation of data generated on the server side. This architecture minimizes the risk to only the new data generated legally from editable form elements. Note that even using PreparedStatement, if the query is based on untrusted data generated previously at the server side (for instance the identification id of an item within a list), a SQL Injection risk is possible.

Although PreparedStatement solves most cases, there are some SQL keywords that cannot be used with PreparedStatement, such as ORDER BY. In these cases, we have to concatenate the column name and the order to the SQL query, but only after verifying that the column name and order are valid in this context and sanitizing them to counter any attempt of SQL Injection attack.

How do I prevent SQL Injection attacks?

Use parametrized queries

Variables passed as arguments to prepared statements will automatically be escaped by the JDBC driver.

conn = pool.getConnection( );

PreparedStatement stmt = conn.prepareStatement("SELECT id FROM Account WHERE username=? AND password=?");

stmt.setString(1, username);
stmt.setString(2, password);

rs = stmt.executeQuery(sql);
if (rs.next()) {
    loggedIn = true;
    out.println("Successfully logged in");
} else {
    out.println("Username and/or password not recognized");

Input validation

Custom validation

Validate all input data to the application using whitelist (what is allowed) for type, format, length, range, reject if invalid. For example, validate an email address and a phone number:

private Pattern regexPattern;
private Matcher regMatcher;

public String validateEmailAddress(String emailAddress) {
    regexPattern = Pattern.compile("^[(a-zA-Z-0-9-\\_\\+\\.)]+@[(a-z-A-z)]+\\.[(a-zA-z)]{2,3}$");
    regMatcher   = regexPattern.matcher(emailAddress);
    if (regMatcher.matches()) {
        return "Valid Email Address";
    } else {
        return "Invalid Email Address";

public String validateMobileNumber(String mobileNumber) {
    regexPattern = Pattern.compile("^\\+[0-9]{2,3}+-[0-9]{10}$");
    regMatcher   = regexPattern.matcher(mobileNumber);
    if (regMatcher.matches()) {
        return "Valid Mobile Number";
    } else {
        return "Invalid Mobile Number";
Use Hdiv's validation

Risk Covered

Hdiv flow control minimizes vulnerable parts and for the remaining parts protection is applied (only) if a vulnerability is present

Although the defense strategies above are important, it depends on the developer to apply them or not. However, Hdiv validates automatically without any developer interaction.

Hdiv gets the required information directly from memory in real time, thanks to the integration points with web frameworks. After this analysis and due to its understanding of the semantics of each piece of data, Hdiv differentiates automatically between two types of data:

  • Data generated on the server side (non-editable data).
    90-95% of the information managed by a web application is non-editable data offered by the server which is presented by the application to be read/selected by the end user. This is the case with static information (text, images), and other components such as lists, buttons, links, etc.
  • Data generated on the client side (editable data).
    Only 5-10% of the information managed by a web application corresponds to data that is generated on the client side by the user, through text boxes (such as a search fields) or file input fields.

Hdiv makes an automatic security validation of the non-editable data received by a web application giving 100% reliability. This means that it is impossible to carry out any kind of attack based on non-editable data validated by Hdiv.

The validation carried out by Hdiv is done through a technique which compares the non-editable data received by the web application (in a request generated by a client), with the non-editable data that is offered in the screens by the web application server, to check that the server is not receiving any modified or additional data.

This simple and powerful mechanism is based on one of the security foundations (input data integrity validation) and offers total guaranties. Furthermore, this validation algorithm needs no updating and is not affected by the evolution of technology or attacks, providing a 100% effective long-term solution.

Hdiv includes a default group of validation rules that tries to avoid most common risks such as XSS and SQL Injection. It can be customized with hdiv-config.xml.

<!-- Accepted pattern within the application for all editable parameters
              (generated from textbox and textarea) -->
<hdiv:validation id="safeText">

<!-- It's necessary to define editable data validation list for the application-->
   <hdiv:validationRule url="/secure/.*"></hdiv:validationRule>
   <hdiv:validationRule url="/safetext/.*" enableDefaults="false">safeText</hdiv:validationRule>