咨询电话

Java代码的即时编译 置顶

发表于2017-03-09 10:43:55 次查看
了解如何保护您的应用程序免受已知和未知的漏洞。

 

Java使得可以在运行时编译Java代码...  任何  Java代码。

编译的入口点是  ToolProvider 类。从Javadoc:

提供用于定位工具提供程序的方法,例如,编译器的提供程序。这个类补充了ServiceLoader的功能。

这个类在版本1.6 - 从10年前发布以来,是可用的,但似乎已被很大程度上忽略。

代码

这里有一个代码段,允许:

public  class  EvilExecutor {

    private  String  readCodeString  sourcePaththrows  FileNotFoundException {
        InputStream  stream  =  new  FileInputStreamsourcePath);
        String  separator  =  SystemgetProperty“line.separator”);
        BufferedReader  reader  =  new  BufferedReadernew  InputStreamReaderstream));
        返回 阅读器lines()。收集收集连接分离器));
    }}

    private  Path  saveSourceString  sourcethrows  IOException {
        String  tmpProperty  =  SystemgetProperty“java.io.tmpdir”);
        路径 sourcePath  =  路径gettmpProperty“Harmless.java”);
        文件SOURCEPATH的getBytesUTF_8));
        return  sourcePath ;
    }}

    private  Path  compileSourcePath  javaFile){
        JavaCompiler  compiler  =  ToolProvidergetSystemJavaCompiler();
        编译器运行javaFileTOFILE()。getAbsolutePath());
        返回 javaFilegetParent()。resolve“Harmless.class”);
    }}

    private  void  runClassPath  javaClass
            throws  MalformedURLExceptionClassNotFoundExceptionIllegalAccessExceptionInstantiationException {
        URL  classUrl  =  javaClassgetParent()。toFile()。toURI()。toURL();
        URLClassLoader  classLoader  =  URLClassLoadernewInstancenew  URL [] { classUrl });
        <?>  clazz  =  ClassforName“Harmless”trueclassLoader);
        clazznewInstance();
    }}

    public  void  doEvilString  sourcePaththrows  Exception {
        String  source  =  readCodesourcePath);
        Path  javaFile  =  saveSourcesource);
        Path  classFile  =  compileSourcejavaFile);
        runClassclassFile);
    }}

    public  static  void  mainString ... argsthrows  Exception {
        新的 EvilExecutor()。doEvilargs [ 0 ]);
    }}
}}

一些解释是按顺序:

  • readCode():从文件系统上的任意文件读取源代码,并将其作为字符串返回。一个替代实现将从网络获取源。

  • saveSource():从启用读取的目录中的源代码创建一个新文件。文件名是硬编码的,更精细的版本将解析代码参数以创建根据其包含的类名命名的文件。

  • compileSource():从java文件中编译类文件。

  • runClass:加载编译的类并实例化一个新对象。为了独立于任何转换,应该在外部源代码类的构造函数中设置要执行的代码。

问题

从功能的角度来看,与其他不提供此功能的代码相比,即时编译代码提高了Java语言的价值。从安全的角度来看,这是一场噩梦。在生产中能够执行任意代码的想法应该是任何一个IT组织中的任何人的脊椎,包括开发人员,如果不是大部分。

经验丰富的开发人员/操作或常规读者可能记得  Java安全管理器  以及如何激活它:

java -Djava .security.manager -cp target / classes ch.frankel.blog.runtimecompile.EvilExecutor harmless.txt

执行上面的命令行将产生以下结果:

java.lang.SecurityManager@4e25154f
异常线程“主” java.security.AccessControlException:
    访问被拒绝(“java.io.FilePermission”  “harmless.txt”  “read”
  在java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
  在java.security.AccessController.checkPermission(AccessController.java:884)
  在java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
  在java.lang.SecurityManager.checkRead(SecurityManager.java:888)
  在java.io.FileInputStream。<init>(FileInputStream.java:127)
  在java.io.FileInputStream。<init>(FileInputStream.java:93)
  在ch.frankel.blog.runtimecompile.EvilExecutor.readCode(EvilExecutor.java:19)
  在ch.frankel.blog.runtimecompile.EvilExecutor.doEvil(EvilExecutor.java:47)
  在ch.frankel.blog.runtimecompile.EvilExecutor.main(EvilExecutor.java:56)

结论

JVM提供了大量的功能。A用任何工具,他们可以用于好或坏。每个人都应该对正确地保护JVM的责任感到负责,在敏感领域(银行,军事等)中双倍。

\

在线客服
  • 点击这里给我发消息
  • 点击这里给我发消息
  • 微信扫一扫
  • 官方微信