图 4. 评论界面
发表的内容是攻击者设计的一个攻击脚本,这个脚本被直接保存到了网页中。任何查看此页面的其他用户,他们的信息都会被盗取。
图 5. 提交攻击脚本
>解决方法 对于保存型 XSS 漏洞,由于我们无可避免的需要显示用户提交的数据,所以过滤是必然的,过滤 < 和 > 等符号可以避免上述漏洞的发生。 问题代码 --- 重定向漏洞 如果应用程序提取用户可控制的输入,并使用这个数据执行一个重定向,指示用户的浏览器访问一个不同于用户要求的 URL,那么就会造成重定向漏洞。 例子允许用户输入一个重定向路径,由服务器执行跳转。
清单 5. index.jsp 主要代码
<form action="Redirect"> 地址:<input name="target" type="text"><br> <input type="submit" value="提交"> </form> |
清单 6. Redirect.java 主要代码
String param = request.getParameter("target"); if (param != null && !param.equals("")) { response.sendRedirect(param); } |
用户在 index.jsp 的表单中输入跳转的路径,服务器端的 Redirect.java 执行 sendRedirect 重定向。 问题分析 程序允许让用户设置重定向地址,而并没对地址内容进行验证处理,而是直接跳转,那么攻击者完全可以设计一个攻击 URL,其中包含攻击者设计的攻击内容,使用钓鱼攻击,诱使用户点击此 URL,受到攻击。 攻击此程序
图 6. 输入路径
点击提交,网页就会跳转到百度界面。 有人试图这样处理跳转路径 param:param = param.replaceFirst("http://", ""); 将第一个 http:// 替换为空字符串,认为这样可以解决问题,但是攻击者往往也很聪明,他会将 URL 改为 : http://http://, 即使替换了第一个,第二天 http:// 就会生效。那么如果对 param 这么处理呢:param = param.replaceAll("http://", ""); 将所有的 http:// 都替换,那么攻击者可以将 URL 设计为 hthttp://tp://,将中间的 http:// 替换为空后,ht 和 tp:// 组合又变为 http://,攻击又一次生效 , 因此,我们需要一个更加全面的考虑。 解决方法 避免由用户决定跳转的页面,如果必须这么做,路径中只允许出现 /以及 数字或者 英文字符可以一定程度的避免这个问题。 问题代码 --- 本站点请求漏洞 本站点请求伪造(on-site request forgery,OSRF)是一种利用保存型 XSS 漏洞的常见攻击有效载荷。是攻击者设计攻击代码,保存到被攻击网页上,当普通用户或者管理员查看页面时,攻击代码就会执行,此攻击代码的目的是伪装成查看网页的用户向服务器发出请求。 这是一个发布图像的论坛例子,用户可以输入图像 URL,论坛负责读取此 URL 进行显示。 img.jsp 与前文的 saveXSS.jsp 代码相同,只是这次显示不再是字符串,而是需要将 <div><%=str%><div/> 改为 <div><img src=<%=str%> width=50 height=50/><div/>,目的是显示用户上传的图像。
清单 7. admin.jsp 主要代码
<% String username = (String)request.getParameter("username"); System.out.println("delete " + username); %> <%=username%> |
admin.jsp 是管理员用于删除用户的请求处理程序,admin.jsp 实际上应该会判断是否是管理员账户,如果是才允许执行删除用户的操作。本文例子假设请求的确为管理员发出。 问题分析 这个程序明显存在着保存型 XSS 漏洞,并且上传的内容被作为图像 URL,img 标签是本站点请求漏洞的敲门器,因为 img 始终会执行 src 属性的 URL 请求,而不管 src 指向的是否是真正的图像。这个程序并没有对 src 是否是图片地址进行验证,因此可以伪造请求。 攻击此程序 将上传的图像 URL 设计为:admin.jsp? username=hello,提交上去后,从攻击者的角度看,只是图片没有显示,因为攻击者并不是管理员,所以实际上无法删除 hello 这个用户。但是当管理员打开这个页面时,img 标签就会执行 admin.jsp? username=hello 的请求,请求删除 hello 用户,由于的确是管理员发出的请求,服务器执行删除操作,删除了 hello 用户,攻击者的目的也就达到了。
图 7. 输入攻击 URL
图 8. 攻击者提交 URL
攻击者点击提交,自身并没有什么影响,只是图片没有显示。然而,当管理员登陆后,admin.jsp 中删除 user 的操作就会执行,例子中是打印删除消息到控制台。
图 9.admin.jsp 控制台输出
解决方法 与保存型 XSS 漏洞一节里的解决方法一样,不仅仅需要限制脚本,还需要判断 img 标签内的 src 属性是否安全,是否包含不是图像的 url。 问题代码 --- 跨站点请求漏洞 跨站点请求漏洞,是一个比较隐蔽的漏洞,发出请求的攻击代码,并不存在于被攻击的网站上,而是利用浏览器的跨站点请求特性(IE6 允许,而 FireFox 和 Chrome 禁止了)进行的。所谓的跨站点,就是同一种浏览器同时打开不同网站的网页 A 和 B,如果这个时候 B 向 A 网站发出某个请求,A 网站就会认为是 A 网页发出的请求,并且接受这个请求。 例子程序是通过跨站点请求漏洞,对登录的用户进行攻击。
清单 8. Attacker.jsp 主要代码
<script type="text/javascript"> setInterval(attack,3000); function attack() { // 不断向 UserLogin.java 发出请求 $.post("http://localhost:8080/KuaZhanDian/UserLogin"); } </script> </head> <body> 伪造的很有吸引力的网站 </body> |
清单 9. UserLogin.java 主要代码
String parameter = request.getParameter("username"); if (parameter != null && !parameter.equals("")) { (1) request.getSession().setAttribute("username", parameter); } else { (2) Object attribute = request.getSession().getAttribute("username"); if (attribute != null) { System.out.println(attribute + "被侵入咯"); } } |
还有一个 index.jsp, 是向 UserLogin.java 提出登录请求的,注意:Attacker.jsp 是另外一个网站的网页,用于吸引被攻击用户,这个网页循环的向 UserLogin 提出请求,为了方便,使用了 JQuery 进行 ajax 开发。UserLogin.java 中,进入(1)位置,代表正常的用户登录,进入(2)的位置,代表用户登录后处理用户的请求。 问题分析绝大多数网站,都没有考虑跨站点的漏洞,因为他们的发生是有一定概率的,首先,攻击者要确认被攻击者使用的是允许跨站点请求的浏览器。其次,被攻击者要同时打开攻击者设计的网站并且登录上面的 UserLogin 才可以。如果两个条件都满足,就可以进行攻击了。攻击此程序吸引被攻击者打开设计的具有诱惑力的网站 Attacker.jsp,那么请求就开始不停地发出,由于服务器认为不是合法用户发出的请求,不予处理。于此同时,被攻击者登录了正常的应用程序 UserLogin,UserLogin 中记录了被攻击者登录的 session 信息,当 Attacker.jsp 再次发请求(注意,Attacker.jsp 是循环发送请求的)给 UserLogin 时,由于被攻击者已经登录,UserLogin 会认为是被攻击者发出的请求,属于正常请求,就处理了这个请求。攻击目的就达到了。实际上攻击成功需要一定步骤,下面图片按照攻击步骤排列。
图 10. 用户登录
用户登录后,不关闭页面,同时又打开攻击者设计的网页
图 11. 用户受到钓鱼攻击
此时攻击者的页面不断向服务器提出请求,用户并不知道,服务器认为是 helloworld 提出的正常请求,执行该请求。
图 12. 控制台输出被攻击信息
解决方法服务器可以给客户端发送唯一的 ID,客户端发送请求时,需要连同这个 ID 一起请求,服务器可以判断这个 ID 是否正确,正确的话才可以执行请求。问题代码 ---SQL 注入漏洞SQL 注入,是攻击者精心设计提交的数据,当服务器使用此数据合成 SQL 语句时,SQL 语句失去了开发者的初衷,被改变了语义。执行了具有破坏力的 SQL 语句。该例子是用户登录的例子,也是 SQL 注入漏洞最容易出现的地方,攻击者精心设计了用户名和密码,使得攻击者可以使用错误的用户名和密码登录应用程序。
|