XSS攻击预防

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

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

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

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

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

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

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

如果您只想要简单的文本, 请不要担心过滤特定的html标记 。 你想要equvilent到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问题,并且您不需要一些您不理解的复杂库/正则表达式(并且在所有复杂性都是安全性的敌人之后可能不安全)。

确保通过运行免费的xss扫描仪来测试您的XSS FILTER

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

  1. 不允许使用HTML标记。 我们的想法是在呈现它们之前将用户输入视为文本和html-escape字符。 为此目的使用OWASP的ESAPI项目。 本页介绍了您应该了解的各种可能的编码 。
  2. 如果必须允许HTML标记,请使用库为您进行过滤。 不要写自己的正则表达式; 他们很难做对。 使用OWASP的Anti-Samy项目 – 它专为此用例而设计。
  1. 不允许使用HTML标记。
  2. 如果没有HTML首先转义,请不要输出用户输入的任何内容。 这是更重要的一点! 这样做,你将永远不会有XSS问题。
  3. 提供预览function,以便用户在发布之前查看其外观。

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

假设您允许

  1. 找到与<\S[^>]*>匹配的用户字符串中的所有内容
  2. 对于每场比赛,检查<(p|a href="[^"]+"|img src="[^"]+")/?>|
  3. 如果它不适合严格的正则表达式,扔掉它。
  4. 见上面第2点。
  5. 努力刻意破坏你的系统。 让别人试着打破你的系统。

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

例如,在这种情况下:

 https://stackoverflow.com/questions/2781574/xss-attack-prevention/...ESCAPE UNTRUSTED DATA BEFORE PUTTING HEREhttps://stackoverflow.com/questions/2781574/xss-attack-prevention/... 

你需要这样做:

 & --> & < --> < > --> > " --> " ' --> ' ' is not recommended / --> / forward slash is included as it helps end an HTML entity 

而在href=""示例中,您需要执行urlescape:

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

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

例如,通过附加表单信息,可以使用Fiddler绕过前端。 在后端使用html编码,例如 =&lt; a&gt;

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

首先删除任何错误的字符序列,例如超长的UTF-8,无效的Unicode。

无论<和>是剥离还是变成实体,您都需要更明确。

您还需要剥离或编码双引号单引号,否则攻击者可以添加您不期望的内部事件,例如‘comment’value =’foo’onSomething = payload; a =’ ‘ >

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

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