【问题标题】:Sanitize HTML5 with PHP (prevent XSS)使用 PHP 清理 HTML5(防止 XSS)
【发布时间】:2014-05-04 11:02:43
【问题描述】:

我正在使用 HTML5 和 Javascript 构建所见即所得的编辑器。 我将允许用户通过 WYSIWYG 发布纯 HTML,因此必须对其进行清理。

保护网站免受跨站脚本 (XSS) 攻击等基本任务即将到来,因为没有最新的 PHP 净化和过滤软件。

HTML Purifier 目前不支持 HTML5,整体状况看起来很糟糕(不会很快支持 HTML5)。

那么我应该如何使用 PHP(后端)清理不受信任的 HTML5 呢?

目前的选项...

还有其他选择吗? PHP 会死吗? ;)

【问题讨论】:

  • 您可以防止使用 csrf 令牌进行跨站点脚本。任何体面的框架都将提供一个简单的实现。如果你选择做一名牛仔并自己动手,那是可行的,但请不要抱怨 php 死了。
  • 我已经有了 CSRF 保护,但是保护还不够。用户仍然可以在没有适当清理的情况下发布(注入)JS 事件、CSS 样式等。允许的 HTML5 标记和属性必须有白名单。 PHP 正在死亡的部分是一个(坏的?)笑话。
  • 发布 CSS 样式?儿子,你说的太不合理了。
  • @pguardiario — CSRF 和 XSS 是完全不同类型的攻击(虽然 CSRF 保护通常会击败反射型 XSS 攻击,但它对存储型 XSS 攻击没有多大帮助)

标签: php html xss wysiwyg sanitize


【解决方案1】:

PHP 提供解析方法来防止代码 PHP/SQL 注入(即mysql_real_escape_string())。这不是 HTML/CSS/JavaScript 的情况。为什么会这样?

首先:HTML/CSS/Javascript 的唯一目的是显示信息。您可以根据自己的要求接受或拒绝 HTML 的某些元素。

其次:由于 HTML/CSS/JS 元素的数量非常多(也在不断增加),因此无法尝试控制 HTML。你不能指望一个实用的解决方案。

这就是为什么我建议采用自上而下的解决方案。 我建议开始限制一切,然后只允许一定数量的标签。 一个很好的基础可能是使用BBCdode,它很受欢迎。如果您想“解锁”除 BBCode 之外的其他特定标签,您可以随时添加一些。

这就是类似 BBCode 的脚本在论坛和网站上流行的原因(包括堆栈溢出)。 WISIGIG 编辑器专为管理员/内部使用而设计,因为您不希望您的网站管理员注入不良内容。

自下而上的方法注定会失败。 HTML sanitizer 面临指数级的复杂性,并且不保证任何事情。


编辑 1


你说这是一个卫生问题,而不是前端问题。我不同意,因为您无法处理所有当前和未来的 HTML 实体,您最好将其限制在前端级别以 100% 确定。

这就是说,也许以下是适合您的解决方案:

  1. 您可以通过对所有实体进行条带化来清理您的代码 使用 PHP 的 strip_tags() 的白名单中的除外
  2. 您还可以删除所有剩余的标签属性(属性) 通过使用 PHP 的 preg_replace() 和一些正则表达式。

$string = "put some very dirty HTML here.";
$string = strip_tags($string, '<p><a><span><h1><li><ul><br>');
$string = preg_replace("/<([b-z][b-z0-9]*)[^>]*?(\/?)>/i",'<$1$2>', $string);
echo $string;

这将返回您的净化文本。

注意:我已排除标记的属性删除,因为您可能仍希望保留 href="" 属性。因此[b-z][B-Z] 正则表达式。

【讨论】:

  • 另外,市面上也有一些不错的编辑器,全包式:CKEditor 或 TinyMCE 编辑器等。为什么不用呢?
  • WYSIWYG 更适合这个用户群。我知道他们不想学习编码语言/语法,比如 BBCode。 HTMLPurifier 的(和类似的)观点是它限制一切,然后只允许一定数量的标签。我只需要几个标签,比如粗体和斜体,所以 CKEditor 和 TinyMCE 会是矫枉过正。
  • 问题在于清理,而不是前端实现或转义数据库查询。
【解决方案2】:

我相信理想的是使用组合:

  mysql_real_escape_string(addslashes($_REQUEST['data']));

写入时

   stripslashes($data) 

阅读总是对我有用,我认为它比

  htmentities($data) on write

  html_entity_decode($data) on read

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-01
    • 2012-04-24
    • 2013-05-26
    • 1970-01-01
    相关资源
    最近更新 更多