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

什么是所有HTML转义上下文?

  •  8
  • dirtside  · 技术社区  · 15 年前

    当输出HTML时,有几个不同的地方可以将文本解释为控制字符而不是文本文本文本。例如,在“常规”文本中(即,在任何元素标记之外):

    <div>This is regular text</div>
    

    以及在属性值内:

    <input value="this is value text">
    

    而且,我相信,在HTML注释中:

    <!-- This text here might be programmatically generated
    and could, in theory, contain the double-hyphen character
    sequence, which is verboten inside comments -->
    

    这三种文本都有 不同的 为将其视为非标记,必须对其进行转义的规则。所以,我的第一个问题是,HTML中是否还有其他上下文可以将字符解释为标记/控制字符?上面的上下文显然对需要转义的内容有不同的规则。

    第二个问题是,需要转义的规范的、全局安全的字符列表(对于每个上下文)是什么,以确保将任何嵌入的文本视为非标记?例如,在理论上,您只需要转义“和”在属性值中,因为 在属性值内 只有结束分隔符字符(“或”取决于属性值以哪个分隔符开头)才具有控制意义。同样,在“常规”文本中,只有<和&具有控制含义。(我意识到并非所有的HTML解析器都是相同的。我最感兴趣的是,为了满足符合规范的解析器,需要转义的最小字符集是什么。)

    切向:以下文本将引发HTML 4.01 Strict错误:

    <a href="http://example.com/file.php?x=1&y=2">foo</a>
    

    具体来说,它说它不知道实体“&y”应该是什么。但是,如果您在&之后放置一个空格,它将验证是否正确。但是,如果您是在运行中生成它,那么您可能不想检查每次使用&是否会导致验证错误,而只需转义所有&内部属性值。

    5 回复  |  直到 11 年前
        1
  •  11
  •   bobince    15 年前
    <div>This is regular text</div>
    

    文本内容: & 必须逃跑。 < 必须逃跑。

    如果以非UTF编码生成文档,则必须转义不适合所选编码的字符。

    在XHTML(通常是XML)中,序列 ]]> 不能出现在文本内容中,因此在这种特定情况下,该序列中的一个字符必须转义,传统上 > . 为了一致性,规范化XML规范选择转义 > 每次在文本内容中,对于转义函数来说这不是一个糟糕的策略,尽管您当然可以跳过它进行手工创作。

    <input value="this is value text">
    

    属性值: & 必须逃跑。属性值分隔符 " ' 必须逃跑。如果没有使用属性值分隔符(不要这样做),则不可能进行转义。

    规范XML总是选择 作为分隔符,因此会对其进行转义。这个 > 属性值中不需要转义字符,规范XML也不需要转义字符。HTML4规范建议的编码 > 不管怎样,为了向后兼容,但这只影响到少数真正古老和可怕的浏览器,现在没有人记得;您可以忽略这一点。

    在XHTML中 < 必须逃跑。虽然你可以在HTML4中逃脱,但这不是一个好主意。

    要在属性值中包含制表符、CR或LF(属性值归一化算法不将它们转换为纯空格),必须将它们编码为字符引用。

    对于文本内容和属性值 :在XML 1.1下的XHTML中,必须转义受限制的字符,即删除字符和c0和c1控制代码、减号制表符、CR、LF和NEL。总共, [\x01-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F] . 在XML 1.1中,空字符可能根本不包括在内,甚至是转义的。在XML 1.1之外,您根本不能使用这些字符中的任何一个,也没有一个好的理由让您愿意这样做。

    <!-- This text here might be programmatically generated
    and could, in theory, contain the double-hyphen character
    sequence, which is verboten inside comments -->
    

    是的,但由于无法从评论中逃脱,所以您对此无能为力。如果你写 <!-- &lt; --> 字面意思是包含符号和字母L-字母T-分号的注释,并将在DOM或其他信息集中反映出来。包含以下内容的注释 -- 根本无法序列化。

    <![CDATA[ 截面和 <?pi XML中的_s也不能使用转义。将CDATA部分序列化的传统解决方案包括 ] Sequence是将该序列拆分为两个CDATA部分,这样就不会同时出现。不能在单个CDATA节中将其序列化,也不能将pi序列化为 ?> 在数据中。

    像这样的CDATA元素 <script> <style> 在HTML中(不是XHTML)不能包含 </ (etago)排序,因为这会提前结束元素,如果后面没有结束标记名,则会出错。由于在CDATA元素中不可能进行转义,因此必须避免此序列,并绕过此序列(例如,通过 document.write('</p>') 进入之内 document.write('<\/p>'); . (你会看到很多更复杂的愚蠢策略,比如打电话 unescape 在JS-%编码的字符串上;甚至经常 '</scr'+'ipt>' 这仍然是非常无效的。)

    在HTML和XML中,还有一个上下文应用了不同的规则,它在DTD中(包括doctype声明中的内部子集,如果有),其中 % 角色有特殊的能力,需要转义才能真正使用。但是作为一个HTML文档的作者,你不太可能需要去接近整个混乱的地方。

    The following text will throw errors as HTML 4.01 Strict:
    
    <a href="http://example.com/file.php?x=1&y=2">foo</a>
    

    是的,这在过渡时期也是一个错误。

    If you put a space after the &, however, it validates just fine. 
    

    是的,根据SGML的规定,除了 [A-Za-z] # 不作为引用开始解析。不过,依靠这个不是个好主意。(当然,XHTML中的格式不好。)

        2
  •  1
  •   Amadiere    15 年前

    上面的上下文显然对需要转义的内容有不同的规则。

    我不确定不同的元素是否有如您所说的不同的编码规则。您列出的所有示例都需要HTML编码。

    例如。

    <h1>Fish &amp; Chips</h1>
    <img alt="Awesome picture of Meat Pie &amp; Chips" />
    <a href="products.aspx?type=1&amp;meal=fish%20%26%20chips&amp;page=1">Fish &amp; Chips</a>
    

    最后一个示例还包括一些与符号(&)的URL编码,此时,它的内容会变得复杂(将与符号作为数据发送,这就是必须对其进行编码的原因)。

    所以,我的第一个问题是,HTML中是否还有其他上下文可以将字符解释为标记/控制字符?

    HTML文档中的任何地方,如果控制字符没有被用作控制字符,则应该对它们进行编码(这是一个很好的经验法则)。大多数情况下,它的HTML编码&或>等。其他情况下,当试图通过URL传递这些字符时,请使用URL编码%20、%26等。

    第二个问题是,需要转义的规范的、全局安全的字符列表(对于每个上下文)是什么,以确保将任何嵌入的文本视为非标记?

    我想说的是 Wikipedia article 对此有一些很好的评论,可能值得一读-同时 W3 Schools article 我想这是一个很好的观点。大多数语言都有内置的函数来准备文本作为安全的HTML,因此可能值得检查您选择的语言(如果您确实使用了任何脚本语言,而不是手工编码HTML)。

    具体来说,维基百科说:“字符<、>、&用于分隔标记、属性值和字符引用。字符实体引用<、&gt;、&quot;和&amp;amp;amp;amp;是在HTML、XML和SGML中预定义的,可用于字符的文本表示。”

    对于URL编码, this article seems a good starting point .

    我已经胡思乱想了一下:这一切都排除了XML/XHTML的思想,XML/XHTML将其他所有的球类游戏带到了球场上,它要求几乎所有的世界和它的狗都需要编码。如果您使用脚本语言并通过它写出一个变量,那么我确信找到内置函数或下载一个库会更容易。:)我希望这个答案的范围是正确的,不会错过要点或问题,也不会以错误的语调出现。:)

        3
  •  1
  •   Mike Fauzy    14 年前

    如果您正在寻找在Web浏览器(包括HTML、javascript和样式表)中转义字符的最佳实践,那么迈克尔·考茨的XSS预防性摘要很可能就是您要寻找的。它包括对不同解释上下文的描述、指示如何在每个上下文中编码字符的表和代码示例(使用ESAPI)。

    http://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet

        4
  •  0
  •   Chase Seibert    15 年前

    如果您关心最终HTML的有效性,那么可以考虑通过DOM构建HTML,而不是作为文本。

    你不会说你的目标是什么环境。

        5
  •  0
  •   RichieHindle    11 年前

    当心 <script> 然后 <!-- 然后 <脚本> 再次,进入双转义状态,在这种状态下,您可能永远都不想这样,所以理想情况下,您应该逃离 < 在脚本的字符串(和regexps)中使用“\u003c”,以避免意外触发它。

    你可以在这里了解更多 http://qbolec-memdump.blogspot.com/2013/11/script-tag-content-madness.html