Giving Back To Open Source, Security Edition
December 4, 2013Note: This post details recently patched security vulnerabilities in a few popular Ruby libraries. If you use Rails, i18n, Doorkeeper, or Sorcery please go make sure that you are up-to-date and then come back to read this article. Some may disagree with us revealing the details below in this manner. Rest assured those who are building exploits have seen each of these vulnerabilities and already acted on them. It’s our opinion that discussing these openly affords an opportunity for education and prevention of future vulnerabilities.
At Thunderbolt Labs we tend to keep ourselves busy with work on our own product and our client projects. This doesn’t leave a lot of time in our schedule, and honestly we often have other ways we’d prefer to spend our free time than writing more software. We love the Open Source community even if we wind up more often on the consuming end or advising projects.
A large-scale client project required us to have a security audit performed. We were confident in our code, and sought out some of the best in the business – Matasano Security. In working with Matasano we were surprised in some of the findings. Our code was getting dinged here and there by a crew of security professionals, but those issues were relatively minor in comparison to some of the vulnerabilities found in popular libraries. Thankfully, because these projects are Open Source, fixes and subsequent releases were quick.
Each of these vulnerabilities are known issues (i.e. Symbol conversion, Send, and Sanitizing user input). This begs the question: If they’re so obvious why hadn’t they been caught or prevented from happening in the first place? Even with many eyes on things, it turns out we can all use a review from professionals with a security background.
We’re going to detail the major vulnerabilities found in our project’s dependencies and show you the impact. We’ve been responsible and waited for all of these vulnerabilities to be patched. Hopefully, showing the details of what was found will educate everyone on how small decisions can lead to unintended security challenges.
Sorcery
https://github.com/NoamB/sorcery
Magical authentication for Rails 3 & 4
The Problem
Sorcery::Controller::Config
included the following call:
Config.send(provider_name.to_sym)
This allowed the provider_name
, which was a user provided value, to be executed against the Config object. Meaning a user could call arbitrary methods on the class which could in theory lead to remote command execution. However, that was never achieved in this situation.
Making matters worse was the fact that Config
inherited from Object
. The widened the scope from calling arbitrary methods on Config
to calling arbitrary methods on Object,
it in turn includes Kernel
which makes the following attacks possible.
Here’s a fun, and safe demonstration you can run in irb
.
$ irb
1.9.3-p448 :001 > Object.send(:exit!)
$
Had that been your web server you would have effectively just exited the process. Most environments would recover with a god or monit style service watching and restarting the service. Outside of the shutdown and startup time no real harm done if this happens once. Clearly this is a DDOS opportunity.
What if we wanted to be more evil? Another example:
$ irb
1.9.3-p448 :001 > Object.send(:sleep)
^CIRB::Abort: abort then interrupt!
from (irb):1:in `call'
from (irb):1:in `sleep'
from (irb):1
from /Users/jim/.rvm/rubies/ruby-1.9.3-p448/bin/irb:16:in `<main>'
1.9.3-p448 :002 >
On a web server we would have just sent this process to sleep and in our environment our process monitoring would not wake that process up. Repeating this would simply consume all of the resources, another DDOS attack vector.
Doorkeeper
https://github.com/applicake/doorkeeper
Doorkeeper is a gem that makes it easy to introduce OAuth 2 provider functionality to your application.
The application in question required an OAuth2 implementation. We were able to get a significant jump on this solution by using Doorkeeper. After being notified of the vulnerability they moved swiftly and deliberately to resolve the issue.
The Problem
A fairly common problem that most Ruby developers either are not aware of or fail to consider in their implementations is, that garbage collection is not performed on the memory occupied by symbols. Essentially this is a memory leak which could be used by someone interested in degrading the performance of an application.
We’re not going to give you an example to run for this one because we don’t want you to lock up your machine. But in theory if you open irb
and create a loop that continues a few thousand times and each time executes a to_sym
on a string you will see the resulting memory usage spike. The longer the value you are converting to string the more memory used and the effect will be increased.
Note: If you follow through on the theoretical situation noted above the problem will survive until a restart of the process.
Rails / i18n
https://github.com/rails/rails
Ruby on Rails
https://github.com/svenfuchs/i18n
Internationalization (i18n) library for Ruby
We managed to get two birds (or bugs) with one stone on this issue, and really we should have prevented the situation. We included user provided data on to our page without sanitizing. This came by way of the locale
query string parameter which in our app, as well as Rails & i18n, denotes in which language to display content.
The Problem
Query string parameters are often used to affect user-specific behavior on a page. In this case the commonly used param locale
was appended to our URLs to carry forward the choice of language and/or region.
To take advantage of this vulnerability an attacker would have to convince you to follow a link that contains a malformed locale
parameter.
Here’s what a typical request might look like:
https://app.example.com/?locale=ca-EN
And here is an example trying to take advantage of this vulnerability:
https://app.example.com/?locale="<script>alert('Arbitrary JS just executed.')</script>
While you may feel like this is a scenario unlikely to fool most people, keep in mind that your users are more likely to fall prey to these sorts of attacks then a web savvy developer, add indirection of a formatted link and BAM! Your user has been compromised.
Conclusion
There is more than one way to give back to Open Source Software. The scale and type of projects we work on at Thunderbolt gives us the opportunity to test open source libraries at a level many can’t. Can a budding start-up afford to have a top security firm look at their dependencies and attempt to break their app? Probably not.
Our situation afforded us the opportunity to hire experts to torture our code. The good news is, it survived. We’re happy to help close a few vulnerabilities and help build awareness of some of the minor things we do as developers that can have serious security implications.