In order to have best up to date protection for users against XSS attacks the data should rather be sanitized when displayed to users rather than at the moment of db insert, if I got this at all correct. So my question is can I automate data sanitization in CakePHP so that the linked models automatically retrieved by Cakes queries are sanitized at point of queries as well? Or should I always manually loop calls for all the linked models' sanitization methods?
All output that is not passed through one of the core helpers or foreign helpers that are known to take care of it should be passed through the h() method in the views.
echo h($model['Model']['name']);
If you want to do it in the model the Model::afterFind() callback is the right place to modify the data. But I would not recommend to sanitize everything there because there are cases like editing the data or exposing the same data to an API or as JSON that might require no or a different sanitization.
See HtmlPurifier and HtmlPurifier for CakePHP as well. It is a strong filter and sanitation lib.
In your views, just use
<?php echo h($data['Model']['field']); ?>
h is a wrapper for htmlspecialchars().
Related
I am writing a search function that enables users to search a particular table on my database. My website runs on CodeIgniter.
For the search function, I use $_GET instead of the CodeIgniter $this->input-get() since I had trouble using the latter within a helper function.
Now, here's a security question:
What is the best way to sanitize and filter malicious characters in the $_GET array in order to prevent XSS and SQL injection?
Bearing in mind that data in the $_GET array will be used to query the database and retrieve info from it.
Is there a recursive way to clean the entire $_GET array without having to go thru one by one element?
Should I use PHP's filter methods or CodeIgniter's?
Any advice will be greatly appreciated!
Thanks in advance!
Codeigniter disables $_GET by default. Using the URI class you can simulate $_GET variables:
GET parameters in the URL with CodeIgniter
You can hack around it and use $_GET, which it sounds like you've done. But I wouldn't recommend that. You should use CodeIgniter's Input class. That provides XSS filtering and you can clean the entire $_GET array by running:
$this->input->get(NULL, TRUE); // returns all GET items with XSS filter
If you use Codeigniter's database utility class to run your queries, it has an escape function built in. Look at the Escaping Queries section.
http://ellislab.com/codeigniter/user-guide/database/queries.html
You can use $this->db->escape($variable) to escape values in queries. It is strongly recommended to use CI's input class though.
Read more at : http://ellislab.com/codeigniter/user-guide/database/queries.html
I am building a db intensive application in yii . So performance and security are naturally a concern . Apart from that form validation is also a major criteria . For security I plan to use parameter binding for all Sql Queries . For validation I want to use validators provided by Yii instead of rolling out my own . I am aware that performance takes a hit with CActiveRecord . So I plan to make Cmodel classes for all my tables , define validation rules in these respective models and also define functions to perform the sql queries for retrieval and insertion of data . All my data collection on the website is primarily through forms (about 95%) , should I use Cformmodel , I dont really understand the distinction between Cmodel and Cformmodel , is there any performance hit in using either .
Also to prevent XSS attack I want to use HTML purify wrapper as a validation rule , since I read almost everywhere that performance is bad for this wrapper , is it going to be bad even if I use it as a validation rule ? And should I be displaying my output text using Chtml::Encode even though I am purifying the input ?
My rough plan to deal with the data is :
$users= new Users() ; //Users is extending CModel , contains validation rules
$users=getdata(Yii->app->userid()) ;
if(isset('update'))
{
if($users->validate())
{$users->updatedata() ; }
}
$this->render('users','data'=>$users)
CFormModel inherits from CModel, CModel is just a generic Model class, there are not performance differences in using CFormModel, which is what would suit more for your application if you don't plan to use CActiveRecord.
For 'functions to perform sql queries' hopefully you mean stored procedures, other wise there is not that big performace gain, even then, writing your own SQL queries only for insertion and retrieval of single models doesn't help much. My advice is that you care about performance latter on. once you really have something to improve upon.
Purifying the input its different from encoding, with HTML purify you eliminate harmfull html to prevent XSS or other tags you dont want to allow. but a string could still contain ( ' ) for example. what CHtml::encode does, its just generating the HTML equivalent, so that you get html entities instead.
I have posted a link to yii forum where you can find best answer.
Yii Forum Link
CModel Model class is base for both CFormModel & CActiveRecord.
CActiveRecord is used when we perform CRUD operation with a table of a database & needs variable definition according to them.
CFormModel is used when we don't need CRUD operation but a logical operation like Login Form. Here we don't use any table for the model.
This is called Premature Optimization Syndrome as you are blocking your development with early and unnecessary optimization.
Develop your application first with the best model/schema as you can, only after look for the bottlenecks and ways to increase performance, load time etc.
Yii implements two kinds of models:
form model
active record.
Both extend from the same base class CModel. A form model is an instance of CFormModel. Form model is used to keep data collected from user inputs. Such data are often collected, used and then discarded. For example, on a login page, we can use a form model to represent the username and password information that are provided by an end user. For more details, please refer to Working with Form
Active Record (AR) is a design pattern used to abstract database access in an object-oriented fashion. Each AR object is an instance of CActiveRecord or its child class, representing a single row in a database table. The fields in the row are represented as properties of the AR object. Details about AR can be found in Active Record.
Source
I've got (I hope) a very simple question for experts at MVC structure:
where to apply input filtering and validation? Controller or model?
I've read a lot of tutorials and manuals on filtering user input, but haven't noticed a lot of discussion where it should be applied. When using forms, it's simple, actually almost everything is done for you by Zend_Form via Zend_Filter and Zend_Validate.
But when I have to filter single value from user input and pass it to the model, what is the best practice, to do cleaning before passing it to the model, or in the model itself?
Lets assume I am creating a model, that other people will use too, and it is doing some important work on filesystem. Am I 100% sure other people will properly prepare parameters before passing it to the model? I am not, so the best would be cleaning parameters in the model itself.
But that's just my thoughts, and as I said before, I'd like to hear yours, right from the masters of the profession ;)
Nice day.
IMHO it depends on whether you know in advance the kind of validation you will have to do.
If it's something that could be expressed as a regex, leave it in the controller, otherwise I think the model should be its place.
Examples.
You have to validate an email address: controller, so the model can be passed some sanitized input and just take care of the actual processing.
You have to check whether a path in the filesystem exists: the controller will take care of seeing if it's a well-constructed path; the model will check if it actually exists in the filesystem in question.
You have to check whether an user-provided string $x can produce an hash $y you stored somewhere: model.
I would say in the controller. My understanding is that models should be constructed under the assumption that they are being given valid data to work with (but with sensible precautions in place in case they're not, such as using prepared statements for database access), and leaving the actual validation of data to an outside agent, in this case the controller.
Typically you do it in the controller. Model should be dealing with legit, usable data.
I've seen different comments all over the place, some say that zend framework automatically sanitizes post/get data but others say it doesn't.
What's the deal? I've seen that doing it in the predispatch with a foreach on getParams is the quickest way, but does anyone have any suggestions?
Probably the deal is about Zend_Controller_Request vs the Zend_Db. Request data are often put into the DB.
Request object does not escape anything. You may force it to do using filters, form filters or e.g. using the reflection technique described here:
Actions, now with parameters!
Zend_Db queries are basically escaped like in other ORM's, like in PDO.
It does not automatically sanitize any request data. It cannot, because that requires it to know how to sanitize it, e.g. should $_GET['foo'] be string sanitized or for numbers? You have to tell it.
Whether you sanitize input manually in the respective Controller Actions or in an ActionHelper or automatically in a Controller Plugin or during bootstrap or with a mixture of these is up to you.
Use what is appropriate.
It definitely doesn't automatically sanitise your variables for you. You could do something like foreach or use array_map depending on the context, for example:
$_POST = array_map('mysql_real_escape_string', $_POST);
Ideally though you should treat each variable on a case by case basis. Personally i make a lot of use of PHP's filter_var for filtering and sanitizing.
This question is mainly geared towards Zend in PHP, although it certainly applies to other languages and frameworks, so I welcome everyone's opinion.
I've only recently been using the Zend framework, and while it's not perfect, I have had a pretty good time with it. One thing that drives me crazy, however, is that most of the examples I see of people using Zend do the validation in special form objects, rather than in the model. I think this is bad practice because data can enter into the system in other ways beyond form input, which means that either validators have to be bent and twisted to validate other input, or validation must be done in a second place, and logic duplicated.
I've found some other posts and blogs out there with people who feel the same way I do, but the developers of Zend made this choice for a reason, and other people seem to use it without issue, so I wanted to get some feedback from the community here.
As I said, this mainly applies to Zend, although I think it's important to look at the issue as a whole, rather than working within the confines of the Zend framework, since Zend was designed so that you could use as much, or as little, as you wished.
This is a non-zend specfic answer, however I believe that the model should be responsible for the validity of its own data. If this is the case then the validation belongs in the model, however this may not always be achievable and it may be necessary to perform validation in the view, however I think this should be in addition to the validation performed in the model not a replacement for it.
The problem with only having validation in the view is that at some point you will probably want another view on your data. Your site may become popular and customers are asking for XML based APIs to generate their own views. Do you then rely on the customer to validate the data?
Even if you do not have to provide APIs some customers may want customized views that are sufficiently different to warrant a completely different version of the page, again you now have validation in the views duplicated.
I think the ideal scenario is to have your model do the validation but to make the results of the validation available for the view to read and render the page again with the validation results displayed.
I think it is perfectly reasonable to have the view doing validation if you want to instantly display validation data back to the user etc but the final decision on data validity should rest with the model.
It's important to remember that data validation which is relevant to an application isn't always the same thing as data validation that's relevant to a database schema.
Consider a simple registration form where a user creates an account with a username and password. You perform validation on the password because you want it to be X number of characters in length and contain a good mix of character types (or whatever).
But none of this is relevant to validate the data for database insertion, because you aren't going to store plain-text passwords - you're going to store a hash of them in some way (md5, md5 + salt, whatever). Instead you might make sure that you have a 32 character hexadecimal string so that it is very likely to be a properly created MD5 hash.
This password example isn't the only scenario, just a good one for explanation here in this topic.
So what's the answer? I don't think there's any one-solution-fits-all. Sometimes you will want (need?) to validate the data twice. Sometimes you'll do it once an only in the Model. Just match it as best as possible to your application's needs.
Perhaps you should have a look at Using Zend_Form in Your Models by Matthew Weier O'Phinney - one of the lead-developers of the Zend Framework - for his view on exactly this question.
Well, the validation can be done at many different levels and usually none of them is "the best". Of course, the model can be populated with invalid data that do not come from the form, but we can also create forms whose data do not go to any model.
Moreover, the direct validation in models is unsually not integrated with our form rendering system, which causes problems if we want to show the error messages and re-populate the form with the user-entered data then.
Both of the solutions have their own pros and cons. It would be perfect to have a system that ensures us that the validation finally must be done at some level. If the form does not validate some data, then the model does and vice versa. Unfortunately, I haven't heard of such library, but I must note that the validators in the frameworks unsually are source-independent. You can pass the POST data to them, but the same can be done with the information retreived from a properly parsed CSV, MYSQL databases, etc.
I am not aware of Zend. But.
Your model have to receive valid data. Model and it's methods shouldn't check data again and again. Of course there are should be functions that do actual validation and they should be called from the gui validation or from the other data input place.
The best you can do on your model side is call "Assertions" on all the data to be sure on the development time that validation have been taken its place.
The lower level of the code (UI, model, utils) the less validation and check code should be there. As then there is a big chance that the same validation will be called more then one.
How about putting esthetical validation in the form, and business rules validation in the model.
Take a registration form for example.
The form would assure that the email field is trimmed and contains a valid email, that the password/confirm password field are identical and that the user checked the I Agree to terms checkbox.
The registration model would make sure that the email hasn't been taken yet in the table, would salt and hash the password.
It's how I split the two usually.
User input should be validated when it is being inputted because it is specific to the form of entry (ie, do some form validation - make sure text boxes that should have numbers are numbers).
Business logic should probably be validated on the model because it is model specific (ie. make sure they have't already reserved that same room or something like that).
The problem with validating it at the model level is that the model might be used in different ways. Correct input for one scenario may not be correct input for another.
The other issue is that you usually want some context sensitive validation, such as displaying a red box around the form control that has the bad input.
The model or database might do some extra validation to make sure the user code isn't doing something completely wrong (constraints, etc).
Peter Bailey's password example is excellent. A user model can only validate, if a password was set (because it's not stored as plain text but as a hash) while input validation can ensure, that the original plain text password corresponds to the security requirements (number of characters,...). Therefore you need both: Model validation and form/input validation, ideally as separate, reusable component and not directly in bloated controller actions.
Think of input validation as whitelist validation (“accept known good”) and model validation as blacklist validation (“reject known bad”). Whitelist validation is more secure while blacklist validation prevents your model layer from being overly constrained to very specific use cases.
Invalid model data should always cause an exception to be thrown (otherwise the application can continue running without noticing the mistake) while invalid input values coming from external sources are not unexpected, but rather common (unless you got users that never make mistakes).
See also: https://lastzero.net/2015/11/form-validation-vs-model-validation/