-
Notifications
You must be signed in to change notification settings - Fork 256
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
Security Issue on Update? #124
Comments
Might be a good idea for out-the-box functionality, but the way I see it these rules have to be overridden in your own User model anyway. The users on the one site I currently run complained about the short max password length. They are a security conscious bunch. Also, not all sites use usernames, some just use email for authentication, so just adding 'username' => 'alpha_dash|unique:users' without the "required" to the base ConfideUser might be an idea to look at. Another suggestion would be to mentioned in the docs that if you use usernames, you should add the "unique" rule to your extended User model. |
I see what you're saying but it still allows the out-of-the-box configuration to be misused by folks that don't override the params. My thought is, if a security plugin includes rules, why not go ahead and set them in a way where users can't take someone else's username. Seems like a pretty big hole. All that needs to be done is add back 'unique' and then except for the current userid. Not sure how that confines anyone. Maybe I'm missing something? |
Please test with saving an update and having it set to unique. Let me know the results. |
In one of my apps I'm doing something like this for the update. public function postUpdate($user)
{
$rules = array (
'username' => 'required|alpha_num|unique:users',
'name' => 'required'
);
// Remove unique from update if it's the same.
if(Input::get('username') == $user->username) {
$rules['username'] = 'required|alpha_num';
}
// Validate & Update User
[....]
} Where $user is from the Route model binding http://laravel.com/docs/routing#route-model-binding It's basically saying if the id that is passed in to get the object has the same username as what is from the Input then it doesn't need to be checked for uniqueness because it hasn't been updated. |
Andrew, I'm sure that would work but you can do this directly in the validation rule ala the following: 'email' => 'unique:users,email_address,10' You can see an example of this in the documentation here: |
That doesn't quite do what you want it to do. In that you're saying ignore the unique check for id 10. What if the user changes their email address? The new email address would not be checked that it is unique. You still need the check on whether the email address was updated. Unless I'm missing something in the documentation for unique. |
The way I understood it: This will check if it is unique but not for id 10. So, if the user saves without changing their email address (and the email address was present in the input array) it would ignore the uniqueness only against the id you specify (the user's id). It's not saying "Don't check if it's unique for id 10 against everyone" it's saying "check if it's unique against everyone BUT id 10" |
I have been working on this issue and manged to get it working with my own version of Confide. It can be see here https://github.com/nightowl77/confide/tree/ardentv2 My version makes saving a user super easy. First - I've thrown out UpdateRules. This is not what a developer would expect after reading the Eloquent docs. I wanted something very simple. As @Zizaco said in his first post about Confide on forums.laravel.io - we have Sentry2 for Laravel, but it is not very Laravel-ish. That's why he set out to create Confide I wanted Confide to be a bit more Laravel-ish. If I want to save a user, I want to call "save" and it should be done. No amend/clone and or Updaterules. As a consumer of Confide I don't want to handle password and uniques and all that. Granted, the functions I now use in the my version of Confide I use was not available in Ardent, so a workaround was required. That workaround was UpdateRules/amend/etc. Also, I wanted to use the power of Eloquent to decide if a user exists. I've thrown out the UserExists function that was in Confide. I now leave that up to the developer to decide. For example: some clients are ok with a user registering multiple accounts under the same email address. Some clients want only one email per user. Instead of having a config option for Confide to handle that, the developer can now handle that himself - simply by adding "unique" to his static $rules. Basically Eloquent will handle it, not Confide. With the version of Confide I'm working on, saving a user is now as simple as:
Sidenote: @andrew13 - you might know that function. It is from your development branch - repositories/EloquentUserRepository.php. I however do not return an array on error, and rather check for $user->errors()->all() in my controller. I only have "public static $rules" looking like this
I commented out "username" as the site I use this for only use email and not usernames. The important bit here is that I use ONLY $user->save for both updates and creation of new users. Currently this version is live in production on www.mybitalert.com and has been thoroughly tested for my use case. It might not be backwards compatible and it might now work for other use cases. I am working on backward compatibility here. laravel-ardent/ardent#52 (comment) Oh, another big change I made is that this version of Confide also does not return the validation error "duplicate". This did not play nicely with the awesome error handling of Former. If a user had a duplicated email, I wanted the error next to the email. If a user had a duplicated username, I wanted the error next to that. The current version of Confide does not tell you which of the 2 is in duplicate, email or username? This leaves the user to wonder why it won't accept his registration. You can see it in action by going to the link above, click sign up, and try to register with the email "nightowl77@github.com". If you want a pull request, please shout. |
Oh, just one negative thing about the version of Confide I'm running. This THOROUGHLY marries Confide to Ardent and Eloquent. Switching out the underlying Data Abstraction Layer for something other than Eloquent will basically be impossible. Functions like "UserExists" will have to come back. I do however not think this is a bad thing. Confide's original mission was to be a Laravel lib which means at least Eloquent will always be available. Making a purposefully "built for Eloquent" Auth Lib allows us to build the absolute best Eloquent Auth lib without being bogged down by all sorts of other issues. @Zizaco knew this and I presume that's why he built a seperate https://github.com/Zizaco/confide-mongo for mongo based authentication. |
@dolbex I hope it works that way. Can you confirm that it does. If so that'll simplify the rules. I will verify as well but won't be able to check until this weekend. |
@nightowl77 The functions you removed should certainly be removed. When they were added it was due to a bug in Ardent at the time. If you'd like to make a pull request I would love to review it. Getting the code base "Cleaner" would be huge. |
@nightowl77 "Oh, another big change I made is that this version of Confide also does not return the validation error "duplicate". This did not play nicely with the awesome error handling of Former." Get that pull request up :) 👍 |
I would not recommend sending a PR to the master branch. I forked this from cossou/confide and some of the small changes aren't mine. I also pull my version of ardent, but I checked - my version of Ardent is not required. It was mainly for backwards compatibility where the unsetting of usernames and passwords where handled in the controllers which would then pass their own rules to real_saves($rules). With this update it should not be required for the programmer to do that work. You can however see the major updates here. Most important is this nightowl77/confide@Zizaco:master...ardentv2#L2L171 and this nightowl77/confide@Zizaco:master...ardentv2#L2L273 I again screwed with the password update in real_save. It just makes more sense to me this way. Maybe I'm missing something, but it works quite nice the way it currently is. If you give me some time I can do a proper PR. But if you maybe start cherry picking parts of the code you like, please please let me know. For me to do this PR right I need to figure out how I'm going to consolidate a fork of a fork. It might take a little while. I'm not quite a git ninja yet, but getting there. |
I would rather do this right. Take the time to do a proper PR. I'll start taking a look just to get familiar with the code changes so I'll be ready when it comes. When do you think you'll be able to get to it? 3 days / 1 week / 1 month? Just to get some sort of idea when I should free up time to review it and merge :) |
learning a lot :) |
The biggest issue here is backwards compatibility. A LOT of programmers still call validation before saving the user. :( Case in point: https://github.com/andrew13/Laravel-4-Bootstrap-Starter-Site/blob/master/app/controllers/user/UserController.php#L92 I want to kill all that stuff, prepareRules, amend, it must all go. Updating a user should be as straight forward as updating any Eloquent model, and confide should hide all that complexities on the programmer's behalf. The big question is: is that something you'd like to put in the master branch of Confide. We are GUARANTEED to break a lot of sites because Confide isn't tagged on a regular basis (last tag was 2 months ago) and most people use "dev-master" in their composer.json (the docs actually request that) On the other hand, do we really want to be "held hostage" by backwards compatibility? I really believe that we could make some real progress here and make Confide real easy to use. Getting great authentication for a new site will be a snap, but we're going to have to break a 100 eggs to make this omelette. Someone is going to shout at us. If you have developer access to confide it might be a good idea to tag this version of Confide v1 and warn people that version 2 with a major code cleanup is coming. Also change the docs under "Required Setup" to say "zizaco/confide": "1.0.x" Let me know what you think. Must go to bed now, already 2 am but will check this thread again first thing in the morning. |
I spent my last two days looking at ammend, updateRules, getupdaterules and what not... I think nightowl77 is right. They needs to be removed 👍 |
@dolbex - that is exactly how it works. Since ConfideUser extends Ardent you can call the function buildUniqueExclusionRules() https://github.com/laravelbook/ardent/blob/master/src/LaravelBook/Ardent/Ardent.php#L750 It basically goes through your rules and will append the user id for you at the end of your unique rule. Otherwise you can try as a quick fix to pull in my version of Confide by adding this to your composer.json file Under "require"
And then in the "root"
You can see how it all fits together here https://gist.github.com/nightowl77/6144540 Your rules would then simply look like this
You would also then save your user the way you save any Ardent model. Don't do any validation before saving, do it the ardent way and check $user->errors()->all after your save call. |
I can tag it as v1.0.x. I don't like breaking people's applications but at some point it doesn't matter. Let's get v2 up and running. |
Tagged version v1.0.1 |
@dolbex of note for buildUniqueExclusionRules you'll just want to call update instead of save. |
You can send a PR to a new branch? That makes me a lot more comfortable. Every day I learn something new! Thank you Andrew. To answer your question regarding "when", I'm working on it right now, and hopefully I can have it done some time today. It would be days rather thank weeks. |
@nightowl77 I made a develop branch since that's where these type of things usually go. PR to that. Great news on a couple days. |
@andrew13 Thank you very much for that! :) I'm just waiting on that pull request above for Ardent. It's not really needed since Confide will now handle all rules internally, but there could always be that 1 use-case where a user want to pass in rules. Plus I don't really want to break compatibility and change the function parameters of real_save. With the current Ardent you cannot pass $rules to either updateUniques or buildUniqueExclusionRules. The moment that PR is accepted I'll push what I have. |
Looking forward to it! |
That issue laravel-ardent/ardent#86 has been sitting in the queue for more than a week now. Can someone please help the maintainers of Ardent by pulling down my version and reviewing the code. Can someone also confirm on that thread that
is the same as
I think that might be one of the issues holding them up. |
What is $class defined as? |
Hi Andrew To answer your question. In the original buildUniqueExclusionRules they used protected function buildUniqueExclusionRules() {
// Because Ardent uses statics (sigh), we need to do this to get the
// model's rules.
$class = new \ReflectionClass($this);
$rules = $class->getStaticPropertyValue('rules'); I then changed it to protected function buildUniqueExclusionRules(array $rules = array()) {
if (!count($rules))
$rules = static::$rules; As far as I know, you don't have to use I made another commit on that pull request (laravel-ardent/ardent#86) this morning. I even updated the docs, so hopefully they will accept it this time. |
So I didn't understand, is this project going to still depend on ardent or not ? I'm using the fixed version of ardent of @nightowl77 because in my case I need to pass rules to updateUnique() (and it's bugged with the actual ardent version as you know). In my case I need custom rules when a user edit his profile, he can edit all the field he wants but, if he edit his password, he must enter his previous password (for security reason because csrf can be bypassed if there is a XSS vulnerability). The problem is when he doesn't edit his password i have to remove password rules otherwise it won't pass the validation (because all the form input are filled but password). I can fix the this doing
|
How about we set this to @nightowl77 Ardent version? |
From the Ardent discussion: |
@nightowl77 Ready for the pull request when you are. Ardent has finally updated their code. So we should be good to go now. |
Maybe I'm missing something here but removing 'unique' from email and username may be an issue in the updateRules for validation. Shouldn't we just be appending the exception id as noted in the Laravel docs?
Doesn't this allow anyone to edit their email / username with an existing username or email in the system?
The text was updated successfully, but these errors were encountered: