当前位置:首页 >> 网络编程

JSP安全性初探

综述:有几种办法可以暴露JSP代码,不过经过大量测试,这和WEB SERVER的配置有绝对的关系,就拿IBM Websphere Commerce Suite而言,还有别的方法看到JSP源代码,但相信是IBM HTTP SERVER的配置造成的。

  如果想发现JSP暴露源代码的BUG的话,首先需要了解JSP的工作原理。

  JSP和其它的PHP、ASP工作机制不一样,虽然它也是一种web编程语言。首次调用JSP文件其实是执行一个编译为Servlet的过程。注意我们就要在这上边做文章,明白吗?我们要干的事情是,让JSP在编译前被浏览器当作一个文本或其它文件发送给客户端,或在JSP装载的时候不去执行编译好的Servlet而直接读JSP的内容并发送给客户端。

  明白了道理及所要达到的目的就好下手了,仔细观察调用及返回过程可以发现:JSP被编译为了Servlet保存在指定的目录下,如:http://www.x.com/lovehacker/index.jsp很可能存放在X:\IBM\WAServer\temp\default_host\default_app\pagecompile\_lovehacker_index_xjsp.class,这是已经编译过的index.jsp。_lovehacker_index_xjsp.class显然是我们不需要的文件,而且我们得到它的可能性也不大,我们要干的是不去执行_lovehacker_index_xjsp.class而是直接读index.jsp的内容。

  据分析最初的xxx.JSP暴露源代码也是因为前边的这种想法造成的,本来目录中存放了一个_xxx_xjsp.class,但访问xxx.JSP本来是个合法的请求,而又找不到对应的Servlet所以就把xxx.JSP当做一个文本或其它文件发送给了用户。

  也许这是因为IBM HTTP SERVER配置不当造成的,但相信如果能成功的话,会有一种成就感,很爽的哦!

  顺便说一下暴露文件存放真实路径可能会带来的危害:

  1.先会让入侵者了解磁盘配置情况
  2.明的入侵者甚至可以分析出管理员的水平高低
  3.为入侵者修改你的首页提供了方便(起码不用在找你的WEB目录在那个磁盘了)
  4.可能被利用一些其它的CGI的漏洞查找到Web目录下的文件如XX.ASP、XX.JSP、XX.PHP等

  JSP安全问题主要有哪几方面?

  本节重点在于对jsp安全问题进行分类阐述和提出解决的建议,所以每种类型的安全问题只采用了一个例子,对于其它各种漏洞的具体细节如涉及到何种软件版本何种操作系统等就不一一进行阐述了,有兴趣的读者可以到jsp爱好者(http://jspbbs.yeah.net)或者国外的安全站点(http://www.securityfocus.com)进行查看和参考。

  根据目前已经发现的jsp安全问题,不妨将它们分为以下几类,源代码暴露类、远程程序执行类和其他类别, 下面来看看具体的东西吧。

  一、源代码暴露类

  源代码暴露类别主要指的是程序源代码会以明文的方式返回给访问者。
  我们知道不管是jsp还是asp、php等动态程序都是在服务器端执行的,执行后只会返回给访问者标准的html 等代码。这是理论上的东西,实际运行起来由于服务器内部机制的问题就有可能引起源代码暴露的漏洞,简单的例子只要在程序文件名后加几个简单的字符就可能获得程序代码,如常见微软asp 的global.asa+.htr、XXXX.asp%81等等漏洞。

  1.添加特殊后缀引起jsp源代码暴露

  在jsp中也存在着和asp这些漏洞类似的问题,如IBM Websphere Application Server 3.0.21、BEA Systems Weblogic 4.5.1、Tomcat3.1等jsp文件后缀大写漏洞;jsp 文件后加特殊字符如Resin1.2的%82、../漏洞;ServletExec的%2E、+漏洞等等。

  例子:举个老一点的JSP大写例子,Tomcat3.1下在浏览器中本来是http://localhost:8080/inde.jsp,可以正常解释执行,但是如果将inde.jsp改为inde.JSP或者inde.Jsp等等试试看,你会发现浏览器会提示你下载这个文件,下载后源代码可以看个一干二净。

  原因:jsp是大小写敏感的,Tomcat只会将小写的jsp后缀的文件当作是正常的jsp文件来执行,如果大写了就会引起Tomcat将index.JSP当作是一个可以下载的文件让客户下载。老版本的WebLogic、WebShpere等都存在这个问题,现在这些公司或者发布了新版本或者发布了补丁解决了这问题。

  解决办法:一是在服务器软件的网站上下载补丁;因为作者以前用过asp 一段时间,接触了很多IIS的漏洞,它的有效解决方法是去掉不必要的映射如htr、htx等,在jsp 中我们同样可以参考IIS的解决方法,不同的是不是去掉而是添加映射,方法为在服务器设置中添加一些映射如.JSP 、.Jsp、.jsp%2E等,将他们映射到一个自己写的servlet,这个Servlet的唯一功能就是将请求导向一个自定义的类似404 not found的出错页面,不同的服务器设置的地方也不同,请参考相应的文档。第二种解决方法可以在没有补丁的时候采用。

  2.插入特殊字符串引起jsp源代码暴露

  还有一种是插入特殊字符串引起的漏洞,BEA WebLogic Enterprise 5.1文件路径开头为 "/file/" 的漏洞、IBM WebSphere 3.0.2的"/servlet/file/"文件开头漏洞等等。

  例子:如IBM WebSphere 3.0.2中,如果一个请求文件的 URL为"login.jsp":http://site.running.websphere/login.jsp,那么访问http://site.running.websphere/servlet/file/login.jsp将看到这个文件的源代码。

  原因:因为IBM WebSphere 3.0.2是调用不同的 servlets 对不同的页面进行处理,如果一个请求的文件是未进行注册管理的,WebSphere 会使用一个默认的 servlet 调用。如果文件路径以"/servlet/file/"作开头这个默认的 servlet 会被调用这个请求的文件会未被分析或编译就显示出来。

  解决方法:在服务器软件的网站下载最新的补丁。

  3.路径权限引起的文件jsp源代码暴露

  我们知道,大部分的jsp应用程序在当前目录下都会有一个WEB-INF目录,这个目录通常存放的是JavaBeans编译后的class 文件,如果不给这个目录设置正常的权限,所有的class就会曝光。

  例子:如果采用的是Apache1.3.12加上第三方jsp软件形式的WEB服务器,因为Apache1.3.12默认的设置是可以读取目录的,如果程序在http://site.running.websphere/login.jsp,只要修改一下http://site.running.websphere/WEB-INF/所有这个目录下以及这个目录下的子目录中的class文件可以看个一干二净的,还可以下载到本机上。

  也许有人会说class是经过编译的,就算被人下载也没有什么关系,但是现在class 反编译为Java代码的软件也很多,有人曾经采用JAD软件对下载的class文件反编译了一下,居然和原始的Java文件几乎一模一样,变量名都没有变,更惊奇的是还可以重新编译为class文件正常使用。

  安全问题更大的就是,网页制作者开始把数据库的用户名密码都写在了Java代码中,现在一反编译谁都能看到数据库的重要信息。通过数据库的远程连接功能,可以轻松的进入到你的数据库中,所有信息全部在他手中。附带说一句,如果用户能获得SQL Server的用户名口令,进入数据库中可以执行任意的dos命令如查看c:\文件、建立和删除目录等,那样整个Windows系统都不安全了。

  解决方法:IIS以前一个有效地解决asp漏洞的方法,就是将asp程序单独放置一个目录,目录设置上用户权限只能执行不能读取。在jsp环境下同样可以通过设置服务器的环境来解决这个问题,简单的说,就是将一些比较重要的目录如WEB-INF、classes等设置上访问的权限,不允许读而取只允许执行。以apache 下解决为例,可以在httpd.conf文件中添加一目录WEB-INF并设置Deny from all等属性。

  另一种比较笨的解决方法就是在每个重要目录下添加一个默认起始页面如index.htm等,这样读取目录就会返回给访问者这个文件而不是其它了。建议采用的一种方法。

  更为重要的是密码的保存问题。在jsp中可以写一个property文件,放置在WINNT系统目录下,然后用Bean来读取数据库信息,这样通过源代码知道了数据库信息存在WINNT中的.property文件里面,但也很难访问它,这样就算源代码被人知道起码数据库是安全的。

  4.文件不存在引起的绝对路径暴露问题

这个问题相信大家都比较熟悉了,因为微软IIS 中也有比较多的类似问题。如微软IIS5.0中的*.idc暴露绝对路径漏洞。同样的这些问题现在也转到了jsp环境中,这个漏洞暴露了web程序的绝对硬盘地址,和其他漏洞结合就具有比较大的危害了

  例子:在特定的服务器软件下,访问一个不存在的jsp文件如 http://localhost:8080/fdasfas.jsp,就会返回Java.servlet.ServletEception: Java.io.FileNotFoundEception: c:\web\app\fadssad.jsp (???????????)这样的错误,这样就可以知道网站在c:\web\app目录下,也许一般人不太在意,但是对于一个黑客来说就是很有帮助了。

  原因:负责jsp 执行的相关Servlet中处理异常的时候没有过滤掉这种情况。

  解决方法:一是下载最新的补丁;如果当时的web 服务器软件没有这个补丁,可以找到服务器软件的jsp 执行映射Servlet文件(当然是class 后缀的),将它用JAD软件反编译,在反编译后的源代码中找到处理Exception的方法,然后将方法中的处理部分全部注释掉,并将请求导向到一个自定义的出错页面中,这样问题就解决了。

  二、远程程序执行类

  这类漏洞的特点就是可以通过url 地址在浏览器中执行任意服务器上的命令和程序,从而引起安全问题。如Allaire JRUN 2.3 远程执行任意命令漏洞、iPlanet Web Server 4.x存在一个缓冲区溢出漏洞等等。
例子:Allaire 的 JRUN 服务器 2.3上输入下面的url地址http://jrun:8000/servlet/jsp/../../path/sample.txt,可以访问到WEB目录以外的文件,如果是exe文件,还有可能会引起执行。

  原因:如果URL请求的目标文件使用了前缀"/servlet/",则JSP 解释执行功能被激活。这时在用户请求的目标文件路径中使用"../",就有可能访问到 WEB 服务器上根目录以外的文件。目标主机上利用该漏洞请求用户输入产生的一个文件,将严重威胁到目标主机系统的安全。

  解决方法:安装最新的补丁。

  三、其他类别

  这些类别的范围就有点大了,可以包括数据库如SQL Server、Oracle 、DB2等的漏洞,也可以包括操作系统如WindowsNT/2000、Linu等的漏洞。这些东西的漏洞可以说都是致命的,如利用Linux的某些漏洞可以轻易获得管理员权限来远程控制服务器,获得系统的完全控制权限,这样要获得jsp源代码或者摧毁服务器比踩死一只蚂蚁还要轻松的多。

  四、全文总结

  通过上面内容可以看出jsp同asp一样还是存在着很多安全上的问题的,客观的说,服务器软件的开发商在内部测试中不可能将系统中的所有bug 找出来,即使发布了软件后,被发现的漏洞也只会是其中的很小一部分,将来还会不断的有新的安全问题出现,所以我们必须时刻提高警惕,并注意自己网站的安全。

  一个好的建议就是多看安全文章,这些安全文章一般都会有详细的信息如软件的版本号、漏洞原因等等,最重要的是还附带了解决办法或者是补丁的下载链接,推荐的安全站点是国内的安全站点www.cnns.net或者国外的http://www.securityfocus.com站点;另外一个好的建议就是多装补丁程序,访问自己所使用的软件公司主页,从那上面获得最新的补丁程序,做得比较好的就是微软的站点,安全公告和补丁都特别及时。

  最后想用一句话作为全文的结尾:一个优秀的黑客不一定是个好的jsp 程序员,一个优秀的jsp程序员一定要是个好的准黑客。

  哪些方式可实现Java Servlet及JSP的应用安全?

  一个web 应用程序可拥有多种资源,经常有许多敏感的信息在没有保护措施的情况下在开放性网络上传输。在这种环境下,实际上许多web 应用程序有一定程度的安全性要求。大多数的servlet 容器有明确的机制和结构来达到这种安全要求。虽然保证和执行的细节可能有些不同,但是,都具有下面的特点:

  1.Authentication:通讯实体相互验证对方的行为是以一个明确的身份在进行的一种机制。
  2.Access control for resources:对某组用户来说,对数据库的某些操作是受到限制的,或对有些程序强调可用性,完整性或保密性的一种机制。
  3.Data Integrity:数据在传递过程中保证不被第三方修改的一种机制。
  4.Confidentiality or Data Privacy:保证数据只被那些授权使用的用户使用,能被安全传递的一种机制。

  Java Servlet,JSP中安全性通过如下几种方式实现:

  一、 Declarative Security

  Declarative security指的是表达一个应用的安全结构,包括角色,存取控制,和在一个应用的外部表单所要求的验证。在web application中发布描述器是实施declarative security的一种主要的工具。

  发布者把application所要求的逻辑完整性映射为在特定运行环境下的安全策略。在运行时,servlet container使用这些策略来强迫验证。

  二 、Programmatic Security

  当declarative security不能够完全表达一个application的安全模型时,就可以使用programmatic Security。Programmatic Security包括HttpServletRequest接口的下列方法:
  getRemoteUser
  isUserInRole
  getUserPrincipal

  getRemoteUser方法返回经过客户端验证的用户名。IsUserInRole向container的安全机制询问一个特定的用户是否在一个给定的安全角色中。GetUserPrinciple方法返回一个Java.security.Pricipal对象。这些APIs根据远程用户的逻辑角色让servlet去完成一些逻辑判断。它也可以让servlet去决定当前用户的主要名字。如果getRemoteUser返回null值(这意味着没有用户被验证),那么isUserInRole就总会返回false,getUserPrinciple总会返回null。

  三 、Roles

  一个Roles就是由Application Developer和Assembler所定义的一个抽象的逻辑用户组。当一个application被发布的时候,Deployer就把这些角色映射到在运行环境中的安全认证,例如组或规则。

  一个servlet container能够为规则执行一些说明或编程安全,这些规则是与调用这些principal的安全属性所输入的要求相联系的。例如:

  1.当deployer把一个安全角色映射为操作环境下的一个用户组,调用principle所属的用户组就从安全属性中获得。如果principle的用户组与在操作环境下的用户组相匹配,那么principle 就是一个安全角色。
  2.当deployeer把一个安全角色映射为一个在安全方针域中的principle名时,调用principle的确principle名就被从安全属性中提取出来。如果两者相同的话,调用的principle就是安全的。

  四、Authentication

  一个web 客端能够使用下面的一种机制来对web 服务器验证一个用户。

  HTTP Digest Authentication
  HTTPS Client Authentication
  HTTP Basic Authentication
  HTTP Based Authentication

  五、HTTP Basic Authentication

  HTTP Basic Authentication是一个定义在HTTP/1.1规范中的验证机制。这种机制是以用户名和密码为基础的。一个web server要求一个web client去验证一个用户。作为request的一部分,web server 传递被称之为realm的字符串,用户就是在它里面被验证的。注意:Basic Authentication机制的realm字符串不一定反映任何一种安全方针域。Web client得到这些用户名和密码,然后把它传递给web server。Web server然后在一个特定的领域验证这些用户。

  由于密码是使用一种64位的编码来传递,而且目的server没有验证,所以Basic Authentication不是一种安全的验证协议。然而一些附加的保护像使用一种安全传输机制(HTTPS)或在网络层使用安全措施能够解决一些问题。

  六、HTTP Digest Authentication

  与HTTP Digest Authentication一样,HTTP Digest Authentication根据用户名和密码验证一个用户。然而密码的传输是通过一种加密的形式进行的,这就比Basic Authentication所使用的64位编码形式传递要安全的多。这种方法没有像HTTPS Client Authentication的个人密钥方案安全。由于Digest Authentication当前不被广泛使用,servlet containers不要求支持它但是鼓励去支持它。

  七、HTTPS Client Authentication

  使用HTTPS(HTTP over SSL)的终端用户验证是一种严格非验证机制。这种机制要求用户去处理公共密钥证明(Public Key Certification PKC)。当前,PKCs在e-commerce应用中是有用的。不适应J2EE的servlet containers不要求支持HTTPS协议。

  八、Server Tracking of Authentication Information

  就像映射在角色中的安全标识一样,运行环境是环境的说明而不是应用的说明。

  1.在web application的发布环境创建一个登录机制和策略。
  2.对发布在同一个container的application能够使用同样的验证信息来代表这些application的principal。
  3.仅仅当通过安全策略域时要求用户重新验证。

  因此,一个servlet container要求在container层来跟踪这些验证信息,而不是在application层。允许一个经验证的用户拒绝一个使用其它资源的application,这些是通过受同样安全性标识限制的container管理的。