powered by Jive Software

Openfire security vulnerabilities

Since we run FastPath for online tech support we couldn’t reject access to the admin site. This is what we’re trying as a temporary workaround. In the web.xml:

 login.jsp,index.jsp?logout=true

Notice we’ve taken out the other exclusions including “setup/setup-” which I’m hoping is the main culprit. I’ve tried to run the exploit against login.jsp, but can’t make it work.

Can anyone coughJivecough verify if this is a sufficient workaround?

Since we run FastPath for online tech support we couldn’t reject access to the admin site. This is what we’re trying as a temporary workaround. In the web.xml:

 login.jsp,index.jsp?logout=true

Notice we’ve taken out the other exclusions including “setup/setup-” which I’m hoping is the main culprit. I’ve tried to run the exploit against login.jsp, but can’t make it work.

Can anyone coughJivecough verify if this is a sufficient workaround?

Since we run FastPath for online tech support we couldn’t reject access to the admin site. This is what we’re trying as a temporary workaround. In the web.xml:

<param-value>
    login.jsp,index.jsp?logout=true
</param-value> <!--
<param-value>
    login.jsp,index.jsp?logout=true,setup/index.jsp,setup/setup-,.gif,.png,error-serverdown.jsp,setup/clears
pace-integration-prelogin.jsp
</param-value>
-->

Notice we’ve taken out the other exclusions including “setup/setup-” which I’m hoping is the main culprit. I’ve tried to run the exploit against login.jsp, but can’t make it work.

Can anyone coughJivecough verify if this is a sufficient workaround?

I apologize for the replyarrhea… Clearspace gave me an error each time I tried to post without mentioning the post actually made it in. Feel free to delete the other 2 posts.

@singerkd:

Tried something like this?

http://www.foo.bar:9090/login.jsp?url=setup/setup-/../../log.jsp?log=info&mode=asc&lines=All

Since we run FastPath for online tech support we couldn’t reject access to the admin site
What about using an proxy? E.g. if you have an Apache running on the same machine, you could use mod_rewrite to do something like this:

RewriteCond %{REQUEST_URI} ^/fastpath
RewriteRule ^/(.*) http://localhost:9090/plugins/$1 [P]

I’m not sure how fastpath works, so not need to figure out yourself how to write the rule. In any case, the benefit is the nicer URL

Hello!

If the history timeline of this document is really true, than this is a sad sad story.

Considering that Jive did not move for MONTHS means they really dont care any more about this project.

Starry

Created issue JM-1489.

I agree. I really am beginning to quest why I still haunt this community. There is no signs of life from Jive, except empty promises.

Hi Starry,

Looks like we are witnessing open source Darwinism in action Maybe its time we take the better parts of Openfire and see if they fit with Tigase? I dunno, this all is so depressing…

daryl

I think vulnerability #1 should be an easy fix:

*org.jivesoftware.admin.AuthCheckFilter#*doFilter(ServletRequest, ServletResponse, FilterChain)

replace line

String url = request.getRequestURL().toString();

with line

String url = request.getServletPath();

I cannot confirm the problem with that fix. However, I’m not sure if this is really so simple.

Is it an good idea that the filter does only checks if the url contains the exclude string? Would be a check with startsWith(…) an better idea?

Things that do not longer work:

echo "GET /setup/setup-/../../log.jsp?log=info&mode=asc&lines=All" | nc localhost 9090
echo "GET /log.jsp;/setup/setup-?log=info&mode=asc&lines=All" | nc localhost 9090

Message was edited by: Coolcat

Using getServletPath() looks like a good and easy solution.

I think it is not sufficient but is a very good start. Instead of using startsWith() we could use regular expressions, I think this is the most flexible solution. The performance impact is rather slow compared to the increased flexibility and performance is not a #1 issue on the admin console.

Another problem we have is that everything containing/ending with .png is currently excluded from access control. This includes URLs like

http://localost:9090/plugins/monitoring/graph/.png?stat=packet_count&timeperiod= last60minutes&width=700&height=250&format=png

I guess we can fix this by explicitly allowing access to just the required images and/or putting all of them into the images directory and allowing access to it.

The problem area isn’t necessarily limited to the list of excludes that is provided in web.xml

The current AuthCheckFilter implementation allows the list of excludes to be changed at runtime. The addExclude(String) method allows you to do this. Custom code (such as plugins) can add new vulnerabilities to your system this way.

Another problem we have is that everything containing/ending with .png
is currently excluded from access control. This includes URLs like (…)
No, this does not work, I tried that.

getServletPath() does not contain the query string (behind ‘?’) and does also not contain the parameter string (behind ‘;’)

http://java.sun.com/javaee/5/docs/api/javax/servlet/http/HttpServletRequest.html #getServletPath()

This path starts with a “/” character and includes either the servlet name or a path to the servlet, but does not include any extra path information or a query string.

@regex:

Hm, regular expressions should be only used where they are really needed. Also this would require changes to many plugins.

Message was edited by: Coolcat

As I see it, the main contributor to the problem is the simplistic way to see if the URL matches any excludes:

for (String exclude : excludes) {
    if (url.indexOf(exclude) > -1) {
        doExclude = true;
        break;
    }
}

As Coolcat said, regexes should be avoided if possible. I think that goes for any wildcard-like mechanism. Wouldn’t we be a lot more secure if we start implementing exact matching (instead of partial matching) and update the web.xml? Will doing that (based on the getServletPath() output, instead of the getRequestURL().toString() output as suggested before) solve our problem? Will it introduce new ones?

Can I ask a stupid question? Why even have excludes?

Will be a better idea to have a hardcoded known password to perform setup, bootstrap openfire and then always use the database password for all subsequent access. The only exception will be plugins that programitically call the exclude feature like the presence plugin.

I can agree with that. In any case, the excludes needed for setup should be removed after the setup has been completed.

However, we should try to preserve the functionality, as some third party products (such as custom plugins) rely on it. If we now simply disable the possiblilty to exclude something, without offering an alternative, we’ll end up upsetting a number of Openfire admins.

I thought about exact matches. I think most plugins will not need any changes since there is only one single exclude.

String url = request.getServletPath();
boolean doExclude = excludes.contains(url);

This is also a performance improvement since it does now make sense to use an HashSet…

However, I think this would require also the following changes:

public static void addExclude(String exclude) {
        excludes.add("/plugins/" + exclude);
    } public static void removeExclude(String exclude) {
        excludes.remove("/plugins/" + exclude);
}

All official plugins should confirm with that. Methods addExclude() and removeExclude() are not used by Openfire itself.

Message was edited by: Coolcat

Hm, it’s not that easy…currently there is an exclude for index.jsp?logout=true

getServletPath() does turncate the query string and it’s not a good idea to exclude index.php itself.

I think we can just remove the exclude for index.jsp?logout=true

The logout parameter in index.jsp is handled like this:

<% // Simple logout code
if (“true”.equals(request.getParameter(“logout”))) {
session.removeAttribute(“jive.admin.authToken”);
response.sendRedirect(“index.jsp”);
return;
}
%>

This will still work if the user is authenticated.

If the user is not authenticated he will be directed to the login page by the AuthFilter. This also happens right now as index.jsp?logout=true redirects to index.jsp which requires authentication. There is no need to remove the authToken from the session if the user is not authenticated.

We get an directory listing for

http://localhost:9090/images/

http://localhost:9090/style/

http://localhost:9090/js/

and *.css, *.js and image files can be accessed without exclusion.

AuthCheck is only applied to *.jsp files.
We should apply the filter to everything:

<filter-mapping>
        <filter-name>AuthCheck</filter-name>
        <url-pattern>/*</url-pattern>
</filter-mapping>

and then create a whitelist for everything that is requried for login. For the last two I’m not sure if this is required.

<filter>
        <filter-name>AuthCheck</filter-name>
        <filter-class>org.jivesoftware.admin.AuthCheckFilter</filter-class>
        <init-param>
            <param-name>excludes</param-name>
            <param-value>
                /login.jsp,
                /style/global.css,
                /style/login.css,
                /images/login_logo.gif,
                /images/error-16x16.gif,
                /images/jive-login-form-bg-gray.gif,
                /images/jive-login-bg.gif,
                /error-serverdown.jsp,
                /setup/clearspace-integration-prelogin.jsp
            </param-value>
        </init-param>
    </filter>

For AuthCheckFilter we take the following, so setup will work.

String srvpath = request.getServletPath();
boolean doExclude = XMPPServer.getInstance().isSetupMode() || excludes.contains(srvpath);

However, for some strage reason setup does not work for me, but it is possible that is some other problem not related with that change.

java.lang.NullPointerException
     at org.jivesoftware.openfire.admin.index_jsp._jspService(index_jsp.java:131)
     at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
     at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
        (...)

Message was edited by: Coolcat