XSS攻击预防

时间:2010-05-06 13:38:54

标签: java javascript security xss

我正在开发一个网络应用,用户可以在其中回复博客条目。这是一个安全问题,因为它们可以发送危险数据,这些数据将呈现给其他用户(并由javascript执行)。

他们无法格式化他们发送的文字。没有“大胆”,没有颜色,没有任何东西。只是简单的文字。 我想出了这个正则表达式来解决我的问题:

[^\\w\\s.?!()]

所以任何不是单词字符(aZ,AZ,0-9),而不是空格,“。”,“?”,“!”,“(或”)“将被替换为空串。每个quatation标记将被替换为:“& quot”。

我检查前端的数据,然后在服务器上查看。

有人可以绕过这个“解决方案”吗?

我想知道StackOverflow是如何做到这一点的?这里有很多格式,所以他们必须用它做好工作。

6 个答案:

答案 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 '&lt;'
'>' (greater than) becomes '&gt;'

这解决了最低级别的XSS问题,并且您不需要一些您不理解的复杂库/正则表达式(并且在所有复杂性都是安全性的敌人后可能不安全)。

确保运行free xss scanner 测试您的XSS过滤器

答案 1 :(得分:2)

我同意Tomalak,只是想补充几点。

  1. 不允许使用HTML标记。这个想法是在呈现它们之前将用户输入视为文本和html-escape字符。为此目的使用OWASP's ESAPI项目。你应该知道的This page explains the various possible encodings
  2. 如果您必须允许HTML标记,请使用库为您进行过滤。不要写自己的正则表达式;他们很难做对。使用OWASP's Anti-Samy project - 它是专为此用例设计的。

答案 2 :(得分:2)

我建议阅读the XSS Prevention Cheat Sheet,其中详细介绍了避免XSS攻击的最佳做法。 基本上,您需要过滤的内容取决于它将被使用的上下文。

例如,在这种情况下:

<body>...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...</body>

你需要这样做:

& --> &amp;
< --> &lt;
> --> &gt;
" --> &quot;
' --> &#x27;     &apos; is not recommended
/ --> &#x2F;     forward slash is included as it helps end an HTML entity

虽然在href=""示例中你需要做一个urlescape:

  

“除了字母数字字符外,使用%HH转义格式转义ASCII值小于256的所有字符。在数据中包含不受信任的数据:不应允许URL,因为没有好的方法可以通过转义禁用攻击防止切换出URL。所有属性都应该引用。不带引号的属性可以打破多个字符,包括[space]%* +, - /;&lt; =&gt; ^和|。注意实体编码是没用的在这种情况下。“

虽然所引用的文章给出了完整的判决,但希望在这个答案中有足够的信息可以帮助你开始。

答案 3 :(得分:1)

  1. 不允许使用HTML标记。
  2. 如果没有HTML首先转义,请不要输出用户输入的任何内容。这是更重要的一点!这样做,你就不会遇到XSS问题。
  3. 提供预览功能,以便用户在发布前看到它的样子。
  4. 如果您必须允许HTML标记,请定义白名单并检查用户输入。你甚至可以使用正则表达式。

    假设您允许<p><a href="..."><img src="...">

    1. 在用户字符串中找到与<\S[^>]*>
    2. 匹配的所有内容
    3. 每次比赛,请与<(p|a href="[^"]+"|img src="[^"]+")/?>|</(a|p)>
    4. 核对
    5. 如果它不适合严格的正则表达式,请扔掉它。
    6. 见上文第2点。
    7. 尽量故意破坏你的系统。请别人试着破坏你的系统。

答案 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

如果您允许具有hrefsrc属性的HTML代码,请确保它们指向http(s):个计划,而不是javascript:个。