Markdown、BBCode、Textile和MediaWiki标记语言实质上都是相同的概念,因此我会将它们归为两个类别:HTML和纯文本标记。
HTML的内容已经处于适合Web内容的“可呈现”形式。这很好,可以节省处理时间,并且它是一种易于解析的语言。几乎任何编程语言中都有数十个库可处理HTML内容,将其转换为其他格式等等。主要缺点是由于早期Web日的松散标准,HTML可能变化非常大,当接受用户的HTML时,您不能总是依赖理智的输入。正如指出的那样,清理或消毒HTML通常非常困难,特别是因为它未按照XML的方式遵循正常的标记规则(即未正确关闭标记很常见)。
出于以下原因,经常使用此类别:
最重要的是用户输入被用于什么目的。如果您计划保留数据并可能需要重新排列格式等操作,则使用精心设计的抽象格式来存储信息是有意义的。如果因为任何原因需要手动处理原始数据,则最好选用易于人类阅读的格式,这样更加方便。如果您只需要在网页(或报告等HTML文档)中显示内容,并且不必担心将其转换或未来可靠性,则将其存储在HTML中是一个合理的做法。
Jeff在编写SO的初期阶段,在codinghorror.com上讨论了一些优缺点。我认为这是值得一读的。
@netrox 数据库不是问题,浏览器输出才是。
唯一的问题是最终呈现可能会被用户插入的HTML破坏。例如,用户可以打开一个<li>
标签但从未关闭它,这取决于页面结构,可能会潜在地破坏其后的整个布局。或者另一个例子是打开一个<strong>
标签而没有关闭它,使得所有剩余内容都变成粗体。
因此,不仅必须验证允许的标记,还必须确切地确定如何允许某些标记而不允许其他标记?因为使用htmlspecialchars()
PHP方法很容易防止解析所有HTML标记,但是当涉及到允许某些标记时,您将不得不寻找其他方法。有strip_tags()
PHP函数可用,它会删除(完全删除)非允许标记,但这意味着以不良方式更改用户的内容,防止用户发布简单的代码(用于共享/显示,而不是用于处理的代码)。
除了破坏布局之外,您还必须考虑XSS攻击,例如将javascript插入到链接的href属性中,这可能会将用户重定向到另一个站点。请参阅可能的XSS攻击的长列表:https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet。
正如您所看到的,防止所有HTML标签被解释非常容易,但仅防止某些标记则要复杂得多。为了理解这一点,您可以查看巨大的"HTML Purifier"框架,其唯一目的是允许某些HTML标签,并确保输出的HTML有效(即不会破坏页面)且免受XSS攻击。
许多不同的标记语言被创建出来,因为清理HTML可能更加困难。
真的吗?为什么会这么难呢?有函数可以删除潜在危险的属性或标签,并在将其输入数据库或文件之前验证HTML。你能给我举一些清理HTML的困难例子吗?