【问题标题】:How do I prevent html element from escaping parent? (security)如何防止 html 元素转义父级? (安全)
【发布时间】:2019-11-10 15:44:19
【问题描述】:

我尝试用谷歌搜索,但一切都与 css 相关,而不是安全性。

我有这个作为评论表:

<pre name="comment">
    <comment-content>
        This is a sample comment by a user
    </comment-content>
</pre>

我允许了一些受控的 html 标签,包括 [pre][/pre],这就是问题的开始。

如果我这样做:

<pre name="comment">
    <comment-content>
        This is a sample comment by a user
        [/pre]
        This text will be outside the comment container
    </comment-content>
</pre>

注释转义了 pre 标记,并忽略了它在 &lt;comment-content&gt;&lt;/comment-content&gt; 标记内的内容。我添加了这个标签作为阻止转义的尝试,但它不起作用。我还注意到我的受控 html 标签将在容器外运行。我有第二个未转义的容器,但是转义第一个容器的问题意味着如果我在该容器之外放置一个 &lt;pre&gt; 标记,它可能会被转义。我也尝试将容器加倍,但这也不起作用。

Here is an image of the [/pre] tag escaping the container

这里是 javascript 在后台执行的快速示例:

//I added .cleanHTML() as a similar function to php htmlentities() and .clean() is similar to php strip_tags()
let content = $(this).html().cleanHTML().clean();

commentHtml += '<pre name="comment" type="text/plain"><comment-content>'+setUserCommentHtml(content.clean())+'</comment-content></pre>';

$(this).html(commentHtml);

注意:我知道大多数安全性应该在服务器端完成,但也希望保持客户端的安全。

我基本上需要一种方法来强制 html 在第二个父结束标记起作用之前要求第一个结束标记。

【问题讨论】:

  • 在解析之前验证您的标签方案。如果失败,则将其全部视为文本(例如,textContent)并且不要解析它。
  • “验证您的标签方案”,这听起来是个不错的解决方案。在setUserCommentHtml() 函数内部,如果我推送到一个数组,每次用户打开一个标签时,然后在关闭它之前验证打开的标签,并从该列表中删除,这似乎有效。
  • 如果你did it a little differently,我认为解决起来很简单。为您的 pre 和 comment-content 元素创建 dom 元素节点,并将评论内容附加到其中。它会清理你的流浪 &lt;/pre&gt; 标签和其他“古怪”的 html 不当行为。
  • 是的,还要验证您正在使用的标签。那里应该有一些好的 Javascript bbcode 库。
  • 对于标签验证我有它需要存在于 const jsonList const customUserAllowedHtml = { "userTag": ["htmlTag", "userParam1=validHtmlParam1", "userParam2=validHtmlParam2", "userParam3=validHtmlParam3"], } 中的标签,如果参数不在此列表中,它会被删除。它基本上是用户可以使用的假 html

标签: javascript html security


【解决方案1】:

发布解决方案(在 cmets 的帮助下)作为标记为已解决的答案。

Jared Farrish 在 cmets 中回答了问题。

将我的 javascript 更改为类似这样可以解决问题:

//I added .cleanHTML() as a similar function to php htmlentities() and .clean() is similar to php strip_tags()
let content = $(this).html().cleanHTML().clean();

let setContentId = Math.floor(Math.random()*10000);
commentHtml += '<pre name="comment" type="text/plain"><comment-content set-content="'+setContentId+'"></comment-content></pre>';

$(this).html(commentHtml);

$('comment-content[set-content="'+setContentId+'"]').html(setUserCommentHtml(content.clean()));

我还在setUserCommentHtml()函数中添加了这个方法。

let htmlOpenTags = [];

//in a loop
if(tagType === 'close' && htmlOpenTags.includes(commentTag)){
    htmlOpenTags.splice(htmlOpenTags.lastIndexOf(commentTag));
    //close tag here
    ...
}else if(tagType === 'open'){
    htmlOpenTags.push(commentTag);
    //open tag here
    ...
}

如果我推送到一个数组,每次用户打开一个标签时,我可以在关闭它之前验证打开的标签是否存在于该数组中,并从列表中删除该标签。

编辑:堆栈溢出说我必须等待 2 天才能标记为答案

【讨论】:

    猜你喜欢
    • 2021-09-10
    • 1970-01-01
    • 2014-01-13
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多