Security issue - EL injection via DynamicContentStreamer

Components, Ajax Framework, Utilities and More.
pavel.horal
Posts: 12
Joined: 27 Apr 2011, 18:00

10 May 2011, 16:00

Hello,

there is an unfortunate severe security hole in the Primefaces implementation. Specifically the dynamic content feature implemented via DynamicContentStreamer phase listener allows for custom EL injection. You don't have to use dynamic content feature and still your application allows this attack.

Let me show you an example of the attack:

Assume Spring integrated application. By going to the folowing URL I am able to get the root application context:

Code: Select all

http://localhost:8080/myApp/whatever.jsf?primefacesDynamicContent=applicationScope.get(param.attr)&attr=org.springframework.web.context.WebApplicationContext.ROOT
More, assume single DAO bean called fooDao with method deleteById(int id). I can call this method as well:

Code: Select all

http://localhost:8080/myApp/whatever.jsf?primefacesDynamicContent=applicationScope.get(param.attr).getBean(param.bean).deleteById(param.id)&attr=org.springframework.web.context.WebApplicationContext.ROOT&bean=fooDao&id=1
Usually all security checks are done on service/business layer. By calling DAO directly I am able to bypass application security.

So this is only for application integrated with Spring? No. The modus operandi of DynamicContentStreamer is wrong at its core. Allowing for EL injection is bad in every possible scenario. This can not be fixed without completely changing Primefaces dynamic content handling.

Unfortunately we realized this at the late project stage. So what to do before the Primefaces guys will fix this? Well, we came up with a simple workaround - we will implement custom servlet filter. This filter will check for primefacesDynamicContent request parameter. If it is present, it will just check its value against pre-defined set of regular expressions. By doing this, we will control what expressions are being used.


I think this one should be reported as a bug. What do you think?

Thanks for any reply,
Pavel Horal

pavel.horal
Posts: 12
Joined: 27 Apr 2011, 18:00

17 May 2011, 15:22

One week and no reply. I will create the bug then.

User avatar
optimus.prime
Prime
Posts: 17433
Joined: 05 Jan 2009, 00:21
Location: Cybertron
Contact:

17 May 2011, 15:37

It is not a bug but an enhancement.

Regarding one week and no reply, this is community forum so there is no guarantee to get a response unlike in Enterprise Forum.

pavel.horal
Posts: 12
Joined: 27 Apr 2011, 18:00

19 May 2011, 16:25

Thank you for your reply.

I don't agree with you. It is a very severe security hole. It allows running injected Java server code. You might say that you can run EL only, but the newest EL with function calls opens whole new area of possibilities. Also it can be combined with XSRF which makes it even more severe.

I chose the topic name EL Injection on purpose. It is very similar to other attacks like SQL injection. Imagine using framework which handles user requests and directly communicates with database. If such framework allows for SQL injection, will you classify it as a severe security bug or as an enhancement?

Also the modus operandi allows for injecting EL at any page (as long as the request is handled by FacesServlet). That means even if I have a perfectly secured application I can still do the injection at my login page.

At the end all projects using PrimeFaces are affected (even the PrimeFaces showcase), even the commercial ones which post to the Enterprise Forum.

User avatar
Oleg
Expert Member
Posts: 3803
Joined: 02 Oct 2009, 09:41
Location: Germany, Black Forest

19 May 2011, 18:57

Hi pavel.horal,

Do you mean, PrimeFaces is not recommended in bank and other business projects using DynamicContentStreamer? Have you ever tried other component libraries (any kinds of EL injection there)?
PrimeFaces Cookbook (2. edition): http://ova2.github.io/primefaces-cookbook/ Learning Angular UI Development with PrimeNG: https://github.com/ova2/angular-develop ... th-primeng Blog: https://medium.com/@OlegVaraksin

pavel.horal
Posts: 12
Joined: 27 Apr 2011, 18:00

20 May 2011, 10:55

Do you mean, PrimeFaces is not recommended in bank and other business projects using PrimeFaces?
The problem I am describing do exist in PrimeFaces. As far as you are aware of it I think it is ok, because you can take countermeasures (like special servlet filter checking the expression being injected).
Also problem is that the DynamicContentStreamer is phase listener which is always enabled and can not be turned off. So there is a potential danger for developers who are not aware of this.

This issue should not prevent any enterprise deployment. PrimeFaces still is probably the best component library around ;).
Have you ever tried other component libraries (any kinds of EL injection there)?
I have to admit I don't have any deep experience with other libraries. To me the modus operandi of DynamicContentStreamer (accepting EL as a request parameter) feels not correct. I don't think other libraries are using this (maybe Optimus will correct me).

pavel.horal
Posts: 12
Joined: 27 Apr 2011, 18:00

23 May 2011, 17:22

I've found a critical exploit of this feature. I will write private message to Optimus with it.

The following code could be used to prevent the injection until this issue is resolved:

Code: Select all

/**
 * Servlet filter for protecting Primefaces' security hole in DynamicContentStreamer.
 * See http://primefaces.prime.com.tr/forum/viewtopic.php?f=3&t=10899 .
 *
 * @author pavel.horal(at)orchitech.cz
 */
public class ProtectingDynamicContentFilter implements Filter {

    private static final String DYNAMIC_CONTENT_PARAM = "primefacesDynamicContent";

    // XXX Hardcoded configuration for now
    private static final String[] ALLOWED_EXPRESSIONS = new String[] {
        "mediaBean.getMediaPreview(param.mediaId)",
        "mediaBean.getMediaImage(param.mediaId)"
    };

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // Nothing to initialize
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        String expression = request.getParameter(DYNAMIC_CONTENT_PARAM);
        if (expression != null) {
            checkContentExpression(expression);
        }
        chain.doFilter(request, response);
    }

    /**
     * Check dynamic content expression.
     * @param expression Expression to be checked. Never null.
     */
    private void checkContentExpression(String expression) {
        for (String allowedExpression : ALLOWED_EXPRESSIONS) {
            if (allowedExpression.equals(expression)) {
                return; // OK
            }
        }
        throw new IllegalArgumentException("Invalid content expression '" +
                expression + "'.");
    }

    @Override
    public void destroy() {
        // Nothing to destroy
    }

}
Last edited by pavel.horal on 24 May 2011, 10:08, edited 1 time in total.

pavel.horal
Posts: 12
Joined: 27 Apr 2011, 18:00

23 May 2011, 17:32

I was unable to find any contact to Optimus. Please contact me at my e-mail pavel.horal(at)orchitech.cz and I will send you more information.
Last edited by pavel.horal on 24 May 2011, 10:07, edited 1 time in total.

robert.m
Posts: 226
Joined: 07 Dec 2010, 22:52
Location: Salzburg/Austria

23 May 2011, 19:49

Hm.. I can't really reproduce this. I'm using Spring 3.0.5 with Tomcat 7, Mojarra 2.1.1 and PrimeFaces 3.0.M1.

When I'm trying the url "http://localhost:8080/app/faces/main.xh ... ntext.ROOT" I get an Exception:

Code: Select all

javax.servlet.ServletException: java.lang.NoSuchMethodException: com.sun.faces.context.ApplicationMap.get(java.lang.String)

pavel.horal
Posts: 12
Joined: 27 Apr 2011, 18:00

23 May 2011, 22:25

The exception you are getting is probably connected to the issue in EL implementation of some early versions of Tomcat 7. Just update to the latest stable Tomcat and it should work.
My configuration is - Tomcat 7.0.14, PrimeFaces 2.2.1, MyFaces 2.0.5, Spring 2.5.6 .

Btw. in my example I was calling get method on a map which is unnecessary. You can also modify your URL in this way:

Code: Select all

http://localhost:8080/app/faces/main.xhtml?primefacesDynamicContent=applicationScope[param.attr]&attr=org.springframework.web.context.WebApplicationContext.ROOT
Last edited by pavel.horal on 23 May 2011, 23:50, edited 2 times in total.

Post Reply
  • Information
  • Who is online

    Users browsing this forum: Baidu [Spider], Bing [Bot], Google [Bot], Yahoo [Bot] and 11 guests