Skip to content

org.springframework.boot.loader.jar.JarURLConnection does not allow usage of SecurityManager without java.security.AllPermission #5411

@Fiouz

Description

@Fiouz

When activating the JVM default security manager with some reasonable policy file (-Djava.security.manager -Djava.security.policy=XXX), a self-contained JAR file created by org.springframework.boot:spring-boot-maven-plugin:1.3.3.RELEASE:repackage cannot load classes:

Exception in thread "main" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:62)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:54)
    ... 1 more
Caused by: java.lang.NoClassDefFoundError: org/springframework/boot/SpringApplication
    at com.example.DemoApplication.main(DemoApplication.java:10)
    ... 6 more
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.SpringApplication
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 7 more

Activating Java security debugging features -Djava.security.debug=access,failure reveals that Spring Boot requires the java.security.AllPermission permission, which defeats the purpose of setting up a security manager:

access: access denied ("java.security.AllPermission" "<all permissions>" "<all actions>")
java.lang.Exception: Stack trace
    at java.lang.Thread.dumpStack(Thread.java:1329)
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:462)
    at java.security.AccessController.checkPermission(AccessController.java:884)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
    at java.net.URLClassLoader$4.run(URLClassLoader.java:709)
    at java.net.URLClassLoader$4.run(URLClassLoader.java:707)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.getPermissions(URLClassLoader.java:707)
    at java.security.SecureClassLoader.getProtectionDomain(SecureClassLoader.java:206)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at org.springframework.boot.loader.LaunchedURLClassLoader.doLoadClass(LaunchedURLClassLoader.java:170)
    at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:142)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
    at java.lang.Thread.run(Thread.java:745)

Policy file used -Djava.security.policy=XXX (obviously, declaring AllPermission should not be an acceptable option):

grant {
  permission java.lang.RuntimePermission "*";
  permission java.io.FilePermission "*", "read,write,delete";
  permission java.net.NetPermission "*";
  permission java.util.PropertyPermission "*", "read,write";
};

The root cause seems to be org.springframework.boot.loader.jar.JarURLConnection that does not override java.net.URLConnection.getPermission(https://docs.oracle.com/javase/7/docs/api/java/net/URLConnection.html#getPermission%28%29):

By default, this method returns java.security.AllPermission. Subclasses should override this method and return the permission that best represents the permission required to make a a connection to the URL

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions