/usr/portage

Preventing cross site scripting by design 4

This is more or less a reply to Dynamic global functions in PHP. My main problems with delegating escaping in the template is the fact, that the people who normally work with templates, are frontend developers and designers. Those who do not and should not care about web security. That is a programmers/architects field. Nobody of the frontend developers should have the possibility to create security level artefacts by accident. So, when a value arrives the template, everything should be done. No special escape-calls should be necessary. I will show you how we do escaping and template value sanitizing at Neu.de. But let’s step through all common models in order to explain, why they are bad. I assume you know the basic MVC-terms, I will use here mostlye view and controller action. First of all, the most common approach. Just assigning variables as-is to the view component:

The second – much better approach – is to escape values before accessing them in the template. This is fine as long as you do not use objects in your templates.

If you have complex, nested objects encapsulating complex business rules, you do not want to convert them to an array to make it possible to escape them afterwards because of speed concerns. So if you pass an object with a method which returns fragile user input, your escaping logic is bypassed. See:

The solution is to wrap assign objects in mock objects. You can easily implement a mock object builder using PHP5s reflection features and create a simple proxy which escapes the return values of every call – or – if an object is returned – wrappes this return object in another mock object. And so on and so on:

Once you implemented that, a) your developers must not care about XSS anymore, they just use the framework and b) you can sleep better at night, because it is not likely probable, that your site is vulnarable against XSS. Sometimes you want to allow HTML-code passing to the template. That’s ok, just give the developer a chance to avoid mocking or escaping. If you want to audit your code for XSS security problems, just grep for the method signature.

Filed on 22-10-2007, 14:02 under , , , , , & four comments & no trackbacks

Trackbacks

Trackback specific URI for this entry

No Trackbacks

Comments

  1. Astro opines:
    published on October 23rd 2007, 09:40:02 am *

    Wow, I’ve never seen Controller, View & XSS in Flowcharts before :-) Very nice! Is there a license?

    Reply

  2. Lars Strojny states:
    published on October 23rd 2007, 10:42:59 am *

    You can just use it for everything you want.

    Reply

  3. Troels Knak-Nielsen responses:
    published on October 26th 2007, 01:01:17 am *

    Very impressive. Symfony uses a design similar to #3, but I haven’t though about creating decorators, like you describe. You do get some problems, if you use the output of one object as input to another. Those cases are probably rare though.

    Still, I’m not sure what you gain in return for this (rather complex) design; If you do output through e(), it’s equally easy to audit the code. Just grep for echo|print.

    Reply

  4. Lars Strojny opines:
    published on October 26th 2007, 05:53:43 pm *

    Passing output in another object: in our environment, this escaping/mocking step is the last before rendering the rendering phase just prints the values and does not reuse values for other objects or something. But you are right, this might be a problem in other environment, where the view is more complex, e.g. an OOP environment were the view code sticks widgets together or for desktop apps written in PHP utilizing GTK+.
    Auditing: Less audit points need less time. I just need to audit the deactivation of that mocking/escaping process, while normally you need to audit every output.

    Reply

Add a Comment & let me know what you think