在 HTML 元素中防止 XSS

Fa7*_*0nK 3 php xss

以下是否足以防止来自 HTML 元素内部的 XSS?

function XSS_encode_html ( $str )
{
    $str = str_replace ( '&', "&", $str );
    $str = str_replace ( '<', "&lt;", $str );
    $str = str_replace ( '>', "&gt;", $str );
    $str = str_replace ( '"', " &quot;", $str );
    $str = str_replace ( '\'', " &#x27;", $str );
    $str = str_replace ( '/', "&#x2F;", $str );

    return $str;
}
Run Code Online (Sandbox Code Playgroud)

正如这里提到的: -
https://www.owasp.org/index.php/Abridged_XSS_Prevention_Cheat_Sheet#RULE_.231_-_HTML_Escape_Before_Inserting_Untrusted_Data_into_HTML_Element_Content


编辑

我没有使用 htmlspecialchars() 因为: -

  1. 它不会改变 / 到 &#x2F;
  2. '(单引号)在设置 ENT_QUOTES 时变为 ' &#039;'(或&apos;)。

根据 OWASP,'(单引号)应该变成&#x27;叫我迂腐)并且
&apos;不推荐,因为它不在 HTML 规范中


Gum*_*mbo 5

在元素的内容中,唯一可能有害的字符是开始标记分隔符,<因为它可能表示某些标记声明的开始,无论是开始标记、结束标记还是注释。所以那个字符应该总是被转义。

其他字符不一定需要在元素内容中转义。

引号只需要在标签内转义,特别是当用于包含在相同引号内或根本不引用的属性值时。类似地,标记声明关闭分隔符>只需要在标签内转义,这里仅当在未引用的属性值中使用时。但是,建议也转义普通的 & 符号,以避免它们被错误地解释为字符引用的开始

现在至于替换的原因/,可能是由于 SGML 中的一个特性,标记语言 HTML 改编自,它允许所谓的空结束标记

要了解空结束标签在实践中的工作原理,请考虑将其与可定义为的元素结合使用:

<!ELEMENT ISBN  - -  CDATA --ISBN number-- >
Run Code Online (Sandbox Code Playgroud)

而不是输入 ISBN 号:

<ISBN>0 201 17535 5</ISBN>
Run Code Online (Sandbox Code Playgroud)

我们可以使用 null end-tag 选项以缩短的形式输入元素:

<ISBN/0 201 17535 5/
Run Code Online (Sandbox Code Playgroud)

但是,我从未见过任何浏览器实现过此功能。HTML 的语法规则一直比 SGML 语法规则更严格。

另一个更可能的原因是所谓的原始文本元素 ( scriptand style)的内容模型,它是具有以下限制的纯文本:

原始文本和 RCDATA 元素中的文本不得包含任何出现的字符串 " </" (U+003C LESS-THAN SIGN, U+002F SOLIDUS) 后跟不区分大小写匹配元素标签名称的字符,后跟以下字符之一“制表符”(U+0009)、“LF”(U+000A)、“FF”(U+000C)、“CR”(U+000D)、U+0020 空格、“ >”(U+003E) 或" /" (U+002F)。

这里说在原始文本元素中,例如script出现的</script/将表示结束标记:

<script>
alert(0</script/.exec("script").index)
</script>
Run Code Online (Sandbox Code Playgroud)

尽管 JavaScript 代码完全有效,但结束标记将用</script/. 但除此之外,/它不会受到任何伤害。而且,如果您只允许在 JavaScript 上下文中使用任意输入来转义 HTML,那您就已经注定要失败了。

顺便说一下,这些字符被转义为何种字符引用并不重要,无论是命名字符引用(即实体引用)还是数字字符引用,无论是十进制还是十六进制表示法。它们都引用了相同的字符。