input extension - opinion!

Hey guys!

I’ve been testing this excellent extension but i got a question, where is better to use it, in controller or model?

E.g.

Controller:




public function actionRegister()

{

                ...

                $model->attributes = Yii::app()->input->post(get_class($model));

                if($model->validate() && $model->save())

                ...

}



Model:




public function afterSave()

{                

                $this->email = Yii::app()->input->stripClean($this->email);

                $this->password = Yii::app()->input->stripClean($this->password);


                return parent::afterSave();

}



Btw… is always better to use stripClean since it includes the methods stripTags() and xssClean() right ?

I recommend preloading the input component, then enable global post/get cleaning, this way you have nothing to worry about, even if $_GET/$_POST is used directly.

Next, in controllers, you can do smth like, i don’t think that is a security risk or something:




$model->attributes=Yii::app()->input->post(get_class($model));

$model->save();



Another good way is to overwrite the CModel::setAttributes() ( http://www.yiiframework.com/doc/api/1.1/CModel#setAttributes-detail ) method, something like:




public function setAttributes($values,$safeOnly=true)

{

    if(!is_array($values))

        return;

    $attributes=array_flip($safeOnly ? $this->getSafeAttributeNames() : $this->attributeNames());

    foreach($values as $name=>$value)

    {

        if(isset($attributes[$name]))

            $this->$name=Yii::app()->input->stripClean($value);

        else if($safeOnly)

            $this->onUnsafeAttribute($name,$value);

    }

}



Then when massively assigning attributes, those will be sanitized(though if you enable global post/get cleaning, this makes no use)

Also, you can create a behavior class, extending CActiveRecordBehavior and use the beforeSave()/beforeValidate() event handler to clean the attributes.

There are many ways to accomplish this, as you can see, but the idea is that you need to be sure that when your attributes are being saved into database, they are in a clean state.

Personally, i use a behavior that i attach to each model, and that behavior binds to CActiveRecordBehavior::beforeValidate()/CActiveRecordBehavior::beforeSave() and cleans the data.

Whichever you’d choose, have in mind that if you use wysiwyg editors, you’ll need to treat those attributes in a special manner, (those attributes needs to be cleaned with the CmsInput::purify() method because you’d want to keep the html content, therefore you’ll have to make use of CmsInput::getOriginalPost()/CmsInput::getOriginalGet() to retrieve the original values and clean them with CmsInput::purify())

Hmm strange… if i use,




$model->attributes=Yii::app()->input->post(get_class($model));

$model->save();



and for example, the user entered something like ‘ERfFERttg&fghGH&’ the application saves an ‘;’ in the end of the string, i.e. ‘ERfFERttg&fghGH&;’

Since this field is a password, when the user goes to login, the password is always incorrect!! Did i miss something ?

on my config file (main.php):




'input'=>array(   

          'class' => 'CmsInput',  

          'cleanPost' => true,  

          'cleanGet' => true,

          'cleanMethod' => 'stripClean',

),



re-check your code, the extension has nothing to do with the ";" at the end of the string.

Also, make sure magic quotes are off on the server, just in case.

I really dont know what to do more to solve this issue… i’ve checked the magic quotes and are all off, i already have done an small test and same thing is happening… and my last test was a debug… and looks like CI_Security.php is replacing the string with an extra ‘;’.

Check the images please, if you can make some test and try to add a string like ‘test&gtre12&b’ and see if you have the same thing.

Ty in advance!

Yes, your tests are correct, but that’s happening because the CI_Security tries to fix the broken html entities, mainly the issue is that it sees the &45f part of the password, then it will add the semicolon to try to transform it into a html entity.

This is good for most of the times, but for cases like yours, it isn’t needed i think.

However, even with this behavior, you should have no problem with the user input, even if the ";" is added when saved into database, it will also be added when the user insert the password for login and you check it against database.

Also, if you don’t want this, just comment the CI_Security code so that this doesn’t happen for you, but i really don’t think it’s the case.

Anyway, you wouldn’t store the passwords in plain text in database, just use sha1() / phpass library for this and save the hash into database, then, when the user needs a new password, just generate a new one, you don’t have to send the password from the database.

Yes, i’m not storing the passwords in plain text in database, i’m already using PHPASS… this was just for testing, to see when and how the system adds the ‘;’ into the user input.

I’m going to make a new test when the user register/authenticates in this situation to see how it work the ‘input’ with ‘phpass’ in this situation.

Okay, please keep me updated with this:)

Yeah, you are totally right twisted :)

After doing some tests with ‘input’ in login/register scenario to see and trying to understand why the ‘;’ is added to the user input when he write something with ‘&’ character and if this going affect in some way the data, i confirm what you said to me in one of your last posts.

‘;’ is only added if you put the character ‘&’ with at least two or more characters in front (e.g. 345&34 / s&t3l, etc…) and that’s makes sense, like you said, the CI_Security tries to fix the broken html entities.

I was doing a terrible confusing!! If was introduced the password ‘qwe&rty’ why the hell the system is saving ‘qwe&rty;’ on my db!! Ok, now i know!

I was also asking, hmm if on register, the password was ‘qwe&rty;’ why on login, if i write ‘qwe&rty’ it always working… like its missing the ‘;’ that i put on register, but this makes sense and its 100% correct, just remember… if i used ‘input’ on register to clean the data then i also need to use it on login because hes going to do the same things that have done on register, in background the ‘input’ add the ‘;’ also to validate!

Some examples that i tested, and you can see what the ‘input’ does:




my pass:	input pass:

qwe&rty		qwe&rty;

qwe&rty;	qwe&rty;

;&qwe&ty	;&qwe;&ty;

#;&qwe&&ty;	#;&qwe;&&ty;

#;&qwe&&ty&;	#;&qwe;&&ty;&;

qwe&rty#$%&;	qwe&rty;#$%&;

qwe&rty#$%&	qwe&rty;#$%&

qwe&rty;#$%&T	qwe&rty;#$%&T

qwe&rty;#$%&t	qwe&rty;#$%&t

qwe&rty;#$%&tt	qwe&rty;#$%&tt;

q&w&e&r&t&y&oo	q&w&e&r&t&y&oo;

q&ww&e&r&t&y&oo	q&ww;&e&r&t&y&oo;

&aa;;;;;;	&aa;;;;;;



Ty twisted for all your help and efforts trying to explain me about your extension!