我一直在研究一种不允许HTML格式化的系统。我目前使用的方法是在HTML实体插入数据库之前将其转义。我被告知我应该将原始文本插入数据库,并在输出时转义HTML实体。
我见过的其他类似问题看起来像HTML仍然可以用于格式化的情况,所以我要求的情况是根本不会使用HTML。
答案 0 :(得分:18)
是的,因为在某个阶段您需要访问输入的原始输入。这是因为......
我确实看到了关于从不想输入HTML的观点。你还用什么去剥离HTML标签?如果它是一个正则表达式,那么请留意可能输入类似内容的混淆用户......
3<4 :->
如果它是正则表达式,它们只会获得3
。
答案 1 :(得分:16)
在插入数据库之前执行转义时,您也会限制自己。假设您决定不使用HTML作为输出,而是使用JSON,纯文本等
如果你在你的数据库中存储了转义的html,你首先必须'unescape'存储在数据库中的值,只是为了再次将其重新转换为不同的格式。
也看到了这个完美的owasp article on xss prevention
答案 2 :(得分:4)
我通常会存储两个版本的文本。在进行正常页面请求时使用转义/格式化文本以避免每次转义/格式化的开销。当用户需要编辑现有条目时使用原始/原始文本,并且仅在创建或更改文本时发生转义/格式化。除非您有严格的存储空间限制,否则此策略非常有效,因为您将复制数据。
答案 3 :(得分:4)
另一个难以捉摸的问题:假设您输入的是其标题中包含字符串R&B
的记录。它将存储为R&B
。并假设我们有一个使用SQL的搜索功能:
$query = $database->prepare('SELECT * FROM table WHERE title LIKE ?');
$query->execute(array($searchString.'%'));
现在,如果有人搜索R&B
,则该行与该行不匹配,因为它存储为R&B
。平等,排序等情况相同。
当然,我们遇到的问题是没有搜索HTML标记,因为<span>
会在有人搜索span
时进行匹配。这可以通过将搜索功能委托给像Solr这样的外部服务来解决,或者通过将版本存储在第二个字段中来清除HTML标签,特殊字符等(用于全文搜索),类似于@limscoder建议的内容。 / p>
有一天,您可能会通过API或其他内容公开您的数据,而您的API用户可能认为它未经转义。
几个月后,一名新团队成员加入。作为一个训练有素的开发人员,他总是使用html转义,现在只看到所有内容都被双重转义(例如,标题显示为He said "nuff"
而不是He said "nuff"
。)
htmlspecialchars()
的引用样式(例如ENT_QUOTES
,ENT_COMPAT
等)会咬你,如果你使用的是默认的以外的任何东西而忘记使用存储/输出中的报价方式相同。
使用htmlentities()
存储,htmlspecialchars()
输出,反之亦然(使用相应的反函数)时会发生类似的问题。您的HTML将被Ü
,Ç
等污染。
如果有多个开发人员在相同的代码库上工作,则更容易被滥用。