Escape HTML with TWIG Markdown

I am working on a blog comment pack and I would like the user to post code using Markdown.
I work with symfony2, TWIG and KNPMarkdownBundle to parse

{{ post.content|markdown }} 

Actually, the content of the markup is well processed ( <code> <p> ...), but if I have HTML code in my content, for example:

 Some content ``` <script>alert("hello world");</script> ``` 

The code is not escaped and I have a warning message. Can someone explain how I can deal with XSS issues? ( foo|raw and foo|escape break the parsing)

+7
markdown symfony twig
source share
3 answers

I just had this problem, but since strip_tags not enough to protect the values ​​in the attribute tag, I will post my answer.

I use HTML Cleaner to remove all unwanted HTML elements and attributes. Open the console and run the following command to install it.

 $ composer require ezyang/htmlpurifier "^4.6" 

Then you can create your own Twig extension:

 namespace AcmeBundle\Twig; class HTMLPurifierExtension extends \Twig_Extension { public function getFilters() { return array( new \Twig_SimpleFilter('html_purifier', array($this, 'purify'), array('is_safe' => array('html'))), ); } public function purify($text) { $elements = array( 'p', 'br', 'small', 'strong', 'b', 'em', 'i', 'strike', 'sub', 'sup', 'ins', 'del', 'ol', 'ul', 'li', 'h1', 'h2', 'h3', 'dl', 'dd', 'dt', 'pre', 'code', 'samp', 'kbd', 'q', 'blockquote', 'abbr', 'cite', 'table', 'thead', 'tbody', 'th', 'tr', 'td', 'a[href|target|rel|id]', 'img[src|title|alt|width|height|style]' ); $config = \HTMLPurifier_Config::createDefault(); $config->set('HTML.Allowed', implode(',', $elements)); $purifier = new \HTMLPurifier($config); return $purifier->purify($text); } public function getName() { return 'html_purifier'; } } 

Open services.yml and register the extension as a service:

 services: acme.html_purifier_extension: class: AcmeBundle\Twig\HTMLPurifierExtension public: false tags: - { name: twig.extension } 

Now you can use it with

 {{ post.content|markdown|html_purifier }} 
+4
source share

As @sjagr suggests, it's best to write your own branch extension. I once encountered a similar problem and just wrote a simple extension for sorting, which was very simple and easy.

NEW TWIG TAG:

 {{ post.content|yourNewTag }} 

NEW TWIG EXTENSION CLASS:

 namespace Car\BrandBundle\Twig; class YourNewTagExtension extends \Twig_Extension { public function yourNewTagFilter($param) { // Escape your content as you wish with some logic and return it return $escaped; } public function getFilters() { return array(new \Twig_SimpleFilter('yourNewTag', array($this, 'yourNewTagFilter'))); } public function getName() { return 'yourNewTag_extension'; } } 

Config

 services: car.twig.yourNewTag_extension: class: Car\BrandBundle\Twig\YourNewTagExtension tags: - { name: twig.extension } 

EDIT:

TWIG:

 {% set someContent = '<script>alert("hello world");</script>' %} {{ someContent|yourNewTag }} 

If you do not want to hide certain tags, use the allowable_tags flag with the strip_tags () function.

 public function yourNewTagFilter($param) { $escaped = strip_tags($param); // Do something else as well if you want return $escaped; // This will print alert("hello world"); as output in your webpage } 
+5
source share

You can use the Twig striptags filter the same way you would have the PHP strip_tags function to allow specific HTML tags through:

 {{ post.content|striptags('<code><p><br>')|markdown }} 

This completely eliminates unnecessary tags instead of parsing them into &lt; and &gt; .

Other than that, you might want to write your own Twig filter if you want to easily reference the same set of "valid tags" "every time.

+2
source share

All Articles