Should I only add validation criteria to user input in CakePHP? - cakephp

When baking models in CakePHP, should I add validation criteria only to the data which are user input? Or to everything? Or to some specific data? The database consists mostly of things which will be added by admins. There's only 1 user-related table. I'm not sure about this. Thanks.

Validate everything!:
Validation to everything. There's no reason not to add validation to everything. If an admin knows what they're doing, and is inserting data per the requirements, they won't see any of the validation errors anyway. But - if they have a moment of insanity, or just don't know what's allowed/not, then having the validation is a great fallback.
We've all done it (or... NOT done it):
It's understandable for a small/simple project to not want to spend the time adding validation - we've probably all done it... but when asked "SHOULD you add validation to everything?", I think the answer has to be "yes!".
Validation - not just for user-generated content:
Validation is overall great - not just for user-entered data, but also for scraped, code-generated data, admin-entered data, and everything in between.
Can be slightly lax... if you must
If most of your data isn't user-generated, you could always think about making the validation slightly more lax than it would be otherwise, but - having it is still better than not.

Related

Should I avoid modifying user inputs before sending to backend if possible?

I'm validating and sanitizing user inputs from the server-side. I'm also validating it from the front-end. But I'm wondering if I should also modify the input values to match the server's requirement before sending a request.
For example, I have a form with a birthday text input in MM-dd format. But the server requires a month(MM) and a day of the month(dd) values separately. I can format the input to match the server's requirement(MM and dd), or I can just pass the value without modification and the server will do the rest. Which method is recommended?
This question is more related to UX practices then frontend itself. I believe that before server validation, frontend checks should be performed.
You shouldn't validate and you definitely shouldn't change any values during user completing the form. However the common practice is to validate fields on blur. This is when you can change fields values.
However I would be very careful with this, to avoid confusing the user. So stripping whitespaces etc. should not be a problem, but aggressive input changes should be avoided.
Also try input masking for operations like date formats.
Check for example this library
https://nosir.github.io/cleave.js/
EDIT:
I case of changing values before sending them to backend, it's perfectly fine. It's good practice to have some mapping layer, which will map between UI forms and DTOs required by backend. UI should be focused on user experience, so some extra work will be required almost every time in more complex scenarios

Adding validation to controllers in Cake 3.x

In CakePHP 3.x is it acceptable to add validation rules within a controller?
I've read http://book.cakephp.org/3.0/en/core-libraries/validation.html but it doesn't actually say where you (can / should) add your methods.
I understand that typically these go in src/Model/Table/ModelName.php. However I'm trying to validate a form which is not tied to a particular database table and doesn't need a corresponding model.
I'm familar with Cake 2.x where I would typically do this in the controller, or possibly add a model with $useTable = false. But in this case the simplest method seems to add the rules directly in the controller, but I wasn't sure whether this is bad practice. If the rules don't go in the controller where should they be put?
Context - this is a form where the user is doing a search. It requires some input and I'm trying to validate 3 fields: email, quantity and a postcode. Cake's validator has inbuilt features to do the first two but in the case of postcode I'll need to add a custom method.
Any advice appreciated.
In CakePHP 3.x is it acceptable to add validation rules within a controller?
Technically possible, but I would consider it as bad practice.
I understand that typically these go in src/Model/Table/ModelName.php. However I'm trying to validate a form which is not tied to a particular database table and doesn't need a corresponding model.
There is a whole section called "Modelless Forms" in the book that covers that use case.

Validation stages

I am validating with Cake 3 but can't get it working probably.
As the docs says there are two stages of validating:
Before you save your data you will probably want to ensure the data is correct and consistent. In CakePHP we have two stages of validation:
Before request data is converted into entities, validation rules around data types and formatting can be applied.
Before data is saved, domain or application rules can be applied. These rules help ensure that your application’s data remains consistent.
So, if I understand this right, at first validation rules are used when I pass data via newEntity and patchEntity.
After that, the application rules are used when using save or delete.
However, when I am passing data (an array) via newEntity the application rules are never used (buildRules is never called). When using newEntity without passing data, application rules are used!
So, my first question, is it right that not both rules are runned, only one (OR validation rules, OR application rules?). I would expect that first validation rules would be called to check the input, and before saving, ALSO the application rules would be called to check if the entity is valid to the applicaton.
Second question, how should I validate with my API? The actions pass their data via the newEntity method, but I want to check if (for example) the category_id belongs to the same user. Thats typical an application rule I guess?
Thank you very much ;)
Quoting CakePHP documentation:
Validation objects are intended primarily for validating user input, i.e. forms and any other posted request data.
Basically, validation is done when you use newEntity or patchEntity to check that the incoming data is consistent:
You don't have a random string where you should have a number
The user email is of correct format
Standard and confirmation passwords are equals
etc.
Validation is not done when you set field manually:
$user->email = 'not a valid email' ; // no validation check
Basically, validation rules are meant to tell the user « Hey, you did something wrong! ».
Application rules on the other end are always checked when you call save or delete, these may be used for:
Checking uniqueness of a field
Checking that a foreign key exist - There is an Group that correspond to your group_id
etc.
Your first assumption is somehow false because in the following scenario, both validation and application rules are checked:
$article = $this->Articles->newEntity($this->request->data);
$this->Articles->save($article) ;
This part of the documentation explain the difference between the two layers of validation.
Concerning your second question, you should not check that a user has the right to do something in your model, this should be done by your controller, see CakePHP book for more details.

Q: Is the password hash in $user not beplaced by *

In my old cakephp 2.x Applications, the password hash was hidden by '*' when I retrieved the data from the User Model. I am not a hundret percent shure, but I think this was done automaticly by Cake.
Now testing Cakephp3.0, I am surprised finding the complete hash when retrieving data from the User Model.
I got a few questions concerning this password-hash-hiding:
Am I right with my opinion this was a function in cakephp2?
Does anyone know, why this function was not implemented in Cakephp3 and why?
If I am wrong by assuming this was included in cake, where is the place to implement this functionality in cake2 and cake3?
Thank you very much for your help.
Am I right with my opinion this was a function in cakephp2?
Yes, in Cake 2.x this is part ot the Debugger, the data itself however is not being touched, just some of the content is being masked when outputting the data.
Does anyone know, why this function was not implemented in Cakephp3 and why?
It is still implemented, but it has been moved. The whole point of this masking thingy was to avoid accidental exposure of datasource credentials (mainly in error messages/pages), it never really had something to do with possible user model data, this is just a side effect for data that happens to use keys like password.
So in 3.x this functionality has been moved to \Cake\Database\Connection::__debugInfo()
https://github.com/cakephp/cakephp/pull/4542
This ensures that you'll still end up with masked credentials when for example debugging connection objects, being it explicitly, or implicitly on error pages, while it doesn't obstruct debugging other data anymore.
[...], where is the place to implement this functionality in [...] cake3?
This highly depends on your use case, if you'd for example wanted to have it masked in debug output, then you could implement it in an overriden __debugInfo() method in your user entity class, similar to how the Connection class is doing it.
https://github.com/cakephp/cakephp/blob/3.0.11/src/Database/Connection.php#L702
Of course this would only work for entities, not for non-hydrated data (array data).

Ways to avoid CakePHP $this->data security hole?

I just realized when doing basic CakePHP stuff, that there is quite bad security issue, which many don't necessarily notice. I'll just take this basic function that I think many users use while doing CakePHP driven apps.
function edit() {
if(!empty($this->data)) {
if($this->User->save($this->data)) {
}
}
}
Lets assume user has privileges to use this action. This action could be editing user information, which may have like city and number and ofcourse username. Lets assume that we want to have a form that allows us to edit just the city and number but not the username. Well what if someone just inserts that username field into that form with firebug for example? Then submits the form. Now the edit would just grab all the post information, including the username field and its value and edit them straight away. So you can change your username in this case even though there werent a field for it.
This can go even further, if someone would use saveAll(), which allows you to validate and save multiple models in one shot. If you could guess from form fields the models to use, you could easily go to other models and tables aswell and alter those information.
Now that you understand my concerns, my question is what would be the best or atleast near the best method to avoid this?
I know I could just grab the data I want from $this->data to other variable and then pass that to the save or saveAll, but because there are many forms and ajax requests, that would be quite a lot of work. But is it the only way to go or are there better ways?
Should I make or is there a behavior which could stop this? Like checking what variables some action in some controller can get from post?
After couple of days research I found that this is not really a "security hole", but rather beginners mistake.
There are two ways avoiding this type of form tampering: Security component ( http://book.cakephp.org/view/1296/Security-Component ) which automatically gets CSRF and form tampering protection by creating one-time hashes for form fields.
The other way is to give the third parameter to save() function. The save actually gets 3 parameters: data, validate, fieldlist. The fieldlist parameter acts like whitelist of fields that are allowed to be saved.
I first reported this problem as a bug to cakephp which it then wasn't but this euromark guy replied to me that he had done nice documenting about the actual problem and how to do secure saves and I really think it was quite good reading. So if you have the same problems, please see this page: http://www.dereuromark.de/2010/09/21/saving-model-data-and-security/

Resources