Spring Framework Security Vulnerability Part 2

I’ve already talked about CVE-2010-1622 and what SpringSource could have done better when dealing with this security issue.

Today I want to focus on what you as a developer or system administrator can learn from the bug.

What can developers learn from CVE-2010-1622?

The exploit requires manipulating the class loader property so that it will download code from an external site. So you can prevent the attack by disallowing modifications of the class loader and by disallowing your application to download and run code from external sites.

Be explicit! Explicitly allow binding of certain properties. This prevents the exploit from working as there is no valid use case that requires access to the class property. Explicitly whitelisting properties also makes sure users cannot change the id of the object bound to a form or altering data that is managed internally like “date of creation” or “last modified by” properties.

To prevent code from external sites being downloaded and executed you can make sure your applications behaves well when run with a security manager. While this is a common concept used for client side code like applets it is far less common for server side applications. Tomcat usually works well with a security manager though it is not enabled by default. Making sure you appplications works with a security manager is also a variant of being explicit: You explicitly grant certain privileges to your code bases and disallow everything else that might be abused by attackers.

What can system administrators learn from CVE-2010-1622?

Your applications should run in a demilitarized zone where they are unable to access the internet or your intranet. If you really need access to external resources use a proxy server and white list the URLs your application needs to contact. Doing so prevents attackers from making your application download external code.

If your applications are built in a way that they work with a security manager use it! For Tomcat there is a short Howto available.

Spring Framework Security Vulnerability Part 1


Spring Source recently published CVE-2010-1622. The advisory describes a vulnerability that affects Spring Framework prior to 3.0.3 and allows attackers to execute arbitrary code.

What could SpringSource have done better?

When Spring Source announced the release of 3.0.3 they reported to have fixed “more than a hundred minor issues” — no indication of the security fix. This could be understandable as they have released the fix 2 days prior to publishing the advisory. I do not understand why they did not announce it later however. The advisory was published as silently as possible although the vulnerability is rated critical, can be exploited remotely and probably affects a large number of applications.

I would have preferred receiving the security advisory through the usual channels used for announcements in addition to the security team page.

Having a look at cve.mitre.org reveals another interesting fact. The CVE id was assigned on April, 29th. That is almost 2 months before the advisory was published. The bug was fixed on May, 27th.

Why does it take more than 4 weeks for a 3 line fix? Why does it take almost 3 additional weeks after the fix to announce the vulnerability?

I would have preferred a priority fix as soon as possible after discovery and a release following short time after that.

Finally SpringSource dicided not to provide a fixed release for dm Server, a product based on Spring Framework, which is also vulnerable. Users are advised to manually patch it instead. SpringSource also continues to provide the vulnerable dm Server 2.0.2 for download without any warning.

I would have preferred to receive a fixed release of dm Server instead of seeing SpringSource continue to ship products containing known security issues.

What can you learn from CVE-2010-1622?

I will follow up with the lessons learned for application developers and system administrators in the next days. Stay tuned.

There is also an interesting analysis of the issue at blog.o0o.nu.

Spring’s New Maintenance Policy

SpringSource, the company behind the popular Spring Framework has announced a new maintenance policy: SpringSource Enterprise Maintenance Policy, effective September 2008.
After a lot of discussion in the community they have now added a Frequently Asked Questions document.

Spring Framework was originally created to overcome the limitations of Enterprise Java Beans (version 1 and 2) and make it easier to build J2EE applications. It has introduced dependency injection to a broad audience and changed the way many enterprise applications are built today. For many years it has been a vendor independant Open Source project available under the Apache Software License. Some time ago the creators of Spring Framework started their own company, received venture capital and things started to change. They’ve added new products like a new application server, bought Covalent and are looking for opportunities to gain some money.

In contrast to their new proprietary products which require a commercial license there has not been a real opportunity to make money from SpringFramework itself. Community support was fine, regular maintenance updates fixed the issues that were discovered and there was no need for commercial support. The recent announcement of their new maintenance policy seems to be their answer to that. They try to create a need for their support offerings. So the new policy basically states:

  • Free maintenance updates will only be available for three months after a major release
  • Maintenance releases will be available to paying customers under a commercial license for three years after a major release
  • Bug fixes will be commited to a maintenance branch but minor releases will not be tagged after the three month period so the community will not know which versions are stable

Though the major releases will remain Open Source the bug free minor versions (three months later) will not. Spring Framework 2.0 was released in October 2006, Spring Framework 2.5 in November 2007 which means that the community will be without minor releases for more than 9 months if the frequency of their releases remains similar.

Sure, you can always build from the sources but this looks like a bad idea given that SpringSource refuses to tag consistent and tested versions.

I can understand the desire to make cash from SpringFramework but I am not sure this way will be successful. For me the products of SpringSource have lost their strong advantage of being vendor independant and fully Open Source. Upcoming projects will have to consider this fact and investigate alternatives.

Update 2008-10-08

SpringSource has listened to the community and updated its maintenance policy: A Question of Balance: Tuning the Maintenance Policy. They’ve dropped the 3 month window and will provide community releases from trunk for each version of Spring while it remains the trunk or until the next version is stable.

References

The specified call count is not a number: null

Today we had an interesting bug in a small web application developed for a customer in the financial industry. The application is based on the Spring Framework, secured by Acegi Security and makes heavy use of AJAX (powered by DWR).

Everything went fine while testing with different browsers from Firefox to Safari and Internet Explorer in different versions. Finally we have started testing in the target environment – well locked down and without support for ActiveX controls from untrusted sites. IE6 needs ActiveX for its implementation of XMLHttpRequest (XHR) – the heart of AJAX. If XHR is not available DWR automatically switches to using IFrames to emulate XHR. This usually works well and has already been used in the previous version. Nevertheless the application just didn’t work: Every remote call failed with a not so user friendly error message: “The specified call count is not a number: null”.

Remote debugging of Tomcat showed that DWR is trying the read the request data using req.getInputStream() to parse it. When using IFrames reading from the request’s input stream fails immediately and returns null, when using XHR it works fine. The main difference is the content type of the requests “application/x-www-form-urlencoded” for IFrames and “text/plain” for XHR. As IFrames do work without Acegi but fail with the Acegi filters in place I guess Acegi does mess with the requests when it wraps them in its SavedRequestAwareWrapper.

I didn’t have the time to further track it down, but I created a small workaround that falls back to using req.getParameter() if reading the stream fails.

The following snippet shows the modification made to DWR’s ParseUtil.java:

in = new BufferedReader(new InputStreamReader(req.getInputStream()));

while (true)
{
    String line = in.readLine();

    if (line == null)
    {
        if (paramMap.isEmpty())
        {
            Enumeration nameEnum = req.getParameterNames();
            while(nameEnum.hasMoreElements())
            {
                String name = (String) nameEnum.nextElement();
                paramMap.put(name, req.getParameter(name));
            }
        }
        break;
    }
...

And who is to blame? Well, as with many interesting problems that’s hard to decide. It’s just a combination of multiple pieces of software mixed with environment constraints. I guess it’s something that just happens and reminds us that testing is not useless.

Update 2008-02-22

Joe has just released DWR 2.0.3 that includes a fix for this issue.

Will the BEA Acquisition Push Spring Framework?


BEA is well known for its J2EE application server Weblogic and recently extended its product line to a SOA stack branded Liquid. Oracle has its own J2EE compontents mainly derived from Orion Server and branded as OC4J. They also have a SOA stack called Fusion.

So you might ask what the future of these products will be.


Oracle already acquired three different business application suites in the past: J. D. Edwards, PeopleSoft and Siebel. Does it make sense to develop three different product lines of business application suites and at least two different product lines of Java EE and SOA middleware? Probably not.

This uncertain future may make companies reevaluate their current technology stack for middleware applications. They will notice that there is an alternative beyond the IBM Websphere dinosaur and JBoss which is now RedHat. The alternative is Apache Tomcat and Spring Framework mixed with some Terracotta if you need distributed shared data.

Spring basically allows you to assemble your own application server. Transaction management, security, remoting, O/R mapping, clustering – just add what you need when you need it.
Basically there is not much left where Spring does not offer a proven solution. On the other hand the features where commercial J2EE servers have been strong in the past (compared to other stacks) are becoming less important:

  • EJB remoting will be replaced by web services
  • entity bean style O/R mapping has already been replaced by Hibernate (where EJB3 tries to catch on)
  • load distribution and fail-over is easy in a world of HTTP or JMS based web services
  • clustering of data is less important in the stateless world of services

In the end the uncertainty caused by Oracle’s acquisition of BEA could very well further increase the growth of Spring and the open source components it makes so easy to combine.

Spring MVC: Null or an Empty String?

Spring MVC converts your empty fields to an empty string instead of null by default. This is often not what you want when you persist your entities. The reason for this behavior is that Spring MVC uses Java’s default property editor for strings when binding the request to your domain object.

A better alternative is to use the StringTrimmerEditor
that removes surrounding white space from the field values and optionally converts an empty value to null instead of an empty string.

Just override the initBinder method of your SimpleFormController:

protected void initBinder(HttpServletRequest request,
  ServletRequestDataBinder binder) throws Exception
{
  // bind empty strings as null
  binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
}

References

Modular Spring Configuration

When assembling applications from a set of reusable compoenents that use the Spring Framework to wire their beans you will end up with a whole bunch of Spring configuration snippets spread around the JAR files containing your components.

Components should be self-contained so everything belonging to the component (including configuration) should be part of it. Ideally assembling the application would just mean dropping an additional component JAR file into the classpath (i.e. adding dependency to its Maven POM) and using the beans it exposes.

A simple convention makes this quite easy: Just put a spring.xml file into the META-INF directory of your components and declare the application context in the application’s web.xml like this:

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
    classpath*:META-INF/spring.xml
    /WEB-INF/applicationContext.xml
  </param-value>
</context-param>

The result: For each component the contained spring.xml is added to the application context and any beans defined therein are automatically created on deployment.

To make sure no name clashes occur you should establish a simple naming conventions for the id attribute of your beans like component.beanname. Resources defined in the main application context that the components require like Hibernate sessions will be named core.beanname.
For example:

<bean id="pbx.pbxDao" class="com.reucon.astis.dao.hibernate.PbxHibernateDao">
  <property name="sessionFactory" ref="core.sessionFactory"/>
</bean>