代码之家  ›  专栏  ›  技术社区  ›  Devner

php&mysql:什么时候使用htmlentities?

  •  21
  • Devner  · 技术社区  · 15 年前

    平台: PHP与MySQL

    为了我的实验目的,我在自己的网站上尝试了一些XSS注射。考虑这种情况,在这里我有表单文本区域输入。因为这是一个文本区域,所以我可以输入文本和各种(英语)字符。以下是我的观察结果:

    A)如果我只应用strip_标签和mysql_real_escape_字符串,并且在将数据插入数据库之前不在输入中使用htmlentities, 查询正在中断 由于异常终止,我被一个显示我的表结构的错误击中。

    B)如果在将数据插入数据库之前,在输入端应用strip_标记、mysql_real_escape_字符串和htmlentities, 查询未中断 我能够成功地将文本区域中的数据插入到我的数据库中。

    因此,我确实理解,必须不惜一切代价使用htmenties,但不确定什么时候应该使用它。基于以上考虑,我想知道:

    1. 什么时候应该使用HTMLEntities?应该在将数据插入数据库之前使用它,还是在我试图显示数据库中的数据时,以某种方式将数据导入数据库,然后应用htmlentities?

    2. 如果我遵循上面b)点中描述的方法(在我的例子中,我认为这是最明显和最有效的解决方案),当我试图显示来自数据库的数据时,是否仍然需要应用HTMLEntities?如果是,为什么?如果没有,为什么不呢?我之所以这样问,是因为在我通过以下网址的帖子后,我真的很困惑: http://shiflett.org/blog/2005/dec/google-xss-example

    3. 然后还有一个PHP函数调用: HTML实体解码 . 我能用它来显示我从数据库得到的数据吗(按照B点所示的步骤之后),因为HTMLEntities应用于我的输入?我更喜欢哪个:HTML实体解码和HTMLEntities,什么时候?

    预览页面:

    我认为在这里添加一些特定情况的更具体细节可能会有所帮助。假设有一个“预览”页面。现在,当我从文本区域提交输入时,预览页面接收输入并显示为HTML,同时,隐藏的输入会收集此输入。当点击预览按钮上的提交按钮时,隐藏输入中的数据将被发布到新页面,该页面将隐藏输入中包含的数据插入数据库。如果在最初提交表单时不应用HTMLEntities(但只应用strip_tags和mysql_real_escape_string),并且文本区域中存在恶意输入,则隐藏输入被破坏,隐藏输入的最后几个字符可视为 " /> 在页面上,这是不可取的。因此,记住这一点,我需要做一些事情来在预览页面上正确地保持隐藏输入的完整性,同时收集隐藏输入中的数据,以便它不会破坏它。我该怎么办?对于延迟发布此信息表示歉意。

    提前谢谢。

    4 回复  |  直到 12 年前
        1
  •  51
  •   nickf    15 年前

    这是一般的经验法则。

    在处转义变量 最后可能的时刻 .

    您希望变量能够清晰地表示数据。也就是说,如果你想储存一个叫“奥布莱恩”的人的姓氏,那么你肯定 不要 想要这些:

    O'Brien
    O\'Brien
    

    …因为,嗯,那不是他的名字:里面没有符号和斜线。当您获取该变量并将其输出到特定的上下文中(例如:插入到SQL查询中,或打印到HTML页中)时, 那个 当你修改它的时候。

    $name = "O'Brien";
    
    $sql = "SELECT * FROM people "
         . "WHERE lastname = '" . mysql_real_escape_string($name) . "'";
    
    $html = "<div>Last Name: " . htmlentities($name, ENT_QUOTES) . "</div>";
    

    你永远不想 htmlentities -存储在数据库中的编码字符串。当您想要生成一个csv或pdf,或者任何 不是 HTML?

    保持数据干净,并且只针对当前特定的上下文进行转义。

        2
  •  5
  •   BarsMonster    15 年前
    1. 只有在将值(无论是从db还是从$\u get/$\u post)打印到HTML之前。HTMLEntities与数据库无关。
    2. B是多余的。您应该在插入到数据库之前mysql_real_escape_string,在打印到HTML之前htmlentities。在HTMLEntities标记显示在屏幕上为<b r/>e.t.c之后,您不需要删除标记。

    理论上,您可以在插入到数据库之前执行HTMLEntities,但如果需要原始文本,这可能会使进一步的数据处理更加困难。

    3. See above
    
        3
  •  5
  •   John Parker    15 年前

    本质上,你应该使用 mysql_real_escape_string 在插入数据库之前(为了防止SQL注入),然后 htmlentities 等等,在输出点。

    您还需要对所有用户输入应用健全性检查,以确保(例如)数值确实是数值等功能,例如 is_int , is_float 等等,在这一点上是有用的。(见 variable handling functions 有关这些函数和其他类似函数的详细信息,请参阅PHP手册的一节。)

        4
  •  0
  •   netrox    12 年前

    我以前经历过,学到了两件重要的事情:

    如果您从$\u post/$\u get/$\u请求中获取值并计划添加到数据库,请使用mysql\u real\u escape\u string函数清理这些值。不要用HTMLEntities对它们进行编码。

    为什么不用HTMLEntities对它们进行编码,并将它们放到数据库中呢?好吧,事情是这样的-目标是使数据尽可能的有意义和干净,并且当您用HTML实体(如Jeff的狗变成Jeff的狗)编码数据时…这将导致数据上下文失去意义。如果您决定实现REST服务,并从数据库中获取该字符串并将其放入JSON中,那么它会像杰夫的狗一样出现,而这条狗并不漂亮。您还必须添加另一个函数来解码。

    假设您要使用SQL“select*from table where field='jeff\'s dog'”搜索“jeff's dog”,您将找不到它,因为“jeff's dog”与“jeff"s dog”不匹配。“bad,eh?”

    要将字母数字字符串(从char类型)输出到网页,请使用htmlentities-always!