Today we’re releasing JRuby 1.4.1 as a recommended upgrade for all previous versions of JRuby. Previous versions contained a bug in JRuby’s regular expression engine that could allow an attacker to perform, for example, an XSS attack on a web application running under JRuby.

Download the 1.4.1 release.

This vulnerability fix is the only change from the previous JRuby release (1.4.0). Also note that the JRuby 1.5.0 release contains this fix as well.

Common Vulnerabilities and Exposures

The Common Vulnerabilities and Exposures (CVE) project has assigned the name CVE-2010-1330 to this issue. This is a candidate for inclusion in the CVE list, which standardizes names for security problems.

Impact

Any Ruby application code that uses regular expressions for string matching and substitution running under JRuby and using $KCODE = 'u' is vulnerable.

If a string contains invalid UTF-8 byte sequences in the (inclusive) range \xC0 to \xFD , the immediately following character will not be matched by a regular expression. Consider the following code:

str = " \xF6 <script>" $KCODE = '' puts "KCODE: " + $KCODE puts str . gsub ( /</ , "<" ) $KCODE = 'u' puts "KCODE: " + $KCODE puts str . gsub ( /</ , "<" )





Ruby 1.8.7 ignores the invalid bytes and continues, while Ruby 1.9.2 raises an ArgumentError due to the invalid bytes. But for JRuby, the effect is to fail to match the character following the invalid byte. For the example above example run with JRuby 1.4.0 prints the following. Note that the fourth line should be the same as the second.

KCODE: NONE ?<script> KCODE: UTF8 ?<script>

The effect of this bug is magnified considering that the Rails html_escape or h helper essentially does what the above example does, meaning that any Rails view using the standard ERb escape helper method is vulnerable.

Releases

The JRuby 1.4.1 and 1.5.0 releases (including release candidates) all have the vulnerability fixed.

The fix was applied to the jcodings library which JRuby uses. As such, a source patch against the JRuby source is not available. Replacing the build_lib/jcodings.jar file in your JRuby source build with the jcodings version 1.0.3 jar file is sufficient to resolve the issue.

If you are unable to upgrade to JRuby 1.4.1, please contact the JRuby team at security@jruby.org for assistance.

Workarounds

Turn off $KCODE = 'u' in your application if you can. Otherwise, the only approach is to patch application or framework code to be aware of the invalid byte sequences.

Thanks

Many thanks to Jörn Hartmann (joern dot hartmann at gmail dot com) for finding and reporting the issue.