zen of coding

'required'=>true… the source of major confusion

In all the time I’ve been following cake on IRC (almost daily), it has become very clear that other than ACL and maybe Auth, ‘required’=>true in the model validation is the most confusing part of CakePHP for many people.

On IRC it comes up, probably, once a week… even from people who’ve “been around”.
And I can imagine that there are a lot of apps out there, where ‘required’=>true is used, without fully understanding as to what it really does.

The problem is that people are quick to assume that ‘required’ means ‘notEmpty’.
Even after pointing people to RTFM, they still come back confused as to the real meaning of ‘required’.

Who cares, right?

Well… we often hear a complain about save() failing (very often) without any apparent reason.
The issue boils down to people having ‘required’=>true in the validation rules, while in reality they only wanted ‘rule’=>’notEmpty’.

When first creating the Model such setup has no ill effects, because all fields are in the data array and the record can be successfully added and even edited (assuming some basic forms).
Then at some point the app becomes a little more complex and people decide to save only a few fields at a time… and of course the validation fails.

This leads to debauchery on IRC, dents in the wall from banging the head, and other nasty side-effects.

My proposal… rename ‘required’ to something else. Doesn’t matter what, just not ‘required’.

The reality of the situation is that, if the key was named ‘mustBeInDataSet’, people would never even bother to include it, unless it was really needed… and lots of mess and confusion would be avoided.

Looking at the code, it doesn’t seem like a major change… although I’ve not done any testing (but I promise that I will).
Just wanted to get some feedback on this issue first….

  • I have noticed a lot of people DON’T user required => true because it breaks their forms that only save a few fields at a time. Most of them don’t think about it, but when they do not use required => true, then the field really is in fact not required, and all a hacker has to do it use a firefox addon such as UrlParams (https://addons.mozilla.org/en-US/firefox/addon/1290) to hack their site and bypass saving certain fields.

    And the only solution for those people is to extend cakephp in someway and add logic for this (I did it in appModel::beforeValidate). When I come around to creating a blog I’m going to blog about this :p

    I even hacked the cakephp bin the other day with this method to prove my point (saved a code snippet without a nickname which was supposed to be required). There was another blogger’s website that I did this to also. Then I created a ticket.

  • @Jonah

    Not exactly, and really that wasn’t the point of this post. Even with ‘required’=>true, there is absolutely nothing that prevents a hacker from adding some field such as ‘id’ to my data array and triggering an UPDATE instead of INSERT.

    A correct, and simple solution, is to use save() with a third param, which is a list (whitelist) of fields that need to be saved. Not everybody does it, but it’s readily available.

    Also, to further secure your application you can use the Security component to create a hash based on the form fields, and only when the hash matches the passed fields would the save() be allowed.

  • In your comment you are talking about the security issue of a hacker putting extra fields into a form such as ‘id’ to screw with you. Yes, this can be fixed with the save() third param. What I am talking about though is a hacker _bypassing_ a field – the complete opposite of throwing in an extra field in. There is no easy way to fix this security issue currently, except by setting ‘required’=>true, but as I was saying, this will break forms that only are only supposed to save a few fields. For instance, a user registration action may require the email field, while the login action does not, thus, you will not be able to use ‘required’=>true as it will break the login action. So ‘required’=>true is not usable to many people because of this (this was your point in you blog post). But my point is that the ‘required’=>true rule is the only way to securely make sure that certain fields *have* to be saved with data (notEmpty can be bypassed by not setting the data variable in $_POST).

    To clarify, the whitelist in the save() funtion represents all the fields that are allowed to be saved, but it does not represent fields that _have_ to be saved.

  • Phally

    You are absolutely right. The name ‘required’ make it look similar to the ‘notEmpty’ rule. Another name would save some confusion, but ‘required’ works just fine (when knowing what it does). So i don’t think it won’t have much priority. Have you filed a ticket?

  • One other thing to notice with required=true is that CakePHP uses this flag with the form helper to add a “required” class to the field.

    There is no other way to do this short of manually adding the class to the $form->input() arguments.

  • @Jonah

    What about using the Security component (as I mentioned), which handles such things a little better than ‘required’=>true, IMO. Anyways, the point of the post was the confusing name of ‘required’, whether or not or how you use it is a whole different story :) (Actually, I should probably do another post on showing how to use the Security component).

    @Phally

    I didn’t see a point of opening a ticket without any testing, etc. Just wanted to stir up some trouble and maybe clarify a few things about this confusing key.

    @Richard@Home

    Good point, well I would hope that if at some point the rename does happen this would also be taken into account. Personally, I think it should be based on validation rules (i.e. if any validation rule is present, the field should be styled as required, note the confusing terminology once again) :)

  • etipaced

    I’m surprised no one has mentioned the ‘allowEmpty’=>bool key yet. I agree that ‘required’ is a little confusing at first, but once taken in context with the ‘allowEmpty’ key, the distinction between the two becomes clear. Oddly (or not), I haven’t yet used the ‘notEmpty’ rule in my validation. I like ‘allowEmpty’=>false better for some reason.

  • Regardless of the rule itself being *exactly* what it means or not, it seems like it’s almost a part of a semantic rule. I use it when my database does indeed not allow the field to be null, in combination with notEmpty (or “minLength,1” when notEmpty wasn’t yet re-introduced in 1.2). Whether it’s overkill or not, as Richard@Home points out, I like the auto-class generation when using the FormHelper on fields declared with required=true.

  • @etipaced

    Sure, using ‘allowEmpty’ is fine, but it has to be used in conjunction with ‘required’=>true, which is the whole point that causes the problems, when used incorrectly. Now throw in ‘allowEmpty’ into the mix and you’ve got even more confusion going around.
    Both keys work perfectly fine, when the person understands how they behave. The reason I’m bringing up this issue is that a lot of people, who are new to cake do not get it, and use ‘required’ (due to it’s confusing name) incorrectly.

  • @Brendon Kozlowski

    Yes, that’s all true, but the main point is still the same… ‘required’ is a confusing name, as it has been proven time and time again. That’s all I’ve been trying to really say here :)

    By the way, I’ve noticed that required class will appear in some cases, even without ‘required’=>true. I actually saw that when I built the form in my following post. The only field that did not have a required class added, was ‘password’… why? No idea.

  • francky06l

    I agree that required is confusing. I am sometimes on IRC and Google group and I see that generates a lot of confusion since people will tend to set “required” instead of “notEmpty”.
    Actually you can have a required empty ….. Even if required is kept, maybe another “alias” for it .. (setInAllForms or whatever) ..
    To me “required” is very explicit, but maybe it “requires” some practice of cake..
    Concerning the password with no “required” class, maybe just because when it’s empty, the hashed password will make not empty (just an idea) ?

  • @francky06l

    I was trying to get to the bottom of that, but got totally side-tracked with work and other things… hopefully I’ll have some time to investigate a little more this week.

  • Pingback: Confusing cakephp validation rule ‘required’=>true | Jojo Siao Weblog()

  • Pingback: Как сделать формы в CakePHP более безопасными | Bunyan.Ru()

  • can u explain to me what is ‘required’ all about? how to use these in the script?

  • caribean

    can i use that using php?

  • @caribean

    No, this is a specific issue that deals with a CakePHP framework. It has no meaning in plain PHP.

  • Christopher Vrooman

    There is another option for those who want to keep using ‘required’ => true…

    Jonathan Snook’s Multivalidatable behavior: http://snook.ca/archives/cakephp/multiple_validatable_behavior.

    You define what fields are to be validated for various scenarios, usually dealing with the User model: registration, confirmation, login, password reset etc, and then in the controller you can set which group of validaton rules to apply depending on what page you’re on.

    Cheers

%d bloggers like this: