使用TWIG Markdown转义HTML代码

时间:2014-10-08 20:13:54

标签: symfony twig markdown

我正在撰写博客评论包,我想让用户使用Markdown发布一些代码 我正在使用symfony2,TWIG和KNPMarkdownBundle进行解析

{{ post.content|markdown }}

实际上,内容已经过很好的降价解析(<code> <p> ...),但如果我的内容中有一些HTML代码,例如:

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

代码未转义,我有一条提醒信息。 有人可以解释我如何处理XSS问题? (foo|rawfoo|escape正在破解)

3 个答案:

答案 0 :(得分:5)

正如@sjagr暗示的那样,你最好编写自己的枝条扩展。曾几何时我遇到过类似的问题,只写了一个简单的扩展来对它进行排序,这非常简单容易。

新TWIG TAG:

{{ post.content|yourNewTag }}

新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 }

修改

<强> TWIG:

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

{{ someContent|yourNewTag }}

如果您不想转义特定标记,请使用带有strip_tags()函数的allowable_tags标记。

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
}

答案 1 :(得分:4)

我碰巧遇到了这个问题,但由于strip_tags不足以保护属性标记中的值,我会提交答案。

我使用HTML Purifier删除所有不需要的HTML元素和属性。打开命令控制台并执行以下命令进行安装。

$ composer require ezyang/htmlpurifier "^4.6"

然后您可以创建自己的Twig扩展名:

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';
    }
}

打开services.yml并将扩展名注册为服务:

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

现在您可以将它与

一起使用
{{ post.content|markdown|html_purifier }}

答案 2 :(得分:2)

您可以像使用striptags filter一样使用Twig的PHP's strip_tags function来允许特定的HTML代码通过:

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

这将完全消除不需要的标签,而不是将其解析为&lt;&gt;

除此之外,如果您希望每次都轻松引用同一组“允许的标签”,您可能需要write your own Twig filter