-
Notifications
You must be signed in to change notification settings - Fork 21.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mass assignment vulnerability - how to force dev. define attr_accesible? #5228
Comments
I was thinking about generating something like this, unless you pass some kind of option to generator (sometimes you just want to skip
|
so, here is what i came up to.
I suggest to have foreign keys and primary keys protected by default(what are keys can be recognized by ActiveRecord easily). IMO Rails should teach developers to set up so important and vulnerable keys by hands. It is not a handicap for prototyping, just +a few lines of code. But it is all about sane and safe rails apps.
I've got a big picture in my head but the backbone is described above. I strongly believe that having keys(references, relations) will make ruby on rails a 20% more awesome. I mean robust |
Oh, didn't mention. On my part - I wouldn't support setting all attrs protected. It will cause such big mess! You cannot force every body to read release notes. Stackoverflow will be down. :] + it is dirty solution. |
@dhh you dont like 'whitelist' idea - i dont too. But what is your opinion regards relation keys? They are obviously should be defined manually - in most cases. That is why having them protected by default is not a big deal. |
Just imagine which power this vulnerability gives in my.. and now in your hands if you get what has happened. |
There're too much trolling going on in this ticket and I'm not sure anymore if you mean anything serious. If you're going to do a bug report or feature request, just stop trolling and try not to be annoying, then the core team will come and check out by themselves. Name calling while trolling doesn't help, trust me. |
@sikachu bugs are serious. This is not only bug report, because this problem is so wide spreaded. postereous, speakerdeck, scribd, github - and I only have started testing. We need to introduce blacklist attributes. MOst of rails apps(from small to github) likely got mass-assignment bugs if they don't user attr_accessible. I just want to attract more attention to reviewing this problem from scratch and calmly decide - what should we do with M As-ment problem. And, if some of you support my idea I could provide fixing pull request. But you ignore this bug, like nothing has happened for a long time. SOrry for not called for trolling, I overplayed :) Everyone, again, express your point please, you are welcome. |
There was a proposal about changing that flag in #4062 and the consensus is the pros of the default configuration outweigh the pros of the alternative. Thanks! |
@fxn have you read my post? Did you see vulnerabilities i pointed out in e.g. github? |
What I want you to see in that thread I mentioned is the way the core team perceives this. You are not discovering anything unknown, we already know this stuff and we like attr protection to work the way it is. |
look. this is github, written on rails. https://github.com/homakov/ClientSit/issues/4 Really, is there any case when user should be able set created_at by himself? It is timestamp! Why I can set it using just <input name=model[created_at] value='1987...' ? |
Rails is not in charge, it is your responsibility to secure your application. It is your responsibility to avoid XSS, to ensure that the user is editing a resource that belongs to him, etc. Rails, however, does a lot of effort to assist you in securing your application as much as it can. That's why you have some protection measures built-in. I don't think we need to special-case anything. The user has a flag to secure by default, I personally think that is enough. I see little benefit in special-casing the timestamps if you have the flag set to false. And I am totally -1 in doing anything fancy with foreign keys because they have of course valid use cases where users can set them. |
Perfect response. Rails are not in charge - my question was like, 'why is that'. Surely nobody is fully in charge. But only rails apps got this kind of bug. Yeah, phpists never got so fast prototyping tools so most of them cannot even dream about update_attributes {} and form generation too. Rails has very convinient tools, I agree! attr_accessible is good and must thing for every developer. But for now we got it too unknown. Most of middle level developers forget about the meaning of this tool. Mixes with attr_accessors in ruby itself - so their model gets very unsecure. So you only a little bit support special casing of timestamp. Regards foreign keys - I didn't get why you are "totally" -1, and if you got spare time please give me valid use cases if you know some. That will help me in understanding your point fully another way to decide problem - populate using of accessible. Include it in scaffold generated output for model files. Im pretty sure rubyists will care much more having these lines and one day 4/5 will know+use this declaration. (now 4/5 don't either know or use, that's sad) |
@homakov I also don't like the idea of doing anything automated with foreign keys or timestamps. That way, people that does not know that they need to use some kind of params protection will be secure in those 2 cases, but it will fail with any other critical field, let's say @fxn what do you think about generating a model class with a comment describing attr_accessible and giving example, something like:
|
@drogus it is your viewpoint. Ok, let's not bother junior devs who will need to think about protection. |
It's 2012. When will people stop believing in "blacklists"? The default has to be restrictive and the developer has to make sure she/he does acceptable exceptions. It's like with the XSS/sanitize stuff. It will never work the "blacklist"/"developer should care" way, imho. At least throw a warning into the debug-log when a model has no attr_accessible defined at all... |
@rmoriz +1 Rails is all about conventions. Broken by default is not a good convention. |
@homakov Man, you look like a kid that wants some attention. Stop trolling and make GitHub a favor — file a private bug request via contact form — that's how non-douchebag people do. I totally agree with @fxn — missing |
@bai don't shoot the messenger, dude. |
@bai what you say? Every book, every tutorial, every guide tells developers to use generators. Do you create all the test + migration files by hand?! |
@docwhat I might have a bit overreacted — apologies for that. Yet I think giving one example of vulnerability is enough, no need to go through commits and issues over and over screwing things up. |
@bai is right, though. Zero-day attacks are a completely inappropriate way of raising awareness of a vulnerability. |
@rmoriz I use generators on prototyping stage extensively, but then it simply gets too custom and often beyond scaffolds. It depends on a dev though. |
@ELeo @meskyanichi was said all argument what I would like, so I would like to reply to just this:
This is absolute true. But, as a framework developer, I can protect my users from security problems caused by framework if it is possible. Developers are not a secretaries or nurses to I shouldn't assume they can't solve their problems but if I can help them to write better and more secure application then I must do it. |
Take a breath, and think naturally... In life, people consciously and loudly choose to tote themselves in the nude. Even simple fashion is considered a statement:
This is an issue of avoiding the dreaded nipslip or more poignantly protecting baby developers from rapists and pedophiles. Seriously, how much can you expect from a five-month-old? Consider another analogy between escaped strings (which Rails quite aptly handles) and consumables. Cereal and arsenic shouldn't mix; medicines are proscribed by experts; and the LSD's for the adventurous. In the end, you choose, but you can't just allow anyone to shove anything into any orifice. Sensible conventions reflect how we think, and thus make languages like Ruby and fameworks like Rails so wonderfully appealing and empowering. Flexibility shouldn't be compromised, of course: I'd be pissed if I had to fight to dress myself. But keep the infant in his diapers and sew the long-forgotten crotch holes in your buddy's pants (coughgithubcough.) After all, mistakes are only human. ;D |
i think instead of fighting, rails people should find a nice solution for this problem. please |
Solution is in the repo, forcing security is enabled by default. |
Couldn't rails automatically use the input fields declared within the form_for block to determine what fields are allowed to be posted? This could be implemented by automatically inserting a special key at the end of the form, then the controller could only allow the declared parameters through to the actions. |
Would it be possible to encode the ids of every element in the form? Using sha1 or something like that. The form could also contain something that would assist in the decoding of the ids. The helper methods (form_for , text_field) would handle the encoding and the controller would automatically decode the params, so it would be transparent to the user. |
@evilgeenius No, it is not possible, because the And form_for is just generates a HTML form. It is not related to handling incoming parameters. And,you cannot restrict incoming parameters on the level of framework, because it is an application-dependent thing. |
On 06.03.2012 20:17, Gabor Garami wrote:
I think he meant attaching a kind of control sum to each form, to allow wrzasa |
Can someone please point out to me a reasonable use case, for a web application, when you don't need to make sure your POSTed data is exactly what you're expecting? I seem to see people think there are cases where not being forced to be explicit about what you allow, would be... needed, apparently. I'd appreciate a case. |
On 07.03.2012 14:00, Norv wrote:
There are cases when you don't care, because your model contains only the Your question is even more important in case of RoR where my use case is |
@norv In the real world, there aren't a lot. One exception is where the data is coming from a "trusted" user, e.g. an admin. Sure, maybe there's fields you want to secure even from an admin, or maybe not, or maybe you just figure it doesn't matter if they want to hack their own app, if they want to go to those lengths. However, not every model deals with POSTed data, and some do but only indirectly. For example, a project I work on imports XML data from a "trusted" source, so in these kinds of models, there's no need for security. There are numerous models in the project like this. I'd essentially have to attr_accessible every last column, if the default were for all attributes to be blacklisted by default. This is somewhat arduous, and is somewhat of a maintainability headache, because if the schema changes later on, I have to add those new fields to the attr_accessible list. If we're going to go with a blacklisted-by-default approach, is there some way for me to auto-whitelist every attribute without having to be so explicit as to type out each one? |
Probably a simple configuration should be enough blacklisted-by-default , a config to change it to whitelisted-by-default and the option to change it directly in the model at run time. I don't see the problem really and rails has just maked a fool of itself... PD: If you advertise you framework as "even an idiot can make a page in 30 minutes" you will end up with a lot of idiots writing pages in 30 minutes... |
To me it seems obvious from the start that mass assignment should be disabled by default. Otherwise, you add a field on a table, and you have to remember to block it on the model? If the field would be user-assignable, then of course a form would have to be modified to add an input, and at THIS time, you would modify the model, because it is related to the same change. Yii framework in PHP which is very similar to Rails, blocks alls fields by default since the beginning. If this is common practice in the Rails community, I would never trust a Rails application. This is as bad as SQL injection. |
Just received an email from GitHub, perhaps related to this issue: "A security vulnerability was recently discovered that made it possible for an attacker to add new SSH keys to arbitrary GitHub user accounts. This would have provided an attacker with clone/pull access to repositories with read permissions, and clone/pull/push access to repositories with write permissions. As of 5:53 PM UTC on Sunday, March 4th the vulnerability no longer exists." |
Thank you! @ELeo I was going to point out the commit above - cjcsuhta already mentioned it. The possibility of different sources for the data getting to the model, than http form input, and needing different treatment for them, tells me again that: authorization, filtering of the incoming data, and even validation needed for the data, are not really model issues. They may apply on the model, or be aware of it, but they cannot and should not be handled all at model level, otherwise you can't really have flexibility nor security as needed. On the other hand, since in the case of web form data, there is an always-present need for request filtering, authorization, and validation, I find it more than reasonable to address these concerns at the level of a web framework. At most, validation, from this list, may be disputable as to where it belongs, it may be the choice of a particular framework to handle it more tied to the model itself. I just don't see how could the rest be model matters, and in the same time have a both flexible and secure framework for development. Side note: I'd say admin is not really an exception in the sense of my question, since checking if the current user is an admin means an authorization check. |
@homakov Congratulations, your name is now on the media: http://www.pcworld.com/businesscenter/article/251259/user_hacks_github_to_showcase_vulnerability_after_rails_developers_dismiss_his_report.html |
We developers using Rails should not have to write Merb or 0day the repo in order to get core Rails devs to stop saying "The emperor DOES SO have clothes!" Core devs, please change your attitude. We want newly-generated rails apps to have a setting in the application.rb that by-default turns off mass assignment, unless we reverse that setting in the application.rb or on a model by model basis. This way it's backwards compatible with existing apps too. Most of us want this. Stop making us resort to such tactics for anyone on the core team to listen. |
@dburry you knocking on the open door. Please read back this issue, the future Rails versions will come with enabled enforcement. |
@hron84 indeed, for this issue... but will our attitudes change enough from this experience so that such tactics won't be necessary with other issues? I see the attitudes as the root cause that made this issue go so long ignored. And I realize this is more a social thing than a technical thing, so maybe this isn't the right forum for me to keep talking about it, sorry :P |
Isn't the question of whether mass assignment is enabled or disabled by default a bit of a red herring? I've just posted a question to this effect at SO, if anyone's interested. |
@sampablokuper Answer is No. User is able to update HIS public key record AND he updates it with new user_id. code:
|
@fny What the fuck, why are you on about babys, rape and pedophiles you sick fuck. oh my god people are so weird nowadays |
@def14nt I was arguing in a convoluted metaphor that the default convention should protect newbie developers ("babies") from hackers ("pedophiles and rapists".) Reading the comment now, I do agree it was in poor taste. The analogies were an attempt to make a dry concept humorous, and in retrospect I see can how the comment can be seen as inappropriate. It's been six years since I made that comment, and I was a naive 21-year-old at the time, so please forgive me. |
@fny Yeah it's OK, just maybe not speak like that elsewhere or your account might be taken down 😉 |
Those who don't know methods attr_accesible / protected - check that article out http://enlightsolutions.com/articles/whats-new-in-edge-scoped-mass-assignment-in-rails-3-1
Let's view at typical situation - middle level rails developer builds website for customer, w/o any special protections in model(Yeah! they don't write it! I have asked few my friends - they dont!)
Next, people use this website but if any of them has an idea that developer didnt specify "attr_accesible" - hacker can just add an http field in params, e.g. we have pursue's name edition. POST request at pursues#update
id = 333 (target's pursues id)
pursue['name'] = 'my purses name'
pursue['user_id'] = 412(hacker id)
if code is scaffolded than likely we got Pursue.find(params[:id]).update_attributes(params[:pursue]) in the controller. And that is what I worry about.
After execution that POST we got hacker owning target's pursue!
I don't mean that it is Rails problem, of course not. But let's get it real(Getting Real ok) - most of developers are middle/junior level and most of them don't write important but not very neccessary things: tests, role checks etc including topic - attr_accesible
how to avoid injections ? What should Rails framework do to force people to keep their rails websites safe? Making attr_accesible necessary field in model? What do you think guys.
The text was updated successfully, but these errors were encountered: