cakephp validation fails on sql injection - php

i installed a plugin on my firefox browser which is called "SQL Inject Me" and then I tried it against my Cakephp website. I see that it was able to inject few blank accounts (some with password) and some without password. The database is not allowed to accept null values for username, emails etc also I'm not sure how is it able to bypass cakephp validation.
my cakephp validation for username field
'username' => array(
'username must not be empty' => array(
'rule' => 'notEmpty',
'message' => 'username field cannot be empty'
),
'username must be unique' => array(
'rule' => 'isUnique',
'message' => 'username is already taken'
)
'username must not contain special character' => array(
'rule' => 'usernameValidation',
'message' => 'username can only contain numbers, characters, underscores, dashes and Periods. Underscore, dash and Period are only allowed in the middle.'
)
)

I think your validations has wrong keys. That should be like this..
var $validate = array(
'username' => array(
'notEmpty' => array(
'rule' => 'notEmpty',
'message' => 'username field cannot be empty'
),
'isUnique' => array(
'rule' => 'isUnique',
'message' => 'username is already taken'
)
'usernameValidation' => array(
'rule' => 'usernameValidation',
'message' => 'username can only contain numbers, characters, underscores, dashes and Periods. Underscore, dash and Period are only allowed in the middle.'
)
)
)
and while saving them you just have to call validate function to go through the validation rules. Below link can help you to how to validate from controller while saving the data.
http://book.cakephp.org/2.0/en/models/data-validation/validating-data-from-the-controller.html
Thanks..!

Add the keys 'required' => true, 'allowEmpty' => false to your validation arrays.

Validations were failing because if you remove fields from a form using developers tools like firebug then cakephp validations will not work for those removed fields.
what i did to fix these issues is to use this code right before passing data to save method.
if(!(isset($this->request->data['User']['email']))){
$this->request->data['User']['email']='';
}
if(!(isset($this->request->data['User']['username']))){
$this->request->data['User']['username']='';
}
if(!(isset($this->request->data['User']['password']))){
$this->request->data['User']['password']='';
}
if(!(isset($this->request->data['User']['confirm_password']))){
$this->request->data['User']['confirm_password']='';
}
If there is a missing field then this code will add that field and assign an empty string to it. Then those fields will be eligible for validation and will eventually fail validation.

Related

Changing validation on the fly in CakePHP

I'm using CakePHP 2.3.8 and I'm trying to figure out if there's a way to set certain validation rules to required on the fly.
For example, my User model has phone_number, username, email, and password validation. If a user wants to change their username, their phone number isn't required to do so. That means I can't set it to required, because then when changing a username, the phone_number will be expected to be present in the data.
public $validate = array(
'username' => array(
'minLength' => array(
'rule' => array('minLength', '3'),
'message' => 'A username with a minimum length of 3 characters is required'
),
'unique' => array(
'rule' => 'isUnique',
'message' => 'This username has already been taken.'
)
),
'email' => array(
'email' => array(
'rule' => array('email'),
'message' => 'Please enter a valid email address.',
),
'unique' => array(
'rule' => 'isUnique',
'message' => 'This email address is already in use'
)
),
'password' => array(
'rule' => array('minLength', '8'),
'message' => 'A password with a minimum length of 8 characters is required'
),
'phone_number' => array(
'rule' => array('valid_phone'),
'message' => 'Invalid phone number',
)
);
To get around this problem, in my controller for the corresponding action what I've been doing is checking to make sure the expected inputs have been posted. If not, set that index to null so that it is validated...such as
public function change_username(){
if(!isset($this->request->data['username'])){
$this->request->data['username'] = null;
}
$this->ExampleModel->set($this->request->data);
//if it wasn't posted, the username index will be created but set to null. This is my workaround for setting something to "required"
if($this->ExampleModel->validates() == true){
//do something
}
else{
//do something
}
}
While this works, I feel like it makes for a lot of extra coding, especially if I have a form that has a lot of inputs.
I've also tried to validate only the inputs that I need, but unless the data was posted, it ignores them. For example
if($this->ExampleModel->validates(array('fieldList' => array('phone')) == true){
.....
}
If "phone" wasn't posted, it doesn't validate it.
Is there any way to set required for a given input's validation to true on the fly? I found this article on using multiple validation rulesets and while it would accomplish what I want, there would be a lot of re-coding involved.
Before validation, can I set an input to required?
Firstly, in your Model validation rules you have phone_number but yet trying to validate phone, there aren't validation rules for phone.
It would be ideal request->data[] to match model fields, you can rebuild an array etc.
From book.cakephp:
This will add a single rule to the password field in the model. You can chain multiple calls to add to create as many rules as you like:
$this->validator()
->add('password', 'required', array(
'rule' => 'notEmpty',
'required' => 'create'
))
->add('password', 'size', array(
'rule' => array('between', 8, 20),
'message' => 'Password should be at least 8 chars long'
));

Cakephp Special Character Validation

I want to to set validation rule in model for user enter only special character only into text field .so please suggest me proper solution.
demo code is
public function addValidations()
{
parent::addValidations();
$this->validate['Field name'] = array
(
'notempty' => array
(
'rule' => array('special char', 'msg',),
'allowEmpty' => false,
'message' => 'Enter Special character only.',
),
);
}
you can define Custom Regular Expression Validation
public $validate = array(
'login' => array(
'rule' => '/^[\W]+$/',
'allowEmpty' => false,
'message' => 'Enter Special character only.'
)
)
// '/^[\w.-]+$/' this will allow only special character.

CakePHP Negated RegEx not working

I am trying to enforce the first name of my model to be any character but numbers, but so far it's not working as expected. When I try this:
public $validate = array(
'first_name' => array(
array(
'rule' => array('custom', '/^[\d]+/'),
'message' => 'Please fill in a valid first name'
)
)
);
it doesn't work because I'm able to save 4 as the name. If I move the negation to within the brackets like so:
public $validate = array(
'first_name' => array(
array(
'rule' => array('custom', '/[^\d]+/'), //allow anything but numbers
'message' => 'Please fill in a valid first name'
)
)
);
It also doesn't work because I'm able to save a4 as the name. So how can I get best of both worlds without having to include both custom validation rules?
/^[^\d]+$/ allows anything but numbers

CakePhp: Form validation on several fields?

I've some conditions to a form to be valid that has to be on several fields instead one, how to do this.
Some example for a registration:
enterprise or firstName+lastName filled
mobile phone number OR static phone number filled
How to do this? Is there an implemented way or I've to do it myself every time?
Thank you
Write your own validation rules. Cake Book: Custom validation rules
Attach a rule to the enterprise field what checks if it is filled or the first, last names are filled. Attach another rule to the name fields to check if the names or the enterprise fields are filled. Similar to the phone fields. You are in the model so you can reach all passed fields in $this->data
I am not sure if I understand the question correctly but you can create your own validation rule and then apply it for the desired fields (not really the other way around). See here
Otherwise Cakephp has a lot of pre-built validation rules here is an example:
var $validate = array(
'title' => array(
'titleRule1' => array (
'rule' => array('minLength', 1),
'required' => true,
'allowEmpty' => false,
'last' => true,
'message' => 'Please enter a title.'
),
'titleRule2' => array(
'rule' => array('between', 1, 100),
'message' => 'Your title must be between 1 and 100 characters long.'
)
),
'description' => array(
'rule' => array('minLength', 1),
'required' => true,
'allowEmpty' => false,
'last' => true,
'message' => 'Please write a description.'
)
);

User validation not working properly in CakePHP through the User Model

For some reason, I can't get this validation to work as I'd like it to, specifically with the password minLength field.
Everything else is fine (even the minLength for Username works). For some reason, when I add the same minLength rule into the password field, it just ignores it and when I actually do enter in a password, it tells me that I need to enter a password:
var $validate = array(
'email' => array(
'email' => array(
'rule' => array('email', true),
'required' => true,
'allowEmpty' => false,
'message' => 'Please enter a valid email address'
),
'isUnique' => array(
'rule' => 'isUnique',
'message' => 'This email is already in use'
)
),
'username' => array(
'notEmpty' => array(
'rule' => 'notEmpty',
'required' => true,
'message' => 'Please enter a valid username'
),
'allowedCharacters' => array(
'rule' => '/^[a-zA-Z]+[0-9]*$/',
'message' => 'Please enter a valid username'
),
'minLength' => array(
'rule' => array('minLength', 3),
'message' => 'Please enter a longer username'
),
'maxLength' => array(
'rule' => array('maxLength', 23),
'message' => 'Please enter a shorter username'
),
'isUnique' => array(
'rule' => 'isUnique',
'message' => 'That username is already taken'
)
),
'password' => array(
'notEmpty' => array(
'required' => true,
'allowEmpty' => false,
'message' => 'Please enter a password'
),
'minLength' => array(
'rule' => array('minLength', 4),
'message' => 'Please enter a longer password'
),
'passwordConfirm' => array(
'rule' => array('checkPasswords'),
'message' => 'Passwords must match'
)
),
);
Am I overlooking something minor? It's driving me nuts.
This happens because in Cake, the password field is automatically hashed as soon as you submit it; which will break your validation rules (a 5 character password suddenly becomes a 40+ digit hash). There are various proposed fixes for this problem.
One that sounds the most promising:
Create two fields e.g pw and pw_confirm as opposed to password and confirm_password. Use these values for your password validation (so, max length etc)
Then something like:
$this->User->set($this->data);
if ($this->User->validates()) {
// all your data validates, so hash the password submitted,
// ready for storage as normal.
$password_hash = $this->Auth->password($this->data['User']['pw'];
$this->data['User']['password'] = $password_hash;
}
This way, Cake won't automatically hash the passed that's entered - allowing your validation to function as you intended.
To visualise this, add this to your register/add user method:
function admin_add() {
if (!empty($this->data)) {
debug($this->data);
exit;
You'll get:
Array
(
[User] => Array
(
[username] => somename
[password] => 25ae3c1689d26b20e03abc049982349482faa64e
)
)
before validation takes place.
It looks like you have a small mistake in your validation array.
Every validation for a field must have a 'rule' key, and you don't have that in your 'notEmpty' validation.
Try updating the password validation like this:
<?php
array(
'password' => array(
'notEmpty' => array(
'rule' => 'notEmpty',
'required' => true,
'allowEmpty' => false,
'message' => 'Please enter a password'
),
'minLength' => array(
'rule' => array('minLength', 4),
'message' => 'Please enter a longer password'
),
'passwordConfirm' => array(
'rule' => array('checkPasswords'),
'message' => 'Passwords must match'
)
))
?>
Also, note that if you're using the Auth component your password will be hashed BEFORE it is validated. This means that even if you enter a 3-character password you'll end up with a 40-character hash, which obviously will validate as being longer than the minLength.
use my change password behavior. it takes care of all those things at a single and clean place:
http://www.dereuromark.de/2011/08/25/working-with-passwords-in-cakephp/
you will most certainly have more problems later on otherwise
because you need a lost password and change password functionality as well.
and maybe a backend for the admin to simply change passwords as well
and to your problem i already commented:
"you should also use last=>true here! otherwise it doesnt make much sense"
i believe this is also part of your problem. all your rules need this param to make it work properly. the error messages will be off otherwise.

Categories