0

I have a case where I have two modules that contain the same package and class names...

module-one

io.foo.Bar

module-two

io.foo.Bar

In either case, if I call Bar.class.getQualifiedName() I'll receive identical strings.

Is there a way to absolutely differentiate them from one another?

Matthew Layton
  • 39,871
  • 52
  • 185
  • 313
  • Why did they have the same package-name in the first place? – Glains Nov 29 '19 at 13:24
  • @Glains because someone is trying to be malicious and replace one class with one that on the surface appears identical, but actually isn't. – Matthew Layton Nov 29 '19 at 13:25
  • 3
    @series0ne: if a malicious actor can put arbitrary classes on your classpath, then you've already lost. There's no reasonable defense against someone who can arbitrarily change what code you're running. – Joachim Sauer Nov 29 '19 at 13:29
  • I don't think there is a way to do that. The classloader will load the class it finds first. – second Nov 29 '19 at 13:31
  • One way to deal with this is to actually sign your application files and verify the checksum once delivered. This way, you guarantee that no malicious code has been injected in the meantime. – Glains Nov 29 '19 at 13:32
  • @JoachimSauer In my case, I might not have lost. This problem occurs with malicious actors in distributed systems, specifically in this case, Corda. I want to be able to enforce that _their_ `io.foo.Bar` is the same as _my_ `io.foo.Bar`. Consider that I've been honest and kept my JAR file in tact, but they've been malicious and replaced it with a seemingly identical class, but it behaves differently – Matthew Layton Nov 29 '19 at 13:35
  • Are you talking about different installations in your system? In that case you would not even have access to the other `Bar` class. (From your question I get the impression you want to compare these things at runtime.) – second Nov 29 '19 at 13:38
  • 1
    @series0ne: if someone can make your code run in a context with malicious code, what stops them from replacing any of *your* code that does the check for *their* malicious code with a trivial implementation like `boolean isRunningInValidContext() { return true; }`? This is the age-old question of "can I allow people to run my code and reliably stop them from modifying them?" to which the short answer is "no, either they can't run it or they can modify it". – Joachim Sauer Nov 29 '19 at 13:56
  • @JoachimSauer because its a distributed ledger which requires consensus from counter-parties. If they want me to sign their transaction, they have to send it to me, and I can refuse to sign on the basis they're using a malicious version of the class. – Matthew Layton Nov 29 '19 at 14:32
  • 1
    You should not base your security model on the version of the class that one is using, because you cannot control any of your code once it's on other people's machines. If it's a distributed system you should not think about securing the code itself, but the protocol used to exchange data. – gpunto Nov 29 '19 at 21:31

1 Answers1

0

I believe module one and module two available in the classpath in a separate jar with a different name, for example, module-one.jar or module-two.jar. Now you can exact name of the jar by using reflection like below:

    Class clz = Bar.class;
    URL location = clz.getProtectionDomain().getCodeSource().getLocation();
    System.out.println(location);

Above code will give output like:

file:<jar location>/<jarname>.jar

This answer is inspired by this question, for more info please go through the question.

Amit Bera
  • 7,075
  • 1
  • 19
  • 42
  • How can you be sure which `Bar.class` you are referring to if both are on the class path. Afaik the classloader is unable to differentiate between them. – second Nov 29 '19 at 13:45