仅对某些类允许 System.exit

Posted

技术标签:

【中文标题】仅对某些类允许 System.exit【英文标题】:Allow System.exit only for certain classes 【发布时间】:2014-07-07 15:39:33 【问题描述】:

我们有一个 Java 1.7 应用程序,它支持插件,客户可以用 Java 编程。但是,我们希望限制插件调用 System.exit。我们可以通过 SecurityManager 来做到这一点。然而,在核心应用程序中,很少有我们想要调用 System.exit 的情况。有没有办法从 SecurityManager 中排除类或包?

【问题讨论】:

当然,根据可配置的标准授予权限是SecurityManager 的主要目的。也许你想阅读some documentation... 【参考方案1】:

与 Batty 的回答类似,但您可以再次禁用设置安全管理器并覆盖 checkExit() 方法。我要做的是允许调用 System.exit() 但这应该会触发插件停止/卸载而不是退出整个 JVM。

您可以使用 Thread.currentThread().getStackTrace() 来找出调用 System.exit() 的代码;

【讨论】:

还有protected Class<?>[] SecurityManager.getClassContext(),可能比较好用。【参考方案2】:

我想你正在寻找这个:

private static class ExitTrappedException extends SecurityException 
 
 
private static void forbidSystemExitCall()
 
    final SecurityManager securityManager = new SecurityManager()  
         public void checkPermission( Permission permission ) 
         
              if( "exitVM".equals( permission.getName() ) ) 
              
                    throw new ExitTrappedException() ; 
            
        
     ; 
    System.setSecurityManager( securityManager ) ; 
 

private static void enableSystemExitCall() 
  
       System.setSecurityManager( null ) ; 

这是在调用插件的类中。

把你的插件调用放在forbidSystemExitCallenableSystemExitCall之间。

【讨论】:

这并没有真正的帮助,因为恶意插件可能仍然会在调用 System.exit() 之前禁用或替换安全管理器。 @jarnbjo 我们将进一步修改我们的自定义 SecurityManager 以检查“setSecurityManager”权限,根据docs.oracle.com/javase/6/docs/api/java/lang/…进行检查 @Benjamin:当然你可以让安全管理器否认它被新的管理器替换或禁用,但这种方法仍然行不通。 Peter 的建议(使用堆栈跟踪来检查调用方法的位置)可能要好得多。 @jarnbjo 我同意堆栈跟踪检查。除了在我们的代码中将其设置为 null 可能存在困难之外,您是否发现检查“setSecurityManager”权限不起作用的任何其他原因? 从代码中将其设置为 null 可能不会有问题,这根本不可能。如果您允许禁用或以其他方式修改安全管理器而不检查谁在进行修改,则无法确保修改不是来自恶意插件。

以上是关于仅对某些类允许 System.exit的主要内容,如果未能解决你的问题,请参考以下文章

如何仅对给定的类类型应用现有的 sonarQube 规则

如何仅对某些模式启用空白模式

货到付款付款方式应仅对 magento 中的某些邮政编码/密码可见

仅对定义文件允许隐式任何

Anylogic:如何仅对同一资源池的某些工作人员执行停机

minifyEnabled仅对某些软件包或我的文件而言