2010-05-06 247 views
5

我正在开发一个Web应用程序,用户可以在其中回复博客条目。这是一个安全问题,因为他们可以发送将呈现给其他用户的危险数据(并由JavaScript执行)。XSS攻击防范

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

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

,所以,只要这不是一个单词字符(包括AZ,az,0-9),而不是一个空白,” !“,”(“或”)“将被替换为空字符串。比每个quatation标记都将替换为:“& quot”。

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

有没有什么方法有人可以绕过这个“解决方案”?

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

+0

什么是您的服务器端语言? – 2010-05-06 13:41:04

+0

Java。我使用Servlets – Colby77 2010-05-06 14:04:31

+0

你没有对'<>'说过任何事情,这可能是xss中使用的最重要的字符...... – rook 2010-05-06 18:05:12

回答

0

可以使用Fiddler旁路前端,例如追加表单信息。 在后端使用html编码,例如<a> = & lt; a & gt;

这样文本将显示为文本而不是html元素。

1
  1. 不允许HTML标记。
  2. 不输出没有HTML的用户输入的任何内容 - 首先转义它。这是更重要的一点!做到这一点,你永远不会有XSS问题。
  3. 提供预览功能,以便用户在发布前可以看到它的外观。

如果您必须允许HTML标记,请定义白名单并根据它检查用户输入。你甚至可以使用这个正则表达式。

说你让<p><a href="..."><img src="...">

  1. 发现,对于每场比赛比赛<\S[^>]*>
  2. 用户串的一切,检查它,<(p|a href="[^"]+"|img src="[^"]+")/?>|</(a|p)>
  3. ,如果它不符合这个严格的正则表达式, 把它扔掉。
  4. 请参阅上述第2点。
  5. 尽量刻意破坏您的系统。要求他人尝试破坏你的系统。
2

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

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

如果你只是想简单的文字不用担心过滤特定的html标签。你想要的PHP的htmlspecialchars() equvilent。使用一个很好的办法就是print htmlspecialchars($var,ENT_QUOTES);此功能将执行以下编码:

'&' (ampersand) becomes '&amp;' 
'"' (double quote) becomes '&quot;' when ENT_NOQUOTES is not set. 
''' (single quote) becomes '&#039;' only when ENT_QUOTES is set. 
'<' (less than) becomes '&lt;' 
'>' (greater than) becomes '&gt;' 

这是最低级解决XSS的问题,你不需要,你不要”一些复杂的库/正则表达式不明白(并且在所有的复杂性都成为安全的敌人之后可能是不安全的)。

请确保运行free xss scanner测试您的XSS FILTER

1

我建议您阅读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:

”除字母数字字符外,使用转义ASCII值小于256的所有字符转义格式。在数据中包含不受信任的数据:URL不应该被允许,因为没有好方法通过转义禁用攻击以防止切换出URL。所有的属性都应该被引用。未加引号的属性可以分解为许多字符,包括[空格]%* +, - /; < => ^和|。需要注意的是实体编码在这方面也没用。”

虽然引用的文章给出了完整的判决,希望有一个在这个答案足够的信息,让你开始。

0

第一删除任何坏的字符序列,如超长UTF-8,无效的Unicode。

你需要更明确是否<和>被剥离或变成实体。

您还需要剥离或编码双单引号,否则攻击者可以添加一个你没有想到的固有事件,例如, <输入名称=“评论”值=“富‘onSomething =有效载荷; A =’” >

如果你真的要允许HTML的一些子集,小心试图用正则表达式解析它,特别是那些你拿出你自己,例如浏览器将渲染棘手的标签<a b=">"onMouseOver=alert(42)>就好了,正则表达式可能会与它不匹配。看看前面提到的Anti-Samy

如果您允许具有hrefsrc属性的HTML标记,请确保它们指向http(s):方案,而不是javascript:方案。