History | Log In     View a printable version of the current page. Get help!  
Issue Details (XML | Word)

Key: JBSEAM-2099
Type: Patch Patch
Status: Closed Closed
Resolution: Done
Priority: Critical Critical
Assignee: Norman Richards
Reporter: Diego Ballve
Votes: 1
Watchers: 2
Operations

If you were logged in you would be able to see more operations.
Seam

Support protection against SQL injection in Query order parameter

Created: 13/Oct/07 06:35 AM   Updated: 28/Apr/08 11:30 AM
Component/s: Framework
Affects Version/s: 2.0.0.CR2
Fix Version/s: 2.0.0.CR3

Original Estimate: Unknown Remaining Estimate: Unknown Time Spent: Unknown
File Attachments: 1. Text File Query.diff (3 kb)

Issue Links:
Duplicate
 
This issue is duplicated by:
JBSEAM-2084 (security) EJB-QL injection in org.jb... Major Closed
Related
This issue related:
JBSEAM-2393 Query order by regexp fails when usin... Major Closed
JBSEAM-2931 Improve the exception thrown by an in... Minor Closed
This issue is related to:
JBSEAM-2169 order by RAND() broken by http://jira... Major Closed

JBoss Forum Reference: http://www.jboss.com/index.html?module=bb&op=viewtopic&t=119810


 Description  « Hide
From http://www.jboss.com/index.html?module=bb&op=viewtopic&t=119810

The 'order' parameter gets directly concatenaded to the query.. that would allow anything to get injected in the query, possibly resulting in a security threat. This patch gives the developer extending framework Query the chance to limit the acceptable order properties.

 All   Comments   Work Log   Change History   Subversion Commits      Sort Order:
Matt Drees [13/Oct/07 01:41 PM]
It looks like the patch requires order clauses to contain either ASC or DESC; I think it'd be good to make the direction optional.

Diego Ballve [13/Oct/07 03:19 PM]
I did not realize it could be omitted. The check for parts[1] becomes:

valid &= ("".equals(parts[1]) || "ASC".equalsIgnoreCase(parts[1]) || "DESC".equalsIgnoreCase(parts[1]));

Felix Ho?feld [14/Oct/07 07:07 AM]
IMHO this will not do. I may want to have more complex order clauses containing more than one property or even properties of child objects like:

SELECT e FROM Employee e ORDER BY e.department.name, e.lastname, e.firstname

I think this will be a common use case. If the order by statement is not defined by a single property name the patch will not work. Besides it requires that the query object is extended, so for any users using an xml declaration (and I think this is the vast majority) it will be useless. Finally it breaks backward compatibility: It would simply blow up all existing applications that use the order by parameter even if it is hardcoded into the xml and not an el expression (and that are therefore not even threatened).

As an alternative I suggest running the order against a simple regex, e.g.

if (! order.matches("^[\\w\\s\\.,]$"))
           throw new IllegalArgumentException("Invalid order by clause in hql statement: " + order);

I don't know HQL syntax well enough: In SQL this would still allow appending queries using UNION but AFAIK UNION is not supported by HQL or JPQL.

BTW I think this bug definitely warants a backport of the final patch and an "official" advisory.



Pete Muir [14/Oct/07 07:31 AM]
Yes, I don't think Diego's solution is correct.

Diego Ballve [14/Oct/07 08:31 AM]
Felix, I agree this is getting more complex than ideal, but If you want more complex order you have more to change than just validating the order param. But lets go through the comments:

First, backward compatibility is not broken. If list of valid params is not set, any is still acceptable.

Second, I have not been using xml to set up queries, i needed more than what xml could offer.. but I agree It would be desirable to be able to set valid props from xml.

Third:

- more than one property: still simple, the check could verify that all props are in the valid list. And actually, I'm splitting the string on spaces, not commas.. 'e.lastname,e.firstname' would be seen as 1 prop.. if defined as valid, it would pass. ;)

- order by child object: we actually use that, the trick is the property must appear in the select.. the way we solved it, your query would become:

SELECT e, e.department.name as depName FROM Employee e ORDER BY e.department.name

Besides, you need to say e.department.name is a valid order parameter and you need getResultList() to process the resulting.. if it is List<Object[]> then return a new List containing item[0].. Not pretty but did the trick.

Not to loose focus, the root of the problem is not to allow anything coming from a mapped requestParam.order to make it to the HQL query, unchecked. If you can restrict what fields can be exposed to web user, even better.

Norman Richards [15/Oct/07 03:41 PM]
Thanks for catching this. After examining the issue, I implemented something very similar to Felix's suggestion to filter out sql injection hacks without imposing any other constraints on the parameter.

The use of the order attribute as a direct request parameter is inherently flawed. We should change seam-gen, and perhaps the Query class itself, to support a better nothing of sortable columns than passing text strings that get appended to the query. What we are doing now is bad, and we should NOT be encouraging people to do it like that.