About a month ago, Mike McCabe and I discovered a Cross-Site Scripting (XSS) vulnerability within a Rails application we were developing. This was surprising because our application had a very small footprint and included no explicit calls to .html_safe or .raw. Eventually, we were able to track this vulnerability down to the twitter-bootstrap-rails gem we were using.
Within our application, we are using the bootstrap_flash helper method for rendering flash messages passed within the application, similar to the example code below.
In our controller, we have the desire to use flash messages to pass error conditions back to the user. These messages often contain user input.
Typically, Rails developers will process error messages within the application layout by iterating over each item in the flash array and printing within a div tag.
Using the previous method and native Rails flash functionality, any user input is automatically HTML encoded.
If we look at the HTML source, we will see that the input is converted to the HTML entities equivalent and is displayed within the browser instead of being rendered.
The problem relates directly to the implementation of the bootstrap_flash helper function. This function is defined in app/helpers/bootstrap_flash_helper.rb within the twitter-bootstrap-rails gem.
The vulnerability exists because the library is explicitly calling the .html_safe function on the msg variable (line 18), which is an element of the flash array. The items within the flash array are defined via the user controller and are not previously sanitized. In the case of our application, these messages include information provided through the application parameters.
The solution is as simple as removing the .html_safe function call occurring on the msg object from within the bootstrap_flash function (line 18). By removing this particular instance of .html_safe, we ensure that the msg variable is automatically encoded prior to generating the HTML content for the div tag container.
This issue was reported to the twitter-bootstrap-rails developers originally on 02/23/2014, and a remediating pull request was submitted and accepted on 03/25/2014. We recommend you update your gem from the Github source by adding the following line to your Gemfile. If it cannot be updated, we've provided a patch version of the helper that can be added to your Rails application here.
With a quick scan through GitHub, it appears that the twitter-bootstrap-rails gem is in use within approximately 16,000 repositories.
Update: CVE identifier CVE-2014-4920 issued on 07/11/2014, but advisory has not yet been issued.
John Poulin is an application security consultant for nVisium who specializes in web application security. He worked previously as a web developer and software engineer that focused on building multi-tier web applications. When he's not hacking on web apps, John spends his time building tools to help him hack on web apps! You can find him on twitter: @forced_request and on myspace: REDACTED.