The latest Rails security flaw [1] is example of a common anti-pattern. Ned Batchelder wrote an awesome post [2] explaining how a similar issue may also exist in Python’s YAML parser [3]. Looking at these vulnerabilities, I am reminded of similar flaws in other frameworks and libraries.
The issue in each case is an abuse of extensibility. At first glance the idea is clever: allow for run-time execution of new code or binding of server-side variables without changing your compiled code, thereby greatly enhancing extensibility. For example, provide extensions to your Python YAML parser that allow you to create arbitrary objects and execute Python code; provide extensions to XML Template parsing that allows for arbitrary command execution [4]; or dynamically assign user-supplied parameters to server-side variables [5] (aka mass assignment) based on the parameter name. This kind of vulnerability is by design in contrast to many other by accident vulnerabilities. We called the mass assignment anti-pattern out [6] several years ago when doing a security analysis of the Core Java EE Patterns for OWASP.
I have a strong feeling we’ll see more vulnerabilities of this type, particularly with the rising popularity of standards like SAML that are built upon several layers of libraries implementing and extending complex specifications. These kind of issues can sometimes be hard to catch with an automated scanning technology, which means most organizations adopting the status quo of application security due diligence [7] will undoubtedly miss detecting some instances of extensibility abuse.
Security-minded developers can protect themselves by taking the following steps:
Turn off unnecessary extensibility in third party libraries and frameworks
Do not use untrusted input in libraries that provide broad extensibility, such as Apache’s Xalan [8] with extensions enabled.
Be vigilant about monitoring for and patching newly discovered vulnerabilities in frameworks and third party libraries. Wherever possible, sign up for security mailing lists or groups like Ruby on Rails Security [9]
Now that's an interesting idea: developer preferences for extensibility mechanisms in libraries. Anyone know of example libraries shipping with that capability?
Doesn't this get into the issue of whether XML dependency injection is a good idea? All of the wiring and some logic is built up in some files that are outside of the build/compilation process. Doing "proper dependency injection" (quotes for sarcasm) to me has always made me worry that I've lost control of how my application works, and somehow based on the right XML/JSON/etc config magic it will work perfectly and meet all security standards.
I believe over-engineering is also a culprit here. We had a similar situation in JSON handling in browser. Some over engineered feature allows custom objects to replace built in object for lists, allowing XSS through JSON parser. The solution was to make every REST API to start with a top level dictionary object. It just sounds arbitrary over engineering!!
Why can't there be a set of parsers for YAML, JSON, and XML that are tested, abused, and audited aggressively so that your interchange formats don't become attack vectors?
The current state of having a half dozen of each of these is complete chaos. Presumably nobody thinks they're accountable because everyone has the option of using another package instead if they're not happy, basically passing the hot-potato constantly.
Is there a non-Ruby project that has a good implementation of these worth studying?
I also don't understand why all parsing of user input needs to have YAML turned on by default. All this stuff should be turned off. I think it is a fundamental design choice that has to be looked at.
We should call it "insecurity by default" (in contrast to insecurity by design). A major problem is that nobody takes responsibility or pays attention for default choices.
A ton of packages have default choices that are inherently bad/insecure (mail servers listening on all interfaces by default, SSH servers accepting root login by default, and so on). Packaging is just as important as development.
Serious developers take an interest in making things as simple as possible, ideally each piece have singular responsibilities, and no magic. Software engineering is hard, and it is heartening to see more people realise and promote awareness of some of the more dangerous anti-patterns we see in frameworks like Rails.
The problem isn't "magic" per se, and the problematic components already have very clearly defined singular responsibilities (an API doesn't get much simpler than "dump" and "parse").
Security problems often happen when two components that are perfectly safe in their original contexts are tied together in a way that their designers didn't intend. These parser problems are examples of that.
So it's actually a good thing that frameworks like Rails try to tie together many components for you "magically". The integration of all those little simple pieces is always a chance to screw up security. It's better to do that hard work once, collaboratively as a community, than to have every developer make those risky choices separately every single time.
It's the same cost/benefit analysis that explains why you should never roll your own crypto. Anybody can make a system that's "secure" enough to keep themselves from breaking it, but that's not nearly good enough. You increase security by increasing scrutiny.
Yes. No other security framework has ever had problems like Rails had. It's definitely not like enterprise Java frameworks that were designed from the outset to satisfy security demands from F-500 appsec teams have had repeated remote code execution flaws. And if they did, they definitely weren't as simple to trigger as "hitting a URL that maps to an embedded Java scripting language". No, only Rails has bugs like these.
There is no magic in Rails, it's just Ruby code. There will always be APIs that shouldn't be given untrusted data. When this happens anyway, calling it an "anti-pattern" does not mean you have perceived some kind of systemic fundamental flaw in the framework. That's just a transparently self-serving way for you to feel superior because after all you're a "serious developer".
Let's get specific, because there's a point here that I think a lot of people are missing (including tptacek).
ActionDispatch::Routing::RouteSet::NamedRouteCollection.add calls 'eval' on the property name passed to it. This invites exploitation. It also fails 'static_typed's desideratum of each component having a single responsibility. And I don't think calling it "magic" is too strong.
I don't know to what extent the Ruby culture encourages calling 'eval' in random API routines like this, but when I previously argued here on HN that that had to be a bad idea, I got some pushback. I would certainly call this a dangerous anti-pattern.
weren't some of the security holes found in the json & yaml libraries? Those weren't rails specific and could have just as easily happened in a Sinatra-like framework too.
[+] [-] dfcarney|13 years ago|reply
-- by Rohit Sethi on February 13, 2013 -- http://blog.sdelements.com/author/rohit/
The latest Rails security flaw [1] is example of a common anti-pattern. Ned Batchelder wrote an awesome post [2] explaining how a similar issue may also exist in Python’s YAML parser [3]. Looking at these vulnerabilities, I am reminded of similar flaws in other frameworks and libraries.
The issue in each case is an abuse of extensibility. At first glance the idea is clever: allow for run-time execution of new code or binding of server-side variables without changing your compiled code, thereby greatly enhancing extensibility. For example, provide extensions to your Python YAML parser that allow you to create arbitrary objects and execute Python code; provide extensions to XML Template parsing that allows for arbitrary command execution [4]; or dynamically assign user-supplied parameters to server-side variables [5] (aka mass assignment) based on the parameter name. This kind of vulnerability is by design in contrast to many other by accident vulnerabilities. We called the mass assignment anti-pattern out [6] several years ago when doing a security analysis of the Core Java EE Patterns for OWASP.
I have a strong feeling we’ll see more vulnerabilities of this type, particularly with the rising popularity of standards like SAML that are built upon several layers of libraries implementing and extending complex specifications. These kind of issues can sometimes be hard to catch with an automated scanning technology, which means most organizations adopting the status quo of application security due diligence [7] will undoubtedly miss detecting some instances of extensibility abuse.
Security-minded developers can protect themselves by taking the following steps:
Turn off unnecessary extensibility in third party libraries and frameworks Do not use untrusted input in libraries that provide broad extensibility, such as Apache’s Xalan [8] with extensions enabled.
Be vigilant about monitoring for and patching newly discovered vulnerabilities in frameworks and third party libraries. Wherever possible, sign up for security mailing lists or groups like Ruby on Rails Security [9]
[1] http://www.zweitag.de/en/blog/ruby-on-rails-vulnerable-to-ma... [2] http://nedbatchelder.com/blog/201302/war_is_peace.html [3] http://pypi.python.org/pypi/PyYAML [4] http://labs.securitycompass.com/tutorials/xslt-command-execu... [5] http://www.codeproject.com/Articles/471784/Exploiting-Micros... [6] https://www.owasp.org/index.php/Category:OWASP_Security_Anal... [7] http://blog.sdelements.com/raising-the-bar-on-application-se... [8] http://xml.apache.org/xalan-j/extensions.html [9] https://groups.google.com/forum/?hl=en&fromgroups#!forum...
[+] [-] politician|13 years ago|reply
[+] [-] typicalrunt|13 years ago|reply
Maybe I'm just too jaded...
[+] [-] ehsanf|13 years ago|reply
[+] [-] astrodust|13 years ago|reply
The current state of having a half dozen of each of these is complete chaos. Presumably nobody thinks they're accountable because everyone has the option of using another package instead if they're not happy, basically passing the hot-potato constantly.
Is there a non-Ruby project that has a good implementation of these worth studying?
[+] [-] eyko|13 years ago|reply
[+] [-] unknown|13 years ago|reply
[deleted]
[+] [-] amalag|13 years ago|reply
[+] [-] ehsanf|13 years ago|reply
A ton of packages have default choices that are inherently bad/insecure (mail servers listening on all interfaces by default, SSH servers accepting root login by default, and so on). Packaging is just as important as development.
[+] [-] unknown|13 years ago|reply
[deleted]
[+] [-] static_typed|13 years ago|reply
[+] [-] ef4|13 years ago|reply
Security problems often happen when two components that are perfectly safe in their original contexts are tied together in a way that their designers didn't intend. These parser problems are examples of that.
So it's actually a good thing that frameworks like Rails try to tie together many components for you "magically". The integration of all those little simple pieces is always a chance to screw up security. It's better to do that hard work once, collaboratively as a community, than to have every developer make those risky choices separately every single time.
It's the same cost/benefit analysis that explains why you should never roll your own crypto. Anybody can make a system that's "secure" enough to keep themselves from breaking it, but that's not nearly good enough. You increase security by increasing scrutiny.
[+] [-] tptacek|13 years ago|reply
[+] [-] bithive123|13 years ago|reply
[+] [-] ScottBurson|13 years ago|reply
ActionDispatch::Routing::RouteSet::NamedRouteCollection.add calls 'eval' on the property name passed to it. This invites exploitation. It also fails 'static_typed's desideratum of each component having a single responsibility. And I don't think calling it "magic" is too strong.
I don't know to what extent the Ruby culture encourages calling 'eval' in random API routines like this, but when I previously argued here on HN that that had to be a bad idea, I got some pushback. I would certainly call this a dangerous anti-pattern.
EDITED to add: reference: http://rubysource.com/anatomy-of-an-exploit-an-in-depth-look...
[+] [-] catch23|13 years ago|reply