Openfire: Multiple Critical Vulnerabilities

Six months ago I reported a few serious vulnerabilities within the famous Jabber server Openfire to its vendor Jive Software. Since these issues could potentially even be used by an attacker to execute code on the operating system level and the vendor did not make any efforts to get these issues fixed, I decided to release my advisory with full technical details to the general public.

Since there is no vendor-patch available at the moment, every Openfire installation should be secured manually:
The simplest and most recommended solution is to deactivate access to the entire admin interface. This can for example be achieved by blocking the according ports (tcp/9090 & tcp/9091 by default) with a firewall. Subsequent communication to the admin interface can be done via SSL tunnels.

The sections below outline the most critical findings. Complete details could be extracted from the related advisory: AKADV2008-001-v1.0.

Bypass Authentication
Authentication to the Openfire admin interface is secured by a filter in the Tomcat application server. This filter guarantees that access to the admin interface is only granted to authenticated users. Otherwise they get redirected to a login page.
A design error in Openfire enables access to internal functions without the need for admin user credentials. The deployment descriptor (web.xml) configures some exclude values for the AuthCheckFilter.

When a request URL contains one of these Exclude-Strings the auth check mechanism can be totally circumvented. This was considered necessary for the initial setup process or the presence plugin.

Following POC demonstrates how an attacker could access internal functions by manipulating the URL providing one of these excludes(/setup/setup-/../../):

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

SQL injection despite using Prepared Statements
In the meantime many developers have noted (or got obligated by secure coding guidelines) that the usage of prepared statements could prevent SQL injection. But in order to successfully prevent such attacks, prepared statements have to be used the right way.

During many static source code analyses which I conducted the last months, I was often confronted with the following problem: Strings were dynamically concatenated before there were passed to the prepared statement object. The proper set()-methods to bind the strings to the prepared statement were not used. In the scenario outlined sql injection is still possible despite using prepared statements.

The openfire case:

Untrusted user data enters the application
String type = ParamUtils.getParameter(request, "type");

A function processes this user input (SQLCondition) and constructs a SQL statement:
String sql = "SELECT * FROM sipPhoneLog";
sql = ... + " WHERE " + SQLCondition;

That statement is passed over to a prepared statement.
return con.prepareStatement(sql);

Einen Kommentar schreiben