Help

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

Injection occurs when user-supplied data is sent to an interpreter as part of a command or query. Attackers trick the interpreter into executing unintended commands via supplying specially crafted data. Injection flaws allow attackers to create, read, update, or delete any arbitrary data available to the application. In the worst case scenario, these flaws allow an attacker to completely compromise the application and the underlying systems, even bypassing deeply nested firewalled environments.

Consider how the parameter is appended to the following SQL command:

String sqlCommand = "select * from MYTABLE where " + parameter;

If the value of the parameter has been provided by a user or potential attacker, and it has not been filtered for malicious characters, the attacker could delete data by providing the parameter value true; delete from MYTABLE. The select command is terminated early and a new malicious delete command appended.

Cause

Systems affected by injection flaws typically pass unfiltered user input directly into subsystems. Careless use of string concatenation to build commands is often a source of an injection vulnerability. Note that many (sub)systems might be affected and that many types of injections into commands are possible: SQL, LDAP, XPath, XSLT, HTML, XML, OS command, and so on.

Exploitability

Attackers find vulnerable systems by analyzing client-server communication. If, for example, a web application exposes and utilizes parameters and values that resemble SQL commands, the attacker can assume that the given value is directly passed from client, to server, to database without any filtering. If you see an URL such as http://example.com/myaction.do?command=SELECT&table=MYTABLE&column=MYCOLUMN&value=1234, chances are good that the backend will use these parameters to concatenate a command string and execute it directly.

Another source for attackers are verbose error messages. If they can make the application fail and print an error message, too much information about the error will present them with an attack vector. For example, printing method names and class names in a stack trace that would indicate command string concatenation is a clear hint for attackers that the system might be vulnerable to an injection attack.

Possible Remedies

Protection against injection flaws depends on the command (sub)system you wish to protect. The most commonly used system is a SQL-based database, so constructing SQL commands deserves attention. You can use string concatenation to construct SQL statements. However, you should not concatenate any value that has been provided by a user if the software. Most, if not all SQL APIs offer a feature called /parameter binding/ that allows you to safely set user inputted values on a SQL command.

In JDBC, you can call methods such as setString(1, unfilteredValue) on a PreparedStatement. In the SQL command this replaces the value for placeholder 1, and the JDBC driver will filter the given value and escape any potentially dangerous characters - such as semicolons, quotes, etc.

Generally, you should never concatenate user input data to build commands of any kind for any interpreter. If you do so, utmost care must be taken and data must be checked and validated thoroughly and any malicious content must be removed or escaped.

Considerations for Seam framework users

The most commonly used subsystem and command interpreter used with the Seam framework is a SQL database. Again, most users would utilize an Object-Relational Mapping software such as Hibernate to access a SQL database. Direct JDBC access is certainly also possible, and the aforementioned precautions apply.

Protecting from injection through Hibernate

Hibernate offers a Query API that allows the safe and unified binding of parameters, which is very similar to JDBC but somewhat easier to use. The same is true for the JPA javax.persistence.Query API. See the Query API documentation for more information. We recommend named parameter binding instead of positional, as it is easier to maintain in most cases.

Filtering input with EntityQuery

The Seam framework offers a simple controller and query solution for rapidly building database application. One of these components, the EntityQuery, allows developers to quickly build database reporting pages. This feature includes smart filtering of user input.

Consider the following form and result list in an XHTML template:

<h:form>
    <div>Username: <h:inputText value="#{exampleUser.username}"/></div>
    <div><h:commandButton value="Search"/></div>
</h:form>

<h:dataTable value="#{userList.resultList}" var="u">
    <h:column>
        <h:outputText value="#{u.fullname}"/>
    </h:column>
</h:dataTable>

The result datatable shows a list of User instances. The input field allows you to filter the result list by username. You do not need to write any code for this with the Seam application framework and EntityQuery, just declare the components and wire them together:

<framework:entity-query 
    name="userList"
    ejbql="select u from User u"
    order="username"
    max-results="20">
    <framework:restrictions>
       <value>lower(username) like lower( concat(#{exampleUser.username},'%') )</value>
    </framework:restrictions>
</framework:entity-query>

<component name="exampleUser" class="my.model.User"/>

When the search form is submitted, the inputted value is assigned to the exampleUser.username variable. This value is then injected into the SQL query restriction. However, although the declaration would imply that this is a simple string concatenation, Seam is using JDBC/Hibernate/JPA parameter binding in the background. If logging is enabled, you'd see the following Hibernate statement being executed:

DEBUG [org.hibernate.SQL] /* select u from User u where lower(username) like lower( concat(:el1,'%') ) order by username */ 

This HQL statement will now be translated into SQL and the :el1 named parameter is bound from the value of the expression #{exampleUser.username}. The JDBC driver will filter any dangerous characters.

Further Reading

http://www.owasp.org/index.php/Top_10_2007-A2