- 论坛徽章:
- 0
|
GET请求和Cookie中的敏感数据\r\n \r\n 就象CGI协议所定义的,把请求数据从客户端传输到服务器端最简单的方法是GET请求方法。使用GET请求方法时,输入数据附加到请求URL之后,格式如下:\r\n- URL[?name=value[&name=value[&...]]]
复制代码 \r\n\r\n 显然,对于传输敏感数据来说,这种编码方式是不合适的,因为通常情况下,整个URL和请求字符串都以明文方式通过通信通道。所有路由设备都可以和服务器一样记录这些信息。如果要在客户请求中传输敏感数据,我们应该使用POST方法,再加上一种合适的加密机制(例如,通过SSL连接)。从JSP引擎的角度来看,在很大程度上,使用哪种传输方法无关紧要,因为两者的处理方式一样。 \r\n\r\n 在WWW的发展过程中,Netscape引入了Cookie的概念。Cookie是服务器保存到客户端的少量信息,服务器提取这些信息以维持会话状态或跟踪客户端浏览器的活动。JSP提供了一个response隐含对象的addCookie()方法,用来在客户端设置Cookie;提供了一个request()对象的getCookie()方法,用来提取Cookie的内容。 \r\n\r\n Cookie是javax.servlet.http.Cookie类的实例。由于两个原因,如果把敏感数据保存到Cookie,安全受到了威胁:第一,Cookie的全部内容对客户端来说都是可见的;第二,虽然浏览器一般不提供伪造Cookie的能力,但没有任何东西能够阻止用户用完全伪造的Cookie应答服务器。一般而言,任何客户端浏览器提交的信息都不可以假定为绝对安全。\r\n\r\n 通过嵌入标记实现的攻击\r\n\r\n CERT Advisory CA-2000-02描述了客户在请求中嵌入恶意HTML标记的问题。这个问题一般被称为“cross site scripting”问题,但它的名字有些用词不当,因为它不仅仅和脚本有关,同时,它和“跨越网站”(cross site)也没有什么特别的关系。不过,这个名字出现时,问题还没有被人们广泛了解。\r\n\r\n 这种攻击通常包含一个由用户提交的病态脚本,或者包含恶意的HTML(或XML)标记,JSP引擎会把这些内容引入到动态生成的页面。这种攻击可能针对其他用户进行,也可能针对服务器,但后者不太常见。\r\n\r\n “cross site scripting”攻击的典型例子可以在论坛服务器上看到,因为这些服务器允许用户在自己提交的文章中嵌入格式化标记。通常,被滥用的标记是那些能够把代码嵌入到页面的标记,比如:\r\n \r\n <SCRIPT>、<OBJECT>、<APPLET>和<EMBED>。\r\n 另外还有一些标记也会带来危险,特别地,可能被用于欺骗浏览者暴露敏感信息。下面是一个包含恶意标记的请求字符串的例子: \r\n http://server/jsp_script.jsp?poster\r\n=evilhacker& message=<SCRIPT>evil_code</SCRIPT>\r\n\r\n 要防止出现这种问题当然要靠输入检查和输出过滤。这类检查必须在服务器端进行,不应依赖于客户端脚本(比如JavaScript),因为没有任何东西能够阻止用户逃避客户端检验过程。下面的代码片断示范了如何在服务器端检查嵌入的标记:\r\n\r\n- <!-- HTML代码结束 -->\r\n<% String message = \r\nrequest.getParameter(\"message\");\r\nmessage = message.replace (’<’,’_’);\r\nmessage = message.replace (’>’,’_’);\r\nmessage = message.replace (’\"’,’_’);\r\nmessage = message.replace (’’’,’_’);\r\nmessage = message.replace (’%’,’_’);\r\nmessage = message.replace (’;’,’_’);\r\nmessage = message.replace (’(’,’_’);\r\nmessage = message.replace (’)’,’_’);\r\nmessage = message.replace (’&’,’_’);\r\nmessage = message.replace (’+’,’_’);\r\n%>\r\n<p>\r\n你提交的消息是: \r\n<hr/><tt><%= message %>\r\n</tt><hr/></p>\r\n<!-- 下面加上其他HTML代码 -->
复制代码 \r\n\r\n 由于要列举出所有不合法的字符比较困难,所以更安全的方法是进行正向过滤,即除了那些确实允许出现的字符之外(例如[A-Za-z0-9]),丢弃(或者转换)所有其他字符。 \r\n\r\n 关于JavaBean的说明\r\n \r\n JSP按照JavaBean规范描述的一系列约定,在JSP页面中快速、方便地访问可重用的组件(Java对象)。每个JavaBean组件封装了一些可以不依赖于调用环境而独立使用的数据和功能。Bean包含数据成员(属性),并通过Get和Set方法实现访问这些属性的标准API。\r\n\r\n 为快速初始化指定Bean的所有属性,JSP提供了一种快捷方式,即在查询字符串中提供name=value对,并让它匹配目标属性的名字。考虑下面这个使用Bean的例子(以XML格式显示): \r\n- \r\n<jsp:useBean id=\"myBasket\" \r\nclass=\"BasketBean\"> \r\n<jsp:setProperty name=\"myBasket\" \r\nproperty=\"*\"/> <jsp:useBean> \r\n<html> \r\n<head><title>你的购物篮</title></head> \r\n<body> <p> 你已经把商品:\r\n<jsp::getProperty name=\"myBasket\"\r\nproperty=\"newItem\"/> 加入到购物篮\r\n<br/> 金额是$ <jsp::getProperty \r\nname=\"myBasket\" property=\"balance\"/> \r\n准备 <a href=\"checkout.jsp\">付款</a> \r\n
复制代码 \r\n 注意在setProperty方法调用中使用的通配符号“*”。这个符号指示JSP设置查询字符串中指定的所有属性的值。按照本意,这个脚本的调用方式如下: \r\n http://server/addToBasket.jsp?newItem=ITEM0105342\r\n\r\n 正常情况下,HTML表单构造的查询字符串就是这种形式。但问题在于,没有任何东西能够防止用户设置balance属性: \r\n http://server/addToBasket.jsp?newItem=ITEM0105342&balance=0\r\n\r\n 处理页面的标记时,JSP容器会把这个参数映射到Bean中具有同样名字的balance属性,并尝试把该属性设置为0。 \r\n\r\n 为避免出现这种问题,JSP开发者必须在Bean的Set和Get方法中实现某种安全措施(Bean必须对属性进行强制的访问控制),同时,在使用的通配符时也应该小心谨慎。\r\n\r\n 实现上的漏洞与源代码安全\r\n\r\n 无论是哪一种JSP实现,在一定的阶段,它们的某些版本都会出现给系统带来危险的安全隐患,即使JSP开发者遵从了安全编程惯例也无济于事。例如,在Allaire的JRun的一个版本中,如果请求URL包含字符串“.jsp%00”作为JSP脚本扩展名的一部分,服务器不会忽略null字节,它会把页面视为一个静态的非JSP页面之类的东西。\r\n\r\n 这样,服务器会请求操作系统打开该页面,而这时null字节却被忽略,结果提供给用户的是JSP页面的源代码而不是页面的执行结果。\r\n类似地,Tomcat的一个版本也有一个安全隐患。只要请求类如下面的格式,它会让攻击者看到JSP页面的源代码:\r\n\r\nhttp://server/page.js%2570\r\n \r\n 这里的骗局在于,%25是URL编码的“%”,而70是“p”的十六进制值。Web服务器不会调用JSP处理器(因为URL没有以“.jsp”结尾),但静态文件处理器会设法把URL映射到正确的文件名字(再一次解码URL)。 \r\n \r\n 另外,许多Web服务器和JSP实现都带有示范脚本,这些示范脚本常常包含安全隐患。在把服务器部署到一个不无恶意的环境(即Internet)之前,禁止对所有这些脚本的访问有利于安全。 \r\n \r\n 简而言之,JSP开发者应该清楚:在自己正在开发的平台上,当前有哪些安全隐患。订阅BUGTRAQ和所有供应商提供的邮件列表是跟踪这类信息的好方法。 \r\n\r\n 结束语\r\n\r\n JSP和任何其他强大的技术一样。如果要保证被部署系统的安全和可靠,应用JSP时必须小心谨慎。在这篇文章中,我们简要地讨论了JSP脚本中常常出现的代码和配置级安全问题,提出了降低由此带来的安全风险的建议。 |
|