`
conkeyn
  • 浏览: 1504244 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

XSS跨站脚本攻击在Java开发中防范的方法

 
阅读更多
详细描述 跨站脚本攻击(也称为XSS)指利用网站漏洞从用户那里恶意盗取信息。用户在浏览网站、使用即时通讯软件、甚至在阅读电子邮件时,通常会点击其中的链接。攻击者通过在链接中插入恶意代码,就能够盗取用户信息或在终端用户系统上执行恶意代码。

成功的跨站脚本攻击所带来的主要问题包括:

帐号劫持 - 攻击者可以在会话cookie过期之前劫持用户的会话,并以访问ULR用户的权限执行操作,如发布数据库查询并查看结果。

恶意脚本执行 - 用户可能在不知情的情况下执行攻击者注入到动态生成页面中的JavaScript、VBScript、ActiveX、HTML甚至Flash内容。

蠕虫传播 - 通过Ajax应用,跨站脚本可以以类似于病毒的方式传播。跨站脚本负载可以自动将其自身注入到页面中,并通过更多的跨站脚本轻易的重新注入同一主机,而
所有这些都无需手动刷新页面。因此,跨站脚本可以使用复杂的HTTP方式发送多个请求,并以用户不可视的方式自我传播。

信息窃取 - 攻击者可以通过重新定向和伪造站点将用户连接到攻击者所选择的恶意服务器并获得用户所输入的任何信息。

拒绝服务 - 通常攻击者通过在包含有跨站脚本漏洞的站点上使用畸形的显示请求,就可以导致主机站点反复的自我查询,出现拒绝服务的情况。

浏览器重新定向 - 在某些使用帧的站点上,用户可能在实际上已经被重新定向到恶意站点的情况下误导为仍处在原始站点上,因为浏览权地址栏中的URL仍保持不变。这是由于没有重新定向整个页面,而只是执行JavaScript的帧。

控制用户设置 - 攻击者可以恶意更改用户设置。
本漏洞属于Web应用安全常见漏洞。
解决办法 推荐措施包括实施安全编程技术确保正确过滤用户提供的数据,并编码所有用户提供的数据以防以可执行的格式向终端用户发送注入的脚本。

对于开发
========

可通过仔细验证所有输入和正确编码所有输出来防范跨站脚本攻击。可使用标准的ASP.NET验证控件或直接在代码中实施验证,要尽可能使用严格的模版。

输出编码要确保在将内容发送给客户端之前对任何可脚本化的内容都进行了正确的HTML编码。可通过HttpUtility.HtmlEncode函数实现,如以下Label控件示例所示:

Label2.Text = HttpUtility.HtmlEncode(input)

要考虑用户输入通过应用可能用到的所有路径。例如,如果数据是由用户输入的,存储在数据库中,然后再重新显示,就必须要确保在每次检索的时候都能正确编 码。如果必须允许自由格式文本输入(如在消息板中),而又希望允许使用一些HTML格式,则可以通过仅明确允许很小的安全标签列表来安全的处理这种情况, 如下所示:

C#示例:
StringBuilder sb = new StringBuilder(HttpUtility.HtmlEncode(htmlInputTxt.Text));
sb.Replace("&amp;lt;b&amp;gt;", "<b>");
sb.Replace("&amp;lt;/b&amp;gt;", "</b>");
sb.Replace("&amp;lt;i&amp;gt;", "<i>");
sb.Replace("&amp;lt;/i&amp;gt;", "</i>");
Response.Write(sb.ToString());

VB.NET示例:
Dim sb As StringBuilder = New StringBuilder( _
HttpUtility.HtmlEncode(input))
sb.Replace("&amp;lt;b&amp;gt;", "<b>")
sb.Replace("&amp;lt;/b&amp;gt;", "</b>")
sb.Replace("&amp;lt;i&amp;gt;", "<i>")
sb.Replace("&amp;lt;/i&amp;gt;", "</i>")
Response.Write(sb.ToString())

Java示例:
public static String HTMLEncode(String aText){
final StringBuilder result = new StringBuilder();
final StringCharacterIterator iterator = new StringCharacterIterator(aText);
char character = iterator.current();
while (character != CharacterIterator.DONE ){
if (character == '<') {
result.append("&amp;lt;");
}
else if (character == '>') {
result.append("&amp;gt;");
}
else if (character == '&') {
result.append("&amp;amp;");
}
else if (character == '\"') {
result.append("&amp;quot;");
}
else {
//the char is not a special one
//add it to the result as is
result.append(character);
}
character = iterator.next();
}
return result.toString();
}

以下建议可帮助构建能够抵御跨站脚本攻击的web应用。

定义允许的内容。确保web应用对所有输入参数(cookies、头、查询字符串、表单、隐藏字段等)验证严格定义的预期结果。

检查POST和GET请求的响应,确保返回内容是预期的且有效。

通过编码用户提供的数据从用户输入中删除冲突字符、括号、单双引号。这可以防范以可执行的方式向终端用户发送注入的脚本。

在可能的时候将所有客户端提供的数据仅限于字母数字的数据。使用这种过滤方案时,如果用户输入 了<script>alertdocumentcookie( 'aaa') </script>,就会被减少为scriptalertdocumentcookiescript。如果必须使用非字母数字字符,在 HTTP响应中使用之前将其编码为HTML实体,这样就无法将其用于修改HTML文档的结构。

使用双重用户认证机制而不是单重认证。

在修改或使用脚本之前确认其来源。

在自己的代码中使用时不要明确的信任任何来自他人的脚本,无论是从web下载还是来自熟人。

大多数服务器端脚本语言都提供了内嵌方式将输入变量的值转换为正确的不可解释HTML。应使用这种方式在将输入显示给客户端之前过滤所有输入。

PHP: string htmlspecialchars (string string [, int quote_style])

ASP / ASP.NET: Server.HTMLEncode (strHTML String)

对于安全操作
============

服务器端编码指的是首先通过编码函数发送所有的动态内容,使用所选择字符集中的代码替换Scripting标签,这可以帮助防范跨站脚本攻击。服务器端编码的缺点是可能耗费资源,对一些web服务器的性能产生负面影响。

如果必须允许站点用户使用HTML标签,如允许用户使用的格式化标签的公告栏,则应限制可使用的标签。创建可接受标签的列表,如粗体字、斜体字或下划线,并仅允许使用这些,拒绝任何其他标签。以下是一些可帮助检测跨站脚本的正则表达式。

简单跨站脚本攻击的正则表达式:
/((\%3C)|<)((\%2F)|\/)*[a-z0-9\%]+((\%3E)|>)/ix

应如下将上述正则表达式添加到新的Snort规则:

alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"NIICross-Site Scripting attempt"; flow:to_server,established;pcre:"/((\%3C)|<)((\%2F)|\/)*[a-z0-9\%]+((\%3E)|>)/i";classtype:Web-application-attack; sid:9000; rev:5;)

跨站脚本攻击的偏执行正则表达式:
/((\%3C)|<)[^\n]+((\%3E)|>)/I

这条特征仅仅查找起始的HTML标签及其对等的16进制,之后的一个或多个字符为非换行符,再之后为结尾标签或其对等的16进制。这可能导致一些误报,具 体取决于Web应用和Web服务器的架构。但这种方式可以确保捕获任何攻击,甚至远程类似的跨站脚本攻击。对于公众方面,可以加强教育程序,帮助用户防范 可用于帐号劫持和其他形式身份窃取的在线欺诈,如网络钓鱼。

对于质量保证
============

修复跨站脚本漏洞最终要求基于代码的修复。“对于开发”和“对于安全操作”部分所述步骤可为开发人员提供修复这些问题所需的信息。以下步骤概括了如何对应用程序手动测试跨站脚本。

步骤1. 在浏览器中打开任意Web站点,查找可接受用户输入的位置,如搜索表单或某些登录页面。在搜索框中输入test并发送给Web服务器。

步骤2. 寻找返回类似于Your search for 'test' did not find any items或Invalid login test页面的WEB服务器。如果结果页面中出现了test,请继续。

步骤3. 如果要测试跨站脚本,在之前使用的同一搜索或登录框中输入<script>alert('hello')</script>字符串并发送给Web服务器。

步骤4. 如果服务器所响应的弹出框显示hello,则站点受跨站脚本影响。

步骤5. 即使步骤4失败,站点没有返回这条信息,仍可能存在风险。在浏览器中点击“查看源码”选项,查看Web页面的实际HTML代码。现在查找发送给服务器 的<script>字符串,如果在源码中看到整个<script>alert('hello')</script> 文本,则Web服务器受跨站脚本的影响。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics