Closed spoofzu closed 4 years ago
I noticed that a different classloader may be used depending on whether springboot is initialized with a SecurityManager or not, regardless of policy settings. That's about as far as I got in the code. I checked to see if I could identify a SecurityManager unit test where this code path is exercised but didn't notice anything.
I don't think there is enough here to believe the root cause has anything in the Spring Framework.
I reviewed the next and other bug submissions to the spring project but didn't notice anything similar. I'm hope this information is helpful.
Do you mean that you searched this repository (Spring Framework) or the Spring Boot repository? The question seems more suited for Spring Boot based on the context.
I'm also wondering did you consider asking on the WebGoa's own issue tracker https://github.com/WebGoat/WebGoat?
It's not a bug in my code since I'm not running any code. It's not a bug in Webgoat since its spring is failing prior to any Webgoat code running. In fact, if I remove the Java security manager from springboots startup Webgoat starts as expected. This is the command that causes the failure,
java -classpath ./webgoat-server-8.0.0.M26.jar:./JVMXRay-0.0.1-SNAPSHOT.jar -Djava.security.manager=java.lang.SecurityManager -Djava.security.policy==/Users/milton/zwebgoat/nulljava.policy org.springframework.boot.loader.JarLauncher --server.port=8080 --server.address=localhost
Removing the security manager and policy like this fixes the problem, "-Djava.security.manager=java.lang.SecurityManager -Djava.security.policy==/Users/milton/zwebgoat/nulljava.policy"
This is a problem in AbstractBeanFactory.java when the Java security manager is present.
Bump. Plz take a look at this when possible, thank you.
Keep in mind, there is NO user code involved in this bug. This problem has been duplicated by using only core Java code. SpringBoot, chooses to use an alternative classloader anytime a SecurityManager is loaded.
Hi @spoofzu
I believe, it's the other way around - by launching your application like this, you've chosen to deviate from the jar launcher which is using a specific class loader for loading resources from the executable jar.
Allowing this use case was considered but declined in the end, see the conversation on the Spring Boot issue tracker. You can however enable the security manager by calling something like System.setSecurityManager(new SecurityManager());
in the main application method.
If you feel that this is a missing use case from webgoat (using a security manager with their app), you can reach out to them for such an improvement. Just note that supporting that from the command line with the system classloader is not going to work because of the issue I've linked to.
I'm closing this issue since it's not related to Spring Framework. Thanks!
HI @bclozel
I'm not a Spring and SpringBoot expert so please bear with me. I'm building an IASP/RASP type tool called, JVMXRay. The tool monitors security access to protected resources by intercepting calls to the SecurityManager API. I extend SecurityManager with a custom implementation called, NullSecurityManager. WebGoat works great with SpringBoot but not JVMXRay. SpringBoot has trouble finding JVMXRay classes. I need my code somewhere in the classpath so I can load it via the security manager command line switch. Looks like your suggesting if I add NullSecurityManager to the WebGoat (or whatever springboot is running) code then the classloader will find my JVMXRay classes. So System.setSecurityManager(new NullSecurityManager() ); inside WebGoat should theoretically work. Of course, this solution is a little restrictive since it limits JVMXRay on SpringBoot to only those that add support to their apps for JVMXRay.
Do you think there is another way I can get JVMXRay to work with SpringBoot and WebGoat? Could I improve the SpringBoot custom classloader or something else perhaps? As a far as I know SpringBoot is a labor of love so I understand this is probably a low priority for you. Feel free to take your time responding. Appreciate your assistance and response.
Regards, Milton
Hi @spoofzu
There are several ways to achieve something like this; it really depends on your deployment model and how developers are supposed to use this library with their application.
If they're meant to integrate it at build time, you could ask them to add that dependency to their build file, and even consider building a specific Spring Boot Starter (with configuration properties and more features).
If your product should be used on an already packed archive, you could use the PropertiesLauncher
instead of the JarLauncher
and add a custom entry for your jar. There are also ways to unpack an existing application and run it with additional dependencies (see this docker + Spring Boot tutorial) - just note that classpath ordering can be lost if you go with a wildcard classpath, as explained in that tutorial.
Finally, if your product is meant to be deployed as an agent (or something close to that), you could take a look at Cloud Native Buildpacks and Paketo. Paketo has buildpacks implementations that do change the classpath or attach an agent to the application, while building the container image. This makes an even better experience if you want this to be included in the CI pipeline automatically.
Thanks!
Ok, thanks @bclozel. I appreciate the advice. I will review these to see if it will help me get jvmxray running with webgoat. --Milton
Affects: \v5.2.0.RELEASE
Running with Spring Boot v2.2.0.RELEASE, Spring v5.2.0.RELEASE
I have been working on getting webgoat to run with springboot with a securitymanager. To minimize likelihood of user coding problems on my part, I'm using java.lang.SecurityManager as the test. I am running with the following policies,
With SecurityManager enabled and the previous policies, no access control checks should fail. Following is the command line I use to execute springboot with webgoat.
java -classpath ./webgoat-server-8.0.0.M26.jar:./JVMXRay-0.0.1-SNAPSHOT.jar -Djava.security.manager=java.lang.SecurityManager -Djava.security.policy==/Users/milton/zwebgoat/nulljava.policy org.springframework.boot.loader.JarLauncher --server.port=8080 --server.address=localhost
The problem is that org.owasp.webgoat.HSQLDBDatabaseConfig is not found and server exists. However, if remove the SecurityManager and policy file from the command line the server starts as expected. The expected behavior with SecurityManager and the AllPermission policies should be the same as no SecurityManager. I reviewed some of the code near,
org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1465
I noticed that a different classloader may be used depending on whether springboot is initialized with a SecurityManager or not, regardless of policy settings. That's about as far as I got in the code. I checked to see if I could identify a SecurityManager unit test where this code path is exercised but didn't notice anything. I reviewed the next and other bug submissions to the spring project but didn't notice anything similar. I'm hope this information is helpful.
-----FULL STACKTRACE FOLLOWS------