快来看这只Tomcat安全猫!!!

做为一个用户量具大的Servlet容器,Tomcat一直以其源码开放,方便易用,社区活跃,文档丰富等特点,受到众多Java Web开发者的喜欢。

在这篇文章中,我们来了解下Tomcat的一些安全机制,为了保证应用服务器的安全,Tomcat都提供些啥。

为了有一个更直观的印象,我们先来做这样一个尝试,在你Tomcat上部署一个包含jsp页面的web应用。这个jsp页面中至少包含下面一段内容:

<%

System.exit(0);

%>

看到上面的语句,我们大概心想:好家伙,这是要退出系统呀。在你向这个jsp页面发起请求时,果然不出所料,你的Tomcat被停掉了

这能说明什么呢,啥也说明不了。毕竟这个exit是自己写在页面中的。那如果是下面这样的场景呢?

1.

服务器上的一个Tomcat,同时跑了不止一个web应用。其中某一个应用中包含上面的jsp页面,这样,当这个应用中触发了这个页面请求的时候,导致整个

Tomcat被停了,而其它的Web应用很无辜的受到了影响。

2.

依然是整个Tomcat上部署了多个Web应用,其中某个应用的代码包含这样的逻辑:

定期对父目录下除自己外的目录执行删除操作。

这个时候,另外的Web应用哥几个又受到了猪一样队友的影响不能正常工作了。

3. 部署的多个应用可以会依赖环境的不同进行不同的操作。而这些对系统的判断,我们一定是通过获取JVM提供的一些属性,比如获取当前操作系统的属性是os.name,版本的则是os.version。如果某个应用在运行过程中把这此属性给改了,那其它应用又受到影响了。

Tomcat内部提供的安全机制,则对上述的场景做了各种限制来保证其不会发生。

既然不会发生,那你还扯这些干嘛呢?你心里一定开始这么想了。

对,Tomcat是提供了这些,但默认并没有开启。不信你试试前面说的在jsp页面中执行System.exit!!!

所以,泡杯茶,继续读一读。


Tomcat实现上述种种形式的限制,都是通过JVM 提供的SecurityManager机制。这种机制配置后,陌生的代码只能执行有限的操作,对于可以执行从remote Code的应用,这种机制更是必不可少。

在JVM中,特定的classLoader,SecurityManager及其它一些要素,组成的Java的sandBox,即传说中的沙箱。你也许在使用杀毒软件时听过这个词,让一个刚下载的不知道干啥的软件在沙箱里运行,确保没问题再使用。

为了使用Tomcat的这种安全机制,我们需要在启动的时候先开启之。

方式:

在启动脚本之后,传递-security参数,以windows系统为例,在启动Tomcat的时候,可以这样操作

  • startup.bat -security

  • catalina.bat -security

上面两种方式任选一个即可。其实质上是给JVM传入了这样一个参数:

-Djava.security.manager。

此时,你再执行上面包含System.exit代码的jsp请求,会看到这个样子的结果


会明显的提示access denied。

这个东西是怎么生效的呢?

打开%Catalina.home%/conf/catalina.policy文件查看下。(Catalina.home代表Tomcat安装目录)


这里面定义了一系列的包permission,Tomcat启动的时候policy文件默认使用这个文件。你可以通过参数-Djava.security.policy=xxx指定。

Tomcat内部又是如何配置和使用的呢?

看这里,Global类里有这样一个常量的定义:

/**

* Has security been turned on?

*/

public static final boolean IS_SECURITY_ENABLED =

(System.getSecurityManager() != null);

如果指定了上面的java.security.manager参数,则JVM的security Manager开启。此时后续的一系列地方都会根据此标识来判断是否要进行安全限制。

例如我们上面提到的场景,为了限制应用内对自身资源的管理,删除等,会设置些目录的访问权限。看下面的代码:

/**

* Configure associated class loader permissions.

*/

private void setPermissions() {

if (!Globals.IS_SECURITY_ENABLED) // 没有启用则直接返回

return;

if (context == null)

return;

// Tell the class loader the root of the context

ServletContext servletContext = context.getServletContext();

// Assigning permissions for the work directory

File workDir =

(File) servletContext.getAttribute(ServletContext.TEMPDIR);

if (workDir != null) {

try {

String workDirPath = workDir.getCanonicalPath();

classLoader.addPermission

(new FilePermission(workDirPath, "read,write")); //为应用工作目录设置读写权限

classLoader.addPermission

(new FilePermission(workDirPath + File.separator + "-",

"read,write,delete"));

} catch (IOException e) {

// Ignore

}

}

for (URL url : context.getResources().getBaseUrls()) {

classLoader.addPermission(url);

}

}

而在大量的Tomcat源码中,你会发现对于securityManager的判断,例如

if (Globals.IS_SECURITY_ENABLED &&

name.equals(Globals.SENDFILE_FILENAME_ATTR)) {

...

System.getSecurityManager().checkRead(canonicalPath);

}

开启securityManager走权限检测的流程,默认走普通流程。以我们熟悉的Filter处理为例,在处理链中,默认直接执行Filter中的doFilter方法,而开启安全机制则会复杂一些,看这些代码:

if( Globals.IS_SECURITY_ENABLED ) {

final ServletRequest req = request;

final ServletResponse res = response;

Principal principal =

((HttpServletRequest) req).getUserPrincipal();

Object[] args = new Object[]{req, res, this};

SecurityUtil.doAsPrivilege

("doFilter", filter, classType, args, principal);

} else {

filter.doFilter(request, response, this);

}

正是由于源码内的这一系列安全限制,才保证Tomcat的安全稳定。马上加上

-security参数试一下吧,骚年。

感觉有用就转发到朋友圈,让更多朋友了解吧。

欢迎关注本公众号,了解更多内容。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值