An Injection attack is the submission of malicious code or commands that could be interpreted and executed by the remote application.
Injection is actually first on OWASP Top Ten list, and includes a wide range of different subtypes depending on whether the nature of command or language.
Taken together, injection attacks are a huge percentage of the serious application security risk. Many organizations have poorly thought through security controls in place to prevent injection attacks. — OWASP, about the injection attacks
In this article we will focus our attention on two particular types of injection:
- SQL Injection (SQLi) – when the injection of SQL commands occours
- Cross-Site Scripting (XSS) – when the injection of a browser-side script occours
then we will see how Liferay Portal solutions helps you to prevent injection attacks, keeping up the security level.
Liferay Portal Security
Liferay follows the OWASP Top 10 and CWE/SANS Top 25 lists to ensure the highest level of protection against several known attacks.
Here are some kind of attacks included in both OWASP Top Ten and CWE/SANS Top 25 and for which Liferay offers the highest level of protection against:
- Injection
- Cross-Site Request Forgery (CSRF)
- Broken Access Control
- Unrestricted file upload
- Clickjacking
- Path traversal
- ...and many others.
Liferay takes care about security, in both the community (CE) and the enterprise (DXP) editions, keeping always up-to-date the known vulnerabilities list, and also having their own security statement.
SQL Injection (SQLi)
SQL Injection is the injection of SQL commands (or queries) as untrusted user input data from client-side.
Depending on user privileges on target database, the attacker could:
- insert, update or delete rows on existing tables
- read sensitive data from tables (select)
- drop tables
- execute administration commands, such as perform the shutdown getting also a DoS attack
One of the benefits using Liferay is that the persistence layer generated by the Service Builder is built to prevent SQL Injection attacks (read more).
However, when the default solution provided by the Service Builder is not enough, Liferay helps you to maintain the highest level of protection against SQL Injection attacks even defining customized finders. Nevertheless, you should pay attention when implementing a custom Finder and follow the instructions provided by the official Liferay documentation.
In particular:
each custom query should have its own
<custom-sql>
element into custom-sql/default.xml and the sql command in a<![CDATA[...]]>
section, without terminating semi-colon;the query parameters should always set using
QueryPos
which performs escaping. Validation of untrusted data is mandatory as well as order-by column names from request parameters.
Strict validation of untrusted data coming from HTTP-request parameters is the key to prevent the SQL injection.
In the following example we will show why the order-by
column names should
never came directly from the request without prior validation, and how an injection attack
on the order-by clause can significatively reduce the total attempts needed
to guess a column value.
Suppose we have extended our model adding a new Vendor entity, introducing a vulnerability on the finder implementation:
the safe version will make use of the BasePersistenceImpl.appendOrderByComparator()
:
with such vulnerability, for instance, the attacker could try to use the
SearchContainer's orderByCol
parameter on the vendors search page,
to inject the following sql command by the form submit action:
_portletName_INSTANCE_instanceId_orderByCol=
In this way, the attacker can guess the i-th digit of the userId having
test@liferay.com
as e-mail address just verifying the results ordering in page.
Each injection attempt will change the results order, whether the exact digit
has guessed or not. Supposing userIds of five digits, the attacker can easily
guess the userId in (5 * 9) - 1 = 44 attempts on the worst case, when a
brute-force attack can require 9 * 10^4 attempts.
The same attack could also be used to guess the screen-name or the encrypted
password, but this will require more attempts.
Some useful tips to protect against SQL Injection attacks
Liferay ServiceBuilder helps you to keep up the security level, but pay attention providing custom Finder implementations: when using the
OrderByComparator
always perform a strict validation for column names in order-by clauses.Keep in mind that vulnerability to SQL Injection is also an input validation problem: in order to prevent the injection attack, string concatenation should be avoided expecially on untrusted data from the request without prior validation.
Make use of query parameters, because the output escaping will neutralize the injection attack.
Cross-Site Scripting (XSS)
Cross-site scripting (XSS) is also known as “Improper neutralization of input during web page generation” and is one of the most common attacks according to OWASP Top 10 and CWE/SANS Top 25.
According to the OWASP reclassification, XSS attacks can be classified in two main types:
Server XSS: when untrusted user input data is included on server response
Client XSS: when untrusted user input data is added to DOM or evaluated through unsafe JavaScript call
Another possibile classification of XSS attacks is about data persistency:
Stored (Persistent or Type-I): when untrusted user input data is stored on the target server persistent storage like database
Reflected (Non-Persistent or Type-II): when untrusted user input data is returned in server response without being permanently stored.
Liferay Portal is built to prevent XSS attacks
When you are developing new portlet component, you should make use of the
standard Liferay frontend taglib.
The taglib elements (such as <aui: >
, <liferay-ui: >
, <clay: >
) are safe
because they always perform output escaping where needed and in the right way,
so they will neutralize almost any kind of XSS attack.
Liferay's HtmlUtil is the right way to safely perform output escaping.
Now let's show some examples of Server XSS attacks...
Reflected Server XSS Attack - example
- 💻 CLIENT: malicious code is submitted via the HTTP-request parameters or body
firstName=<script>alert('XSS!')</script>
- 🌍 SERVER: dynamically generated response includes untrusted data (because missing HTML-escaping):
<p> Hello, <%= firstName %> </p>
- 💻 CLIENT: the browser shows the response page executing the injected malicious code
<p>
Hello,
<script>
alert("XSS!");
</script>
</p>
Stored Server XSS Attack - example
- 💻 CLIENT: malicious code is submitted via the HTTP-request parameters or body
firstName=';alert(document.cookie);'
- 🌍 SERVER: the model entity is updated on persistence layer with untrusted data:
...
customer.setFirstName(firstName);
_customerService.updateCustomer(customer);
- 🌍 SERVER: dynamically generated response includes stored untrusted data, exposing the application to an XSS vulnerability because it misses the JS-escaping:
<aui:script>
var firstName = '<%= c.getFirstName() %>';
...
</aui:script>
- 💻 CLIENT: the browser shows the response page executing the injected malicious code, which now is also stored, even after a page refresh.
<script>
var firstName = '';alert(document.cookie);'';
...
<script>
XSS attacks could be neutralized performing output escaping:
every time you dynamically set an attribute value or content in a raw-HTML element from an untrusted source (HTTP-request parameters);
when using Java variables
<%= ... %>
on jsp inside<script>
elements;when defining customized taglibs.
Here are some examples of HtmlUtil usage:
Some useful tips to protect against XSS attacks
untrusted data should always be validated and sanitized before stored or processed for the output response. Enums or constants could be used for values mapping when the input parameters are strings;
use Liferay frontend taglibs, and HtmlUtil to perform output escaping. Escaping the output values in dynamic response page will neutralize injected code as well as
<script>
elements or JavaScript snippets, preventing the execution by the web-browser;be aware of custom JavaScript code which directly modifies DOM nodes. Unsafe JavaScript code could reveal in a vulnerability to Client XSS Attacks.
Conclusion
Injection is one of the most common attack on web applications. Defense strategies against Injection attacks are:
prevention by validation of untrusted data before it could be stored or processed for the output response;
neutralization by output escaping or sanitization.
Liferay ensures the highest security level in both the community (CE) and the enterprise (DXP) editions, and supports the developer to keep the security level high even when providing new solutions.