intercepting filter

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

intercepting filter

Post by alex.barylski »

Currently I filter each of my GPC variables inside each action controller, immediately after retreival from the REQUEST object...

After the third action controller in a row I have refactored to use REQUEST instead of GET/POST directly and I'm sitting here thinking...

I could really clean up the code in each controller if I used an intercepting filter in the front controller and had the intercepting filter somehow set the REQUEST object up with filtered data. That way I just have to access the REQUEST object in the controllers and not have to worry about filtering data...

Basically I could implement this as a simple regex lookup mapped to the given name of the variables. Ideally I could associate the regex based on type and avoid the duplication occuring when filtering first name and last name (strings). However I could possibly have each filter cross reference existing filters if they accomplish the same end result...

What do you think? What do you do? Do you filter inside each individual controller or would it make more sense to filter using an "Intercepting Filter" - hence I figure that is where the name came from. :)

Cheers :)
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post by Kieran Huggins »

I'd filter in the model, not before.

Different data types have different valid forms; Phone numbers, postal codes, etc... each need to be normalized according to their own rules.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

Kieran Huggins wrote:I'd filter in the model, not before.

Different data types have different valid forms; Phone numbers, postal codes, etc... each need to be normalized according to their own rules.
I agree, however why do you feel this filtering cannot be done inside the controller?

What difference does it make whether I do something like:

Code: Select all

$phone = preg_replace('/^[0-9]-[0-9]/', '', $phone);
Inside the controller or inside the model?
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post by Kieran Huggins »

According to MVC (model 2, etc..) the model should contain all the business logic, including data validation.

That way your model is a single point of failure. You can be sure that no matter what your source is, no matter what controller is accessing it, your data will be 100% safe. That's a nice thing not to have to worry about!

Also, how would you unit test your models if your validation was in a controller somewhere?

It's clean and DRY 8)
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

validation !== filtering, though.

I usually leave the filtering up to the layer which is responsible for presenting the data to an external source. I.e. if it's a data accessor, then it will escape the data for the data base it is accessing, if it's an XML/HTML view object, it will translate or strip special characters etc.

The reason is fairly obvious when you think about it - whilst I might be filtering for HTML in general, what if the data also goes to a plain text flat file? No need to filter html, but I will need to filter null chars or similar.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

Kieran wrote:According to MVC (model 2, etc..) the model should contain all the business logic, including data validation.
Well in my system, data validation is not the same as filtering.

Filtering The process of removing non-essential characters, so a phone number would likely have zero purpose for quotes or other letters. Likewise pagination offset variables are likely only integers and shouldn't contain any JavaScript which could be used for XSS, no?

Validation The process of validating the format of the data. Making sure a phone number is actually a phone number and not formatted like a SSN.

Escaping The process of securing the data for a specific storage medium. Some databases use a different escaping technique than the slashes added by mysql_real_escape_string(). I want to say MSSQL but I cannot say for sure, I think you escape the data by adding double single quotes, not a slash.


So for me, there are three different phases/layers of making data secure.

Filtering is done inside the controller, validation is done in the model (business logic) and finally escaping is completed inside the data access layer or table data gateway. My specific implementation of MVC model 2 doesn't require any dependency between MVC components like traditional MVC, so basically I have my controller initialize both the model and then the view.

By filtering data inside my controller I prevent both XSS exploits and SQL injection by adding further protection in each subsequent layer.

Although not bullet proof in theory (I suppose someone might be able to construct an XSS attack from a really loosely filtered data input) in all practicality I have yet to see a variable which after going through some trivial filtering have any chance of either SQL or XSS exploits.

Using this controller approach, I consolidate making data safe for both the Model and View in one location.
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post by Kieran Huggins »

I'm interested to know everyone's position of why you would separate filtering from validation?

I, for one, can't see any reason to do keep them separate. It's not like the model just dumps the input into SQL (hopefully!!!).
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

Kieran Huggins wrote:I'm interested to know everyone's position of why you would separate filtering from validation.
I am not sure what "keep them separate" means. I use separate classes to do each, but often in conjunction. Sometimes you want to filter and validate, and sometimes you just want to validate. Also you may want to validate first to check for maliciousness, or after filtering to check for correctness.
(#10850)
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

I think talk about filtering/validating in the Model is confusing. What is this Model in the context of $_POST? I think in Hockey's case it's obviously the initial superglobal, which is why it should be filtered and validated prior to any other use inside a Controller. Otherwise you have to pass it to a special Model first, and then only use it, which IMO is a royal pain. Not all POST data is for a Model - a lot is going to be setup data (e.g. Controller routing, Internationalisation, etc.). Other bits could be simple decision flags (e.g. does the user want RSS or HTML?).

Splitting filtering and validation? What arborint said - they are generally two different things, so they in separate in that they start from separate classes. Most times, they'll end up occupying the same input chain before the data is accessible for use.
Also, how would you unit test your models if your validation was in a controller somewhere?
Easy - validation is a different behaviour so why would I be testing it? I'd have validation/filter tests elsewhere - other than of course the obvious requirement of a Model to escape and sanitise data before hitting the database. Even that is getting quickly tiresome if you're migrating to prepared statements. So two streams of unit tests - one verifying the behaviour of the appropriate filter/validation chain elements, the other the Model CRUD etc.

Secondly, the controller itself would be tested via acceptance tests. So it's well ringed.
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

Kieran Huggins wrote:I'm interested to know everyone's position of why you would separate filtering from validation?

I, for one, can't see any reason to do keep them separate. It's not like the model just dumps the input into SQL (hopefully!!!).
Validation is ensuring the data that is in bound is what you expected, filtering is preparing outbound information for use. This is a boolean scenario, it either validates, or does not.

In your example, the SQL layer would filter the string for use with the database (escape string), but your model would validate the input to ensure it is the expected data format (string value is a string, integer/float is numeric, etc.) Filtering is a functional aspect, it will remove or escape bad data.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

Jenk wrote:Validation is ensuring the data that is in bound is what you expected, filtering is preparing outbound information for use.
Yes you can filter outbound and the most important filtering is escaping, which is often considered something separate from filtering. But input filtering in the form of forcing type or character whitelists in really preparing inbound data for validation -- and simplifying the validation required or eliminating the need for validation.
(#10850)
Post Reply