34

I need my users to enter the URI of their personal website in their profile so that other users can see and click on it. I am worried that this could lead to XSS attacks if the output is not sanitized properly.

Like in this very simplistic schema below:


enter image description here


I am using the full stack symfony2 framework, Doctrine as ORM and Twig as a template engine. I know that Symfony provides some amazing Validation tools, and that TWIG provides automatic output escaping (which is not necessary in this particular case) as well as some filters for output sanitizing.

I've read the following about how symfony2 and twig handle sanitization:

Doctrine comes with sanitization for database (SQL) injections. Apart from this, there is no recommended / provided input sanitization at controller level in Symfony2. However, using Twig in the view, output sanitization is available.

As an example, in CakePHP however:

Data sanitization is implemented as a Utility which can be accessed from anywhere (controller, component, model .. even view). It follows a sanitize-all-input approach with a fixed set of predefined sanitization filters. Sanitizing specific inputs with dedicated rules is possible, but seems not to be encouraged.The existing rules concentrate on SQL and HTML injections and filtering out general suspicious unicode characters.

1 How do symfony2 + twig users handle input sanitization? Do they discard input sanitization totally and for example rely on validation only? Or do they write their own utility function to filter user inputs? or maybe use a library like owasp-esapi-php?

2 How do symfony2 + twig users handle output sanitization? Do they rely on the filters provided by the twig engine only? For example, are there already any tools that one can use to sanitize a user-entered URI, something similar to this?

3 In this situarion, how would you handle database storage and display of a user-entered URI like in the example above, would you care about input sanitization at all? or would you use output sanitization only and store the URI as is?

Community
  • 1
  • 1
Mick
  • 30,759
  • 16
  • 111
  • 130
  • 1
    Maybe I don't get it right but in the cakephp doc, it is written that: `For sanitization against XSS it’s generally better to save raw HTML in database without modification and sanitize at the time of output/display.` So you should save the input as it is. You can then use a twig filter to prevent XSS attacks. Id do believe [`{{ user.website|e('url') }}`](http://twig.sensiolabs.org/doc/filters/escape.html) would do the job. If not, it is always possible to [create a new filter](http://twig.sensiolabs.org/doc/advanced.html#filters). – cheesemacfly May 24 '13 at 18:26
  • One of the ways is to make a request(example with curl) to the inputed url passed through the Url validator. If successful, you can display this address, or escape it and output as text. – Alexey B. May 25 '13 at 14:55
  • 1
    After a little research, I believe it all comes down to CakePHP using [`htmlentities`](http://php.net/manual/en/function.htmlentities.php) vs symfony/twig using [`htmlspecialchars`](http://us2.php.net/htmlspecialchars), so I am not sure if the CakePHP example was really relevant here. – cheesemacfly May 30 '13 at 19:28
  • That's very nice to open a bounty @rufinus! Thanks! – Mick Mar 14 '14 at 18:00
  • im very intrested in the answer. currently it seems the favored method is output sanitzing.. but to be honest i see no point in storing potential dangerous JS code in my Database, only to filter it out when outputing. this makes just no sense. – Rufinus Mar 14 '14 at 18:11
  • @Patt, are you using the symfony form component? if that is the case take a look at the url form type: http://symfony.com/doc/current/reference/forms/types/url.html – Onema Mar 20 '14 at 23:27

4 Answers4

3
  1. You should not worry at all about input sanitization, Doctrine is immune to sql injection

  2. By default, all output is escaped. So even if $text has script tags, it will be escaped; visible as text but not executed by browser. And if you want to have http://example.com clickable, there are jquery plugins that can do that for you.

  3. I would only put validation, there is

    new Symfony\Component\Validator\Constraints\Url() ;
    

available for you

Zeljko
  • 5,048
  • 5
  • 36
  • 46
  • 2
    Sorry @Zeljko,I disagree, this constraint does not prevent XSS attacks. [URL can contain code](http://stackoverflow.com/questions/205923/best-way-to-handle-security-and-avoid-xss-with-user-entered-urls). I'll try to open a bounty to see how experts handle these sort of things.. – Mick May 24 '13 at 13:32
  • Why not? If good guy use some url that his data will be valid and you can store it. If bad gay use "" field will be invalid. No XSS. – nonlux Mar 20 '14 at 08:27
  • 1
    see https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Validator/Constraints/UrlValidator.php – nonlux Mar 20 '14 at 08:27
3

There is also a nice symfony2 bundle that allow users to implement input filtering in entities using Annotations. Like this :

/**
* @Filter\StripTags()
* @Filter\Trim()
* @Filter\StripNewlines()
*
* @var string
*/
public $email;

The bundle : dms-filter-bundle

Mohamed Ramrami
  • 12,026
  • 4
  • 33
  • 49
0

I think Symfony and CakePHP are frameworks and the save process can't correctly know the input context and what it will save into DB. Developer knowns the context, if it's URL, HTML, SQL, etc, , even when outputting data, so output sanitization is often chosen, and if the developer wants to implement input sanitization, he always can and uses some existing tools.

You can use HTML Purifier to "purify" all user inputs.

https://github.com/Exercise/HTMLPurifierBundle

Aaron Belchamber
  • 1,480
  • 1
  • 16
  • 20
Divi
  • 800
  • 1
  • 7
  • 16
  • 2
    and i can use filter_var and many other sanitazion tools, thats not the point here. Its not about `how can you`, but more of `how should you`. – Rufinus Mar 19 '14 at 15:35
0

Using the form validators provided by Symfony verifies the integrity of the data supplied to your application's database.

You should consider adding a test for a url-pattern, there are various

Other users already pointed out you are safe against various attax using components (csrf, type/property validation (symfony-form), sql-injection(Doctrine) and xss (twig) and of course various access authentification)

So for the specific attack you ask about it is necessary for bad user to submit a script-tag and some poor user get this displayed and executed, you could easily avoid getting this into your application with a simple regex of them

preg_replace('/(<' .'script'. '>)(.*)(</' .'script'. '>)/g', '', $text);

So i think it is safe not to rely on the sanitation of the output, there are many reasons, for example you do not use twig because your application is endpoint driven or for some reason you need to call |raw filter on text fields or maybe you dont even have influence on the display because thirds are displaying the data each on their way.

john Smith
  • 17,409
  • 11
  • 76
  • 117