它们是否与XML相同,或者加上空格( )?

我发现了一些巨大的HTML转义字符列表,但我不认为他们必须转义。我想知道有什么需要逃脱。


如果将文本内容插入到文档中需要文本内容的位置1,通常只需要像在XML中那样转义相同的字符。在元素内部,这只包括实体转义&和元素分隔符小于号和大于号< >:

& becomes &amp;
< becomes &lt;
> becomes &gt;

在属性值内部,你还必须转义你正在使用的引号字符:

" becomes &quot;
' becomes &#39;

在某些情况下,跳过其中一些字符可能是安全的,但我鼓励您在所有情况下都转义所有五个字符,以减少出错的几率。

如果您的文档编码不支持您正在使用的所有字符,例如,如果您试图在ascii编码的文档中使用表情符号,则还需要转义这些字符。现在大多数文档都使用完全支持unicode的UTF-8编码进行编码,这是不必要的。

一般来说,你不应该将空格转义为&nbsp;,不是一个正常的空间,它是一个不间断的空间。您可以使用这些代替普通空格来防止在两个单词之间插入换行符,或者插入额外的空格而不自动折叠,但这种情况通常很少见。除非有设计限制,否则不要这样做。


我所说的“期望文本内容的位置”是指应用正常解析规则的元素或带引号的属性值内部。例如:< p > < / p >或< p title =“这里”> < / p >。上面所写的内容不适用于具有特殊解析规则或含义的内容,例如脚本或样式标记中的内容,或者作为元素或属性名的内容。例如:<NOT-HERE>…> < /不在>、<脚本不在> < /脚本,<时尚>不在> < /风格,或< p不在这里 ="...">...</ p >。

在这些上下文中,规则更加复杂,更容易引入安全漏洞。我强烈建议您不要在这些位置中插入动态内容。我曾见过有能力的安全意识的开发人员团队引入漏洞,因为他们假设他们已经正确地编码了这些值,但遗漏了一个边缘情况。通常有一个更安全的替代方案,比如将动态值放在属性中,然后用JavaScript处理它。

如果必须,请阅读开放Web应用程序安全项目的XSS预防规则,以帮助您了解需要牢记的一些问题。


这取决于上下文。HTML中一些可能的上下文:

文档主体 在公共属性内部 内部脚本标记 内部样式标签 几个!

请参阅OWASP的跨站点脚本预防备考单,特别是“为什么我不能只使用HTML实体编码不受信任的数据?”和“XSS预防规则”部分。但是,最好阅读整个文档。


基本上,在HTML和XML文件中有三个主要字符应该总是转义,这样它们就不会与其他标记交互,所以正如你可能期望的那样,其中两个是语法包装器,它们是<>,它们如下所示:

 1)  &lt; (<)
    
 2)  &gt; (>)
    
 3)  &amp; (&)

我们也可以使用双引号(")作为",单引号(')作为&apos

避免将动态内容放在<script>和<style>中。这些规则不适用于他们。例如,如果你必须在a中包含JSON,将<替换为\x3c,将U+2028字符替换为\u2028,在JSON序列化后将U+2029替换为\u2029。)

HTML转义字符:完整列表: http://www.theukwebdesigncompany.com/articles/entity-escape-characters.php

所以你需要转义<或&,当后面跟任何可以开始字符引用的东西时。同样,对于带引号的属性,关于&号的规则是唯一这样的规则,因为匹配的引号是唯一会终止一个属性的东西。但如果您不想在此处终止属性值,请转义引号。

Changing to UTF-8 means re-saving your file: Using the character encoding UTF-8 for your page means that you can avoid the need for most escapes and just work with characters. Note, however, that to change the encoding of your document, it is not enough to just change the encoding declaration at the top of the page or on the server. You need to re-save your document in that encoding. For help understanding how to do that with your application read Setting encoding in web authoring applications. Invisible or ambiguous characters: A particularly useful role for escapes is to represent characters that are invisible or ambiguous in presentation. One example would be Unicode character U+200F RIGHT-TO-LEFT MARK. This character can be used to clarify directionality in bidirectional text (eg. when using the Arabic or Hebrew scripts). It has no graphic form, however, so it is difficult to see where these characters are in the text, and if they are lost or forgotten they could create unexpected results during later editing. Using ‏ (or its numeric character reference equivalent ‏) instead makes it very easy to spot these characters. An example of an ambiguous character is U+00A0 NO-BREAK SPACE. This type of space prevents line breaking, but it looks just like any other space when used as a character. Using   makes it quite clear where such spaces appear in the text.


确切的答案取决于上下文。一般来说,这些字符不能出现(HTML 5.2§3.2.4.2.5):

Text nodes and attribute values must consist of Unicode characters, must not contain U+0000 characters, must not contain permanently undefined Unicode characters (noncharacters), and must not contain control characters other than space characters. This specification includes extra constraints on the exact value of Text nodes and attribute values depending on their precise context. For elements in HTML, the constraints of the Text content model also depends on the kind of element. For instance, an "<" inside a textarea element does not need to be escaped in HTML because textarea is an escapable raw text element.

这些限制分散在规范中。例如,属性值(§8.1.2.3)不能包含不明确的&号,并且(i)为空,(ii)在单引号内(因此不能包含U+0027撇号字符'),(iii)在双引号内(不能包含U+0022引号字符'),或(iv)不带引号-具有以下限制:

... 不能包含任何空格字符、U+0022引号字符(")、U+0027撇号字符(')、U+003D等号字符(=)、U+003C小于号字符(<)、U+003E大于号字符(>)或U+0060重音字符('),并且不能为空字符串。


如果你想使用JavaScript转义一串标记,有:

https://github.com/component/escape-html

或者,如果你不想拉入依赖项,这里是同样的事情,尽管稍微慢一点,因为它使用split/map/join而不是charCodeAt/substring。

function escapeMarkup (dangerousInput) {
  const dangerousString = String(dangerousInput);
  const matchHtmlRegExp = /["'&<>]/;
  const match = matchHtmlRegExp.exec(dangerousString);
  if (!match) {
    return dangerousInput;
  }

  const encodedSymbolMap = {
    '"': '&quot;',
    '\'': '&#39;',
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;'
  };
  const dangerousCharacters = dangerousString.split('');
  const safeCharacters = dangerousCharacters.map(function (character) {
    return encodedSymbolMap[character] || character;
  });
  const safeString = safeCharacters.join('');
  return safeString;
}