If so, this isn’t a security vulnerability in Rails. A new Rails application isn’t vulnerable by default. It’s a security vulnerability in apps written using a certain style, or perhaps a vulnerability by default in apps written using the generators and scaffolding baked into rails.
But for guys like me who never use mass assignment, our applications are not vulnerable by default, correct? And likewise, for people who RTFM before using mass assignment, their applications are not vulnerable, correct?
If I understand this, it is very different from something like the routes vulnerability a while back, where EVERY Rails app was vulnerable whether you liked it or not. Saying Rails has a security vulnerability here is like saying that ActiveRecord has a SQL Injection vulnerability because by default, find_by_sql allows you to compose queries out of strings, and if you don’t choose to use the correct form, you will be attacked by little bobby tables.
(EDIT) To be clear, I like what the article says, I’m just not sure that the phrase “Rails has a security vulnerability” applies in this case, or that it is technically true that Rails is insecure by default.
Well, gee...so maybe some novice developers write an app using the generators and scaffolding baked into Rails, and as a result they get a security vulnerability that a more experienced developer might have avoided by doing extra work, and you say that's not a security problem in Rails?
Maybe it isn't a "vulnerability", per se, but it sure seems like a poor design choice. A "hardened" framework is going to make parameter whitelisting the default behavior, even if it's a little less convenient. If the github developers (who are presumably experienced) can make this mistake, then anyone can make this mistake.
Young man, do not take that flippant tone with me (raps ruler on desk). Those novice developers failed to RTFM. If you want a framework that produces secure applications for inexperienced developers who do not read the fine manual, you are setting a laudable goal for Rails, but I hardly think that “Secure even for people who are 1. novices and 2. compound their ignorance by refusing to RTFM” is synonymous with “security problem.”
If you open your history book to when Rails was first becoming popular, there were many people grumbling that because it was built on top of a dynamic language that it was vulnerable to all sorts of bugs caused by novice developers getting their types wrong. The argument at the time was that Rails provided a certain type of freedom and power at the expense of certain safeguards. The same argument was played out when people started noticing that monkey-patching run amuck caused certain problems.
I agree with you that this is a design choice. If you want to say that you disagree with the choice as it was originally made, I agree with that too. I won’t say that I would have made a different choice back when that feature was first baked in, I did not write the framework. But here we are today, and it seems like a very good time to make a different choice.
Let's make the reasonable assumption that your clients—the people using your interfaces— are trying to do a good job. They're smart, they're motivated, they're conscientious. They're willing to read some documentation to help them understand the system they're using. They want things to behave correctly.
That being the case, if they make a mistake when using your interface, it's your fault. We're assuming they're doing their best—they want to succeed. If they fail, it's because you let them. So, if somebody uses your interface incorrectly, either they're working hard at it (less likely) or your interface allowed them to do something easy that was not correct (more likely). This puts the shoe on the foot not used to wearing it: it means that responsibility for interface usage errors belongs to the interface designer, not the interface user.
Source: Scott Meyers: The Most Important Design Guideline? http://www.aristeia.com/Papers/IEEE_Software_JulAug_2004_rev...
I suppose that the github developers all failed to RTFM, too, right? So either they're all n00bs, or we can safely assume that everyone makes mistakes when the framework makes mistakes easy to make.
(Also, I suspect that you're joking about the "young man" thing, but it's probably worth pointing out that I've been coding for a long time. I may even be older than you. But I still make mistakes, and I definitely appreciate it when my frameworks make the Right Way the Only Way. It's not just about novices.)
Except that PHP makes it so easy to write insecure code that novices are pretty much guaranteed to produce vulnerabilities and even experts have to be vigilant to avoid accidentally stepping on one of the many landmines in the language.
If the designers of the language (or framework) put a landmine in it, and a developer steps on it, the designers of the language absolutely bear some responsibility for the fact that the landmine was there to be stepped on.
Historical experience has shown that no matter how excellent the mechanism, the practical security baseline is determined by the default policy.
Windows NT has had, since inception, a far more sophisticated security mechanism than the default unix model. But that doesn't matter in the real world, because to retain backwards compatibility with Windows 95 (and through to DOS), almost no security policy was shipped by default until Vista.
Was Windows insecure? According to your criteria, no. According to the actual real-world consequences, yes.
The bottom line is that policy matters and that in this case, the rails crew have chosen a demonstrably bad policy.
The one tool can be said to have a poor policy, I agree with that. But Rails does not have a hole in it. I did not have to rush to “close” holes in the projects I’m responsible for when I read these posts because I hadn’t used the tool in the first place.
What Rails has is a poorly designed tool. But if you’re going to say that if a developer can misuse the tool then Rails has a security problem, then I’m going to say that the exact same thing is true of ActiveRecord.
The policy of the optional tool is broken. That's a bad thing. The entire point of a security baseline is to provide an attractor towards which design and code approach without resistance. If you want insecure, fine, but you'll have to go out of your way to get it.
Rails is not doing that.
> But if you’re going to say that if a developer can misuse the tool then Rails has a security problem, then I’m going to say that the exact same thing is true of ActiveRecord.
And I would agree. The allure of Rails is how easy it is to get something going. The problem with Rails is how easy it is to get any old thing going.
See also: every major PHP application ever written.
Regarding your ActiveRecord example, I would totally agree that there was a hole if the standard approach to running SQL was to use find_by_sql with string interpolation. Fortunately, that's appropriately viewed as an option of last resort, with appropriate amounts of "here be dragons" around the dangers of calling that method. Meanwhile, tutorials gleefully do mass-assignment, with perhaps a footnote about attr_accessible, which was of course not included for the sake of brevity.
It might be worth saying that Rails strictly as a framework does not have a security problem with mass assignment, only a very dangerous tool, but there is certainly a problem with the culture regarding it.
> But for guys like me who never use mass assignment, our
> applications are not vulnerable by default, correct?
Yes, if you never ever call `update_attributes` you're not vulnerable. This is, however, the most common way to perform model updates. > And likewise, for people who RTFM before using mass
> assignment, their applications are not vulnerable,
> correct?
No! Absolutely not! The Github exploit is a prime example of this. Solid developers, who have obviously ReadTFM, can easily fall victim to this because the default is to be insecure!The fact is that Rails ships code generators that give you insecure code and put the onus on you to do something about it.
I'm not absolving any developer of their responsibility to not shoot themselves in the foot. Ultimately, if this Github exploit had been used to do serious damage, Github, not the Rails core team, would have been responsible. It is the developer's responsibility to ensure that their code is as free of vulnerabilities as they can make it.
While the proposed solutions in the issues I linked to were denied, it doesn't mean there shouldn't be some solution added to Rails. This is definitely a case of convenience favored over security.
There’s no “vulnerability by default” in ActiveRecord’s handling of SQL snippets. There’s a right way and a wrong way. Likewise with mass assignment. There’s a right way to use it and a wrong way to use it. FWIW, I don’t use mass assignment, ever, because the “right” way offends my sensibilities by making me load up a model with authorization logic.
Rails is not vulnerable by default because Rails apps do not include mass assignment by default. It’s not like there’s a controller method called ‘update’ created if you don’t write one that uses mass assignment. You have to generate or write an update method, and if you do and you include a sql query, you have to get the sql fragments right. Likewise if you use mass assignment, you have to do attr_accessible right.
All that being said, I don’t like attr_accessible, I think it might have been brilliant at the time but a few years later I think we can revisit this problem with fresh eyes and a lot of experience as a community and do even better. Which by extension means that I don’t like mass assignment.
SO:
We probably agree that this feature should be taken out and shot, but are quibbling over which charge should be read off the indictment before giving the order to fire ;-)
Or install a plugin and inherit one:
https://github.com/josevalim/inherited_resources/blob/master...
PHP learned their lesson a while ago with register_globals: if you need to specifically disable people from attacking your site in many places, it's inevitable that you'll miss one or two.
The default scaffolding doesn't contain an attr_accessible property, so it's not visible to the user that there's something missing. There's also no feedback from Rails that your attributes are insecure; only feedback if one tries to change an attribute explicitly made non-accessible. Figuring out which attributes must be private is a problem possibly beyond the scope of core Rails, though.
Perhaps a command like `rake routes` for publicly accessible model attributes might be of benefit.
I really liked wycats proposal of moving this sort of thing to the controller - it's a much more logical place to look, and I do think there's a thing as a too-skinny controller - mapping inputs to model attributes is a perfectly sane thing for the controller to do IMO.
Saying that `update_attributes` is a security vulnerability doesn't really make sense... it's like if I said cars can accelerate to very unsafe speeds by default and this is a huge safely risk, ignoring the fact that cars also come with brakes :)
Convenience is truly overrated. Inconvenience is cheap, lack of safety (which translates to security issues and bugs) is far far more expensive.
“`...You hadn't exactly gone out of your way to call attention to them had you? I mean like actually telling anyone or anything.' `But the plans were on display...' `On display? I eventually had to go down to the cellar to find them.' `That's the display department.' `With a torch.' `Ah, well the lights had probably gone.' `So had the stairs.' `But look you found the notice didn't you?' `Yes,' said Arthur, `yes I did. It was on display in the bottom of a locked filing cabinet stuck in a disused lavatory with a sign on the door saying ”Beware of The Leopard".'"
Brilliant point. While we're all talking about this issue, lets all team up, all of us here on HN, right now, to email php-internals and ask them to bring back register_globals and turn it on by default. It was a mistake on their part to disable it. After all, who doesn't read and follow all the documentation?
I believe this is absolutely correct.
This is not a bug or a security hole in Rails, but an issue with programmers not paying attention.
If Rails had no attr_accessible feature, it would be standard practice to always filter attributes in the controller, and no one would call this a rails issue - they would put the blame where it belongs: Github.
Instead, because attr_accessible exists, people are flaming that it should be enabled by default.
If anyone should be getting flamed for this, it should be the Rails maintainers that weren't open to the discussion.
Rails is just a web framework and does provide developers who use it with the ability to use it securely or insecurely. In this case, the shipped default leaned more toward convenience than security. There are tradeoffs involved.
GitHub provides codebase hosting to thousands of projects, some of which are private. They have a large public attack surface. And they're business which takes money. And they're probably making millions. This should imply certain things to it's management team. It's reasonable to assume they'd take security very very seriously. Perhaps not need bank-like level security, but still, pretty well up there.
Any Rails app developer has had the ability to unilaterally go into their own codebase and fix/close any security vulnerabilities. This same ability does not exist for users of the GitHub webapp. (Of course, we could choose not to use GitHub, but that would be good neither for GitHub or the user.)
That said, security is hard and getting it 100% right 100% of the time is probably impossible. And I love GitHub, and think they get more things right than wrong, enough of the time, that I'll give them the benefit of the doubt.
I do agree that this is GitHub's responsibility. I think they handled the situation appropriately, however. I'm shocked at the backlash people have against GitHub locking the user's account while it was being investigated.
I just want to give a huge nod of recognition to this extremely civil way to express disagreement. Bravo!
I'm not saying the Rails devs shouldn't have changed it five (maybe seven now?) years ago when it first came up, but output escaping wasn't default until 3.x, and everyone in the community knew both were major problems.
They (temporarily) disabled the account, fixed the problem and re-enabled the account. All while keeping people in the loop about what happened......at 9am............on a sunday.
I may be wrong, but that seems like a pretty reasonable way of handling the situation.
A bad workman always blames his tools.
So do expert workmen when given crappy tools.
http://googleonlinesecurity.blogspot.com/2010/07/rebooting-r...
1 - The mass assignment rails issue was resolved as soon as could be after it was reported 2 - The public key form update vuln was NOT reported and used, NOT to attack github but to make some point to the Rails team.
The second issue was the one github had been talking about in the original blog post. They handled it as soon as it was discovered.
In so far as they responded as quickly as possible, yes they had it in hand.
I said it is a bug (and a serious one).
A bug, as you may be aware, is a mistake, fault, failure, problem or other unintended or surprising behavior in software.
See updates to my post for some additional clarification. I hope that helps. Thanks for reading!