1

I was told that all user-provided inputs (e.g. $_GET variables) must be put through xss filtering and htmlspecialchars to prevent database attacks. but I don't know which is best, putting the filtering in controllers or the models? I hope I'm not micro-optimizing again...

dapidmini
  • 1,490
  • 2
  • 23
  • 46
  • Model is the cleaner option – Blinkydamo Nov 23 '16 at 07:56
  • It's interesting to see how different answers focus on different aspects of the question. Answers stating it should be in the model are correct if we are talking about SQL injection - that should indeed be prevented where data access happens. However, the XSS aspect of the question points to the view, output encoding should be in views where the appropriate encoding can be chosen. XSS is a presentation responsibility. – Gabor Lengyel Nov 24 '16 at 10:15

3 Answers3

2

You are mixing things up I'm afraid.

To prevent "database attacks" (by which you mean SQL injection I suppose), you have to use parameterized queries (with something like PDO in php). There are great questions on SO that help to prevent SQL injection in PHP.

But this has nothing to do with XSS and htmlspecialchars().

XSS is about an attacker being able to inject Javascript code into an application page. If that is possible through any form of user input, the page is vulnerable to XSS.

It is a huge topic, but in very short, XSS is an output problem, and the solution that helps to prevent it is output encoding. It may have many forms, basic html encoding is done by htmlspecialchars() in PHP, but there is much more to it, like for example it is inadequate when writing variables into a Javascript context (between script tags, into event attributes, etc). And then we haven't mentioned DOM XSS, when the entire thing happens in Javascript without a single server roundtrip.

A full tutorial on preventing XSS would not fit in an answer here.

However, let me note something closely related to your question. You should not encode user input before writing it to your database. If you store encoded data, then on the one hand it will be much harder to search/sort, because encoded characters will mess those up. Also it is a separation of concerns thing, your models have nothing to do with presenting the data, and encoding is presentation logic. When storing your data in the database, you don't even know in what context it will be presented, so you cannot even choose the right encoding method (html encoding? javascirpt encoding? xml or json or ldap? where will your data end up?).

So you can just store it as received (properly escaping it for the SQL query by using parameters, obviously), and then care about output encoding in your views, when that output is actually made.

Community
  • 1
  • 1
Gabor Lengyel
  • 14,129
  • 4
  • 32
  • 59
  • thank you for the long answer (I like it, I just don't know what words to use). yes, I've never worked on a big project like this so this is the first time I had to worry about security stuff. I'll have to read up a lot about this. – dapidmini Nov 24 '16 at 09:32
1

Personally I would create a helper class containing such functionality which could be instantiated wherever needed, or an abstract class or trait for your controllers containing those functions.

You should also make sure the db models are making use of prepared statements or PDO, and you could include a further level of filtering/sanitizing in the model abstract class also.

flauntster
  • 2,008
  • 13
  • 20
1

I preffer make that in model, after result.

Once result ready, i like to modify result object, date format, charset and another values, this to return a clean object.

Fat model, slim controller.

uruapanmexicansong
  • 3,068
  • 1
  • 18
  • 22
  • does that mean the query results are also modified in models? like adding htmlspecialchars_decode or the likes? – dapidmini Nov 24 '16 at 09:34
  • Yes, assuming you have an object: – uruapanmexicansong Nov 24 '16 at 22:50
  • Sorry, This is your query object: $post->title = "lorem ipsum"; $post->body = "Hello world"; $post->date = "2016-11-24"; $post->tags = "lorem,ipsum,dolor,sit,amet"; You should to process your data to return final object. For example: $tags = $post->tags; $post->tags = explode(",",$tags); $post->body = htmlspecialchars($post->body); $list($post->date->year,$post->date->month,$post->date->day) = explode($post->date); return $post; There're someways to program. My recommendation is, cleanest are better. – uruapanmexicansong Nov 24 '16 at 22:58
  • 1
    oh i see now. I've always thought models are just to get data from database, and all other processes was supposed to be done in controllers.. – dapidmini Nov 25 '16 at 02:25
  • You can program as easy as you feel comfortable, but if you need the same data in another controller, you'll need to copy and paste or process again. – uruapanmexicansong Dec 01 '16 at 22:19