我正在开发一个网络应用,用户可以在其中回复博客条目。这是一个安全问题,因为它们可以发送危险数据,这些数据将呈现给其他用户(并由javascript执行)。
他们无法格式化他们发送的文字。没有“大胆”,没有颜色,没有任何东西。只是简单的文字。 我想出了这个正则表达式来解决我的问题:
[^\\w\\s.?!()]
所以任何不是单词字符(aZ,AZ,0-9),而不是空格,“。”,“?”,“!”,“(或”)“将被替换为空串。每个quatation标记将被替换为:“& quot”。
我检查前端的数据,然后在服务器上查看。
有人可以绕过这个“解决方案”吗?
我想知道StackOverflow是如何做到这一点的?这里有很多格式,所以他们必须用它做好工作。
答案 0 :(得分:3)
如果您只想要简单的文字,请不要担心过滤特定的HTML标记。你想要等于PHP的htmlspecialchars()。使用它的一个好方法是print htmlspecialchars($var,ENT_QUOTES);
此函数将执行以下编码:
'&' (ampersand) becomes '&'
'"' (double quote) becomes '"' when ENT_NOQUOTES is not set.
''' (single quote) becomes ''' only when ENT_QUOTES is set.
'<' (less than) becomes '<'
'>' (greater than) becomes '>'
这解决了最低级别的XSS问题,并且您不需要一些您不理解的复杂库/正则表达式(并且在所有复杂性都是安全性的敌人后可能不安全)。
确保运行free xss scanner 测试您的XSS过滤器。
答案 1 :(得分:2)
我同意Tomalak,只是想补充几点。
答案 2 :(得分:2)
我建议阅读the XSS Prevention Cheat Sheet,其中详细介绍了避免XSS攻击的最佳做法。 基本上,您需要过滤的内容取决于它将被使用的上下文。
例如,在这种情况下:
<body>...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...</body>
你需要这样做:
& --> &
< --> <
> --> >
" --> "
' --> ' ' is not recommended
/ --> / forward slash is included as it helps end an HTML entity
虽然在href=""
示例中你需要做一个urlescape:
“除了字母数字字符外,使用
%HH
转义格式转义ASCII值小于256的所有字符。在数据中包含不受信任的数据:不应允许URL,因为没有好的方法可以通过转义禁用攻击防止切换出URL。所有属性都应该引用。不带引号的属性可以打破多个字符,包括[space]%* +, - /;&lt; =&gt; ^和|。注意实体编码是没用的在这种情况下。“
虽然所引用的文章给出了完整的判决,但希望在这个答案中有足够的信息可以帮助你开始。
答案 3 :(得分:1)
如果您必须允许HTML标记,请定义白名单并检查用户输入。你甚至可以使用正则表达式。
假设您允许<p>
,<a href="...">
和<img src="...">
:
<\S[^>]*>
<(p|a href="[^"]+"|img src="[^"]+")/?>|</(a|p)>
答案 4 :(得分:0)
前端可以使用Fiddler绕过,例如通过附加表单信息。 在后端使用html编码,例如&LT a取代; =&amp; lt; a&amp; gt;
这样文本将显示为文本而不是html元素。
答案 5 :(得分:0)
首先删除所有不良字符序列,例如超长UTF-8,无效的Unicode。
你是否需要更明确是否&lt;和&gt;被剥离或变成实体。
您还需要删除或编码双和单引号,否则攻击者可以添加您不期望的内部事件,例如: &lt; input name ='comment'value ='foo 'onSomething = payload; a =''&gt;
如果您真的想要允许某些HTML子集,请小心尝试使用正则表达式解析它,尤其是您自己提出的那些,例如:浏览器会在正则表达式可能不匹配的情况下呈现棘手的标记<a b=">"onMouseOver=alert(42)>
。查看前面提到的Anti-Samy 。
如果您允许具有href
或src
属性的HTML代码,请确保它们指向http(s):
个计划,而不是javascript:
个。