htmlspecialchars - 与其他所有内容相比,不同的属性转义?

时间:2014-07-04 19:34:36

标签: php security htmlspecialchars

我一直在阅读htmlspecialchars(),以逃避数据库中的用户输入和用户输入。在任何人说什么之前,是的,我正在过滤db输入以及使用带有绑定的预准备语句。我只关心确保输出。

我对何时使用ENT_COMPATENT_QUOTESENT_NOQUOTES感到困惑。我在做研究时遇到了以下摘录:

  

htmlspecialchars()来电中的第二个参数是ENT_COMPAT。我有   使用它,因为它是一个安全的默认值:它也将逃脱   双引号字符"。如果你真的,你真的需要这样做   输出HTML属性(如<img src="<?php echo htmlspecialchars($img_path, ENT_COMPAT, 'UTF-8')">)。你可以用   其他地方ENT_NOQUOTES

我在其他地方也发现了类似的评论。为属性转换单引号和/或双引号但未在其他地方转换它们的目的是什么?我唯一能想到的是你是否在页面中添加了实际的html:

我的变量是:<img src="somepic.jpg" alt="some text">如果您在此处转换双引号,则由于转义引号而无法正确呈现。在摘录中给出的示例中,我甚至无法想到将使用任何类型的引用的实例。

其次,在此特定参考中,它表示在其他地方使用ENT_NOQUOTES。为什么?我的个人思考过程告诉我在任何地方使用ENT_QUOTESENT_NOQUOTES当且仅当变量是需要它们的实际html属性时。

我已经做了很多搜索和阅读,但仍然对这一切感到困惑。我的主要目标是确保输出到页面,这样就不会发生html,php,js操作。

2 个答案:

答案 0 :(得分:4)

到处使用ENT_QUOTES。 PHP会在您需要的时候提供选项,但99%的时间都没有。不必要地转义引号是无害的。

htmlspecialchars($string, ENT_QUOTES, 'UTF-8');

因为代码太长而无法随处写,所以将它包装在一些小函数中。

function es($string) {
  return htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
}

答案 1 :(得分:1)

在HTML中,存在不同的上下文,其中不同的字符被认为是特殊的。例如,在double-quoted attribute value中,文字双引号将被解释为属性值分隔符:

  

8.2.4.38属性值(双引号)状态

     

消耗next input character

     

U + 0022报价标记(“)
  切换到after attribute value (quoted) state

     

U + 0026 AMPERSAND(&amp;)
  切换到character reference in attribute value stateadditional allowed character为U + 0022报价标记(“)。

     

U + 0000 NULL
  Parse error。将U + FFFD REPLACEMENT CHARACTER字符附加到当前属性的值。

     

EOF
  Parse error。切换到data state。重建EOF角色。

     

其他
  将current input character附加到当前属性的值。

在这种情况下,双引号需要使用character reference进行编码。单引号属性值类似,但这里引用的第一个文字单引号被认为是属性值结束分隔符。

类似的做法也适用于数据上下文,即。例如,在标签之外:

  

8.2.4.1数据状态

     

消耗next input character

     

U + 0026 AMPERSAND(&amp;)
  切换到character reference in data state

     

“&lt;” (U + 003C)
  切换到tag open state

     

U + 0000 NULL
  Parse error。将current input character作为字符标记发出。

     

EOF
  发出文件结束标记。

     

其他
  将current input character作为字符标记发出。

正如您所看到的,对于跨站点脚本而言,唯一被视为有害的字符是<,因为它会切换到标记打开上下文。因此,需要使用字符引用对其进行编码,以避免注入标记。

但是,它也允许使用字符引用而不是文字字符,即使它们在相应的上下文中不是特殊的,甚至根本不是。例如,以下内容是等效的:

<a href="http://example.com/">
<a href="&#x68;&#x74;&#x74;&#x70;&#x3a;&#x2f;&#x2f;&#x65;&#x78;&#x61;&#x6d;&#x70;&#x6c;&#x65;&#x2e;&#x63;&#x6f;&#x6d;&#x2f;">

因此,根据上下文,实际上只需要将某些特殊字符编码为字符引用,但对其他上下文中特殊的其他字符进行编码也不会有害。