0

Is there a way to configure the JVM to block instances of a class being created?

I'd like to do this to ensure no service running in the JVM is allowed to create instances of a class that has been identified as a security risk in a CVE, lets call that class BadClass.

NOTE: I'm looking for a general solution, so the following is purely additional information. I would normally address this by switching the library out, or upgrading it to a version that doesn't have the exploit, but it's part of a larger library that wont be addressing the issue for some time. So I'm not even using BadClass anywhere, but want to completely block it.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Brad Parks
  • 66,836
  • 64
  • 257
  • 336
  • With a custom security manager I guess, although I have absolutely no reference on how to do that to block loading of classes. It is the built-in mechanism which was used to sandbox applets back when they were relevant. – Gimby Oct 27 '20 at 13:40
  • 1
    Relevant to security manager angle (and potential duplicate): https://stackoverflow.com/questions/991703 – Michael Easter Oct 27 '20 at 14:15

3 Answers3

2

A distinct non-answer: Do not even try!

What if that larger library that has this dependency wants to call that method? What should happen then?

In other words, what is your blocking supposed to do?

  • Throw some Error instance, that leads to a teardown of the JVM?
  • Return null, so that (maybe much later) other code runs into a NPE?

Remember: that class doesn't exist in a void. There is other code invoking it. That code isn't prepared for you coming in, and well, doing what again?!

I think there are no good answers to these questions.

So, if you really want to "manipulate" things:

Try sneaking in a different version of that specific class into your classpath instead. Either an official one, that doesn't have the security issue, or something that complies to the required interface and that does something less harmful. Or, if you dare going down that path, do as the other answer suggests and get into "my own classloader" business.

In any case, your first objective: get clean on your requirements here. What does blocking mean?!

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • thanks for the feedback - I'm open to any type of blocking, so throwing an error or returning null, or not loading the class - all are good by me. To me, `BadClass` should never be used in any service Im running in the JVM, which is literally >30 microservices Of course these are all developed/tested in multiple stages, through a dev/test/staging/performance and then finally prod environment, so Im completely fine with a service dying horribly in all envs but prod. – Brad Parks Oct 27 '20 at 14:08
  • Still, what are you going to do then, when your code calls biglib, and biglib calls BadClass? Stop using biglib?! – GhostCat Oct 27 '20 at 14:48
  • Yeah if that situation arises, then we'd have to unblock it - but then we'll be aware at develop time what's up, and can try and find some other workaround - but I don't think we're using BadClass at all - ie BigLib has lots and lots of classes and I don't think `BadClass` is being used at all. – Brad Parks Oct 27 '20 at 16:47
2

I do not know a JVM parameter, but here's some alternatives that might pout you in a position that solve your requirements:

  1. You can write a CustomClassLoader that gives you fine control on what to do. Normal use cases would be plugin loading etc. In your case this is more security governance on devops level.

  2. If you have a CICD pipeline with integration tests you could also start the JVM with -verbose:class parameter and see which classes are loaded when running your tests. Seem a bit hacky, but maybe suits your use case. Just throwing everything into the game, it's up to you judging about the best fit.

  3. Depending on your build system (Maven?) you could restrict building applications just on your private cached libs. So you should have full control on it and put a library - review layer in between. This would also share responsibility between devs and the repository admins.

supernova
  • 1,762
  • 1
  • 14
  • 31
  • The tricky part here: many larger real world installations (stuff that uses "larger libraries") might come with their own classloaders already. You really want to get into that game? And then, as written in my answer: sure, you can *understand* when that class gets used, but how do you *actually* block its usage ... segfaulting the JVM? – GhostCat Oct 27 '20 at 13:53
  • 1
    I'm not stating it's the best and most generic option. Indeed I just listed 3 options that *could* fit one or the other company scenario. I personally believe this is better then stating a global NOGO. And please don't get me wrong - I got your arguments, which by themselves make sense. But at the end we're both far away from the "real" problem (which I believe comes from a requirement). That I learned that sometimes a slightly different approach might do the trick. – supernova Oct 27 '20 at 14:08
  • yeah it is a requirement coming from a security division in our company - our services can't go to prod unless they address these issues, and this class is being included, in this case, in spring boot, but is a general concept that will keep popping up - something that isn't addressed in a larger library, which we're not even using. – Brad Parks Oct 27 '20 at 14:15
  • Question is if this needs to be pro-active (the maven solution), prohibitive (fail in build) or retro-active (let the app crash or tear it down). If the last option is ol you might simply use the -JVM option `verbose:class` and use a log collection framework (logstash or similar) or a scanner process to search for bad classes. Then you can act on upon the alert. – supernova Oct 27 '20 at 16:07
  • I'd say it's a "let the app crash or tear it down" situation, forcing the class to not be used... I'm discussing with our team and suggesting the option - thanks for the feedback! – Brad Parks Oct 27 '20 at 16:50
  • One more approach might be to build the service into a fat jar, and exclude the troublesome classes, or use [minimizeJar](https://maven.apache.org/plugins/maven-shade-plugin/examples/includes-excludes.html) to remove classes that aren't used, if using Apache Maven Shade plugin – Brad Parks Oct 27 '20 at 19:36
  • 1
    and another possible solution is to use maven to remove the bad classes dynamically, and create a new artificate (release version) of the bad library in question, [as discussed in this blog post](akes an existing JAR, unpacks it and removes a class and makes a new artifact.... http://gochev.blogspot.com/2014/07/patching-maven-library-with-your-custom.html) – Brad Parks Oct 28 '20 at 15:32
0

Have you considered using Java Agent?

It can intercept class loading in any classloader, and manipulate it's content before the class is actually loaded. Then, you may either modify the class to remove/fix it's bugs, or return dummy class that would throw error in static initializer.

Boguś
  • 150
  • 3
  • 11