Zend Framework 输入/输出 XSS 过滤:Strip Tags、Textile、BBCode

发布于 2024-12-09 20:40:37 字数 702 浏览 0 评论 0原文

在我的 CMS 应用程序中,管理用户可以通过所见即所得编辑器添加 HTML 内容,该编辑器由 HTMLPurifier 过滤。我现在想添加留言板功能。我计划使用 Zend StripTags 过滤器 无需白名单即可删除所有 HTML,然后通过使用 Zend 的 BBCodeTextile 解析器。

我的问题是:

  1. 如果我没有白名单,XSS 可以通过 StripTags 吗?
  2. 添加 BBCode 或 Textile 作为输出解析器是否会重新引入 XSS 的可能性?

In my CMS application, administration users can add HTML content via a WYSIWYG editor that gets filtered by HTMLPurifier. I am now wanting to add a message board functionality. I am planning on using the Zend StripTags Filter without a whitelist to remove all HTML, and then provide for rich markup by using Zend's BBCode or Textile parsers.

These are my questions:

  1. Can XSS make it through StripTags if I have no whitelist?
  2. Does adding BBCode or Textile as an output parser reintroduce the possibility of XSS?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蓦然回首 2024-12-16 20:40:37

阅读一篇关于 Markdown 的文章之后,以及 该帖子的答案中链接的另一篇文章,看来在文档中重新引入 XSS 不仅是可能,但微不足道。为了安全起见,我需要通过 HTMLPurifier 运行内容,作为输出过滤器链。因为我担心 HTMLPurifier 作为输出过滤器的性能,所以我正在考虑使用 Wibble 代替。

这仍然没有回答第一个问题,但就我而言,这一步是不必要的。


我在尝试使用它们时发现 Zend 的 BBCode 和 Textile 有严重的错误。我改为使用 PHP Markdown。另外,Wibble 似乎还没有准备好投入生产。

我在数据库中使用了两列:contenthtmlcontent 列保存用户提交的文本。保存记录时,我使用 PHP Markdowncontent 转换为 HTML >,将其传递给 HTMLPurifier ,然后将该值保存到 html 列中。我不会以这种方式转换所有观点。


实现细节

我把PHP Markdown放在这里:library /markdown.php。在我的活动记录模型中,使用 Zend_Db_Table_Row_Abstract,我使用 _insert()_update() 挂钩在保存记录之前处理值:

// prepare html based on the content
require_once 'markdown.php';
$flt = new My_Filter_HtmlPurifier();
$this->html = $flt->filter(Markdown($this->content));

这是我的 HTMLPurifier 过滤器:

/**
 * Based on examples from http://blog.astrumfutura.com/archives/365-Example-Zend-Framework-Blog-Application-Tutorial-Part-8-Creating-and-Editing-Blog-Entries-with-a-dash-of-HTMLPurifier.html
 */
require_once 'HTMLPurifier.includes.php';
require_once 'HTMLPurifier.autoload.php';

class My_Filter_HtmlPurifier implements Zend_Filter_Interface
{
    /** @var HTMLPurifier */
    protected $_htmlPurifier;

    public function __construct($options = null)
    {
        // set up configuration
        $config = HTMLPurifier_Config::createDefault();
        $config->set('HTML.DefinitionID', 'My HTML Purifier Filter');
        $config->set('HTML.DefinitionRev', 3); // increment when configuration changes
//        $config->set('Cache.DefinitionImpl', null); // comment out after finalizing the config

        // Doctype
        $config->set('HTML.Doctype', 'XHTML 1.0 Transitional');

        // Add support for object (flash) tags
        $config->set('HTML.SafeObject', true);
        $config->set('Output.FlashCompat', true); // IE Support

        // Custom Filters
        // Add support for iframes - YouTube, Vimeo...
        $config->set('Filter.Custom', array(new HTMLPurifier_Filter_MyIframe()));

        // Add support for anchor targets
        $config->set('Attr.AllowedFrameTargets', array('_blank', '_self', '_target', '_top'));

        // configure caching
        $cachePath = CUST_APP_PATH . '/../cache/htmlpurifier';
        if (!is_dir($cachePath)) {
            mkdir($cachePath, 0700, true);
        }
        $cachePath = realpath($cachePath);
        $config->set('Cache.SerializerPath', $cachePath);

        // allow for passed-in options
        if (!is_null($options)) {
            //$config = HTMLPurifier_Config::createDefault();
            foreach ($options as $option) {
                $config->set($option[0], $option[1], $option[2]);
            }
        }

        // create the local instance
        $this->_htmlPurifier = new HTMLPurifier($config);
    }

    public function filter($value)
    {
        return $this->_htmlPurifier->purify($value);
    }
}

After reading a post about Markdown here on SO, and another article linked in an answer to that post, it appears that reintroducing XSS into a document is not only possible, but trivial. To be secure, I will need to run content through HTMLPurifier as the final step in the output filter chain. Because I am concerned with the performance of HTMLPurifier as an output filter, I am looking into using Wibble instead.

This still leaves the first question unanswered, but in my case, that step will be unnecessary.


I discovered when trying to use them, that Zend's BBCode and Textile are horribly buggy. I instead used PHP Markdown. Also, Wibble doesn't seem like it's production ready yet.

I used two columns in my database: content and html. The content column holds the user-submitted text. When saving the record, I convert content to HTML with PHP Markdown, pass it through HTMLPurifier and then save that value to the html column. I am not converting will every view that way.


Implementation Details

I put PHP Markdown here: library/markdown.php. In my active record model, using Zend_Db_Table_Row_Abstract, I use the _insert() and _update() hooks to process the values before the record is saved:

// prepare html based on the content
require_once 'markdown.php';
$flt = new My_Filter_HtmlPurifier();
$this->html = $flt->filter(Markdown($this->content));

Here is my HTMLPurifier filter:

/**
 * Based on examples from http://blog.astrumfutura.com/archives/365-Example-Zend-Framework-Blog-Application-Tutorial-Part-8-Creating-and-Editing-Blog-Entries-with-a-dash-of-HTMLPurifier.html
 */
require_once 'HTMLPurifier.includes.php';
require_once 'HTMLPurifier.autoload.php';

class My_Filter_HtmlPurifier implements Zend_Filter_Interface
{
    /** @var HTMLPurifier */
    protected $_htmlPurifier;

    public function __construct($options = null)
    {
        // set up configuration
        $config = HTMLPurifier_Config::createDefault();
        $config->set('HTML.DefinitionID', 'My HTML Purifier Filter');
        $config->set('HTML.DefinitionRev', 3); // increment when configuration changes
//        $config->set('Cache.DefinitionImpl', null); // comment out after finalizing the config

        // Doctype
        $config->set('HTML.Doctype', 'XHTML 1.0 Transitional');

        // Add support for object (flash) tags
        $config->set('HTML.SafeObject', true);
        $config->set('Output.FlashCompat', true); // IE Support

        // Custom Filters
        // Add support for iframes - YouTube, Vimeo...
        $config->set('Filter.Custom', array(new HTMLPurifier_Filter_MyIframe()));

        // Add support for anchor targets
        $config->set('Attr.AllowedFrameTargets', array('_blank', '_self', '_target', '_top'));

        // configure caching
        $cachePath = CUST_APP_PATH . '/../cache/htmlpurifier';
        if (!is_dir($cachePath)) {
            mkdir($cachePath, 0700, true);
        }
        $cachePath = realpath($cachePath);
        $config->set('Cache.SerializerPath', $cachePath);

        // allow for passed-in options
        if (!is_null($options)) {
            //$config = HTMLPurifier_Config::createDefault();
            foreach ($options as $option) {
                $config->set($option[0], $option[1], $option[2]);
            }
        }

        // create the local instance
        $this->_htmlPurifier = new HTMLPurifier($config);
    }

    public function filter($value)
    {
        return $this->_htmlPurifier->purify($value);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文