• Post Reply Bookmark Topic Watch Topic
  • New Topic

Preventing others from calling code from your jar  RSS feed

 
Anayonkar Shivalkar
Bartender
Posts: 1558
5
Eclipse IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I'm not sure if this question belongs to this forum (Security forum does not seem to be specific about Java Security - so posting it here).

I have a doubt as below:
1) I have a jar (say x.jar) which I distribute as part of product.
2) The product user is able to 'customize' few facilities - i.e. to sub-class some of classes from x.jar and write their own code.
3) However, I want the user to discourage the actual invocation of my APIs - i.e. they are free to sub-class my classes, but they should not be able to call(or sub-class) 'specific' part of my code (i.e. x.jar)

The problem I'm having is - since the code is stable (and I want to change it as less as possible) - I'm not following the access-modifier approach like keeping methods as private or default (or creating facades for each publicly exposed method).

Currently, I'm achieving partial security as below:
1) Write my own SecurityManager
2) Override checkSecurityAccess method (e.g. it will allow access only if package name starts with some specific string - basically, this condition can be anything - assuming client's code does not meet this requirement)
3) In each public method, check if its caller method is having access to this method (instead of copy-pasting this code everywhere - I can inject it via AspectJ).

So, my questions are:
1) Is this proper approach, or something better can be done?
2) How to hide security manager logic from client (because if client decompiles my jar, it will know which condition it should meet to access the code )

Thanks.
 
Ulf Dittmer
Rancher
Posts: 42972
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Software licenses generally prohibit decompilation, so if you think that's something you need to worry about you may have to rethink the relationship with your clients you should obfuscate the code so that at least the common decompilers (JODE, jad, JD-GUI) can't decompile it. That may mean using a commercial tool, I think ProGuard might not be sufficient.
 
Jelle Klap
Bartender
Posts: 1952
7
Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There isn't a way to prevent it, and you probably shouldn't waste effort trying to. If the public API documentation is clear it should be enough to encourage the user to use it correctly and not create dependencies on "internal types" or "internal methods". Things like OSGi have made an effort to let a bundle expose only a public API, and indeed if you use such a JAR in an OSGi environment you are limited to just that.
 
Anayonkar Shivalkar
Bartender
Posts: 1558
5
Eclipse IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the replies folks!

@Ulf - 'client' here is just another team (not customer) - so, they are allowed decompile the jar

So - what's the bottom line here (if any)? Should I only rely on obfuscation(and give up idea of SecurityManager implementation)? Sorry - we are not working in OSGi environment
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Anayonkar Shivalkar wrote:The problem I'm having is - since the code is stable (and I want to change it as less as possible) - I'm not following the access-modifier approach like keeping methods as private or default (or creating facades for each publicly exposed method).

So it sounds to me like you want a band-aid to cover for the fact that you didn't write your code properly to begin with; and that's rarely a good way to go. The problem you have now (I suspect) is that you can't alter your existing code without possibly breaking other code that relies on it; however, the same is likely to be true of a "security-based" solution as well: You'll break code that is already doing things you don't want, because you allowed it to.

Personally, I think I'd bite the bullet and release a refactored version that is implemented properly - however, I suspect that Joel Spolsky might not agree with me.

Winston
 
Anayonkar Shivalkar
Bartender
Posts: 1558
5
Eclipse IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Winston - the blog is quite a nice read!

I agree with Joel Spolsky - my code is anyway working - on lot of machines, and for quite long time - so I wouldn't give it much though to write it from scratch

Looks like its high time I get my hands (and code) dirty with SecurityManager then...
 
Hauke Ingmar Schmidt
Rancher
Posts: 436
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:Personally, I think I'd bite the bullet and release a refactored version that is implemented properly - however, I suspect that Joel Spolsky might not agree with me.


I think we have a different situation here. Refactoring to implement specific functionality is something different than rewriting everything from scratch to do it better this time. In this case you would keep the business functions and just add a façade that works as expected in Java.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Anayonkar Shivalkar wrote:I agree with Joel Spolsky - my code is anyway working - on lot of machines, and for quite long time - so I wouldn't give it much though to write it from scratch

Would you have to write it "from scratch" though? It seems to me that you could produce a refactored version that reuses all the code you've already written, but just hides it from your clients - wrappers are wonderful things.

I'm also not sure how a SecurityManager-based solution is likely to break any less code than a refactored one - and I suspect it may introduce a whole new layer of things to go wrong.

But Joel and I don't always see eye to eye; and at the end of the day, it's your decision to make.

Winston
 
Ulf Dittmer
Rancher
Posts: 42972
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
'client' here is just another team (not customer)

So they're part of your company? If so, can't you provide them with documentation that makes it clear how the library is and is not supposed to be used, and expect them to follow that?
 
Anayonkar Shivalkar
Bartender
Posts: 1558
5
Eclipse IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:Would you have to write it "from scratch" though? It seems to me that you could produce a refactored version that reuses all the code you've already written, but just hides it from your clients - wrappers are wonderful things.

Yeah - but as I mentioned, the idea is to make minimal changes to code. Though I genuinely wish if it were possible to use wrapper or refactor the code
Ulf Dittmer wrote:So they're part of your company? If so, can't you provide them with documentation that makes it clear how the library is and is not supposed to be used, and expect them to follow that?

Well - ahem
Firstly, the documentation is not always honored and secondly, the mindset is like
if your jar exposes 5 methods, it means we can use 5 methods; if you want us to use 3 methods, then expose only 3 methods

Btw, if I employ use of SecurityManager, will there be any performance impact? I don't think so - because default SecurityManager is anyway used by JVM - but would like to get expert viewpoint on this.

Thanks.
 
Ulf Dittmer
Rancher
Posts: 42972
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
if I employ use of SecurityManager, will there be any performance impact? I don't think so - because default SecurityManager is anyway used by JVM - but would like to get expert viewpoint on this.

There's certainly an overhead in checking this for each method call, but without knowing how much work the method call does, and how often it's called, it's impossible to say whether the overhead would be measurable, and -if it is measurable- whether it's enough to be cause for concern.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Anayonkar Shivalkar wrote:but as I mentioned, the idea is to make minimal changes to code...

Aaagh! Why do managers (or clients) insist on adding vague, asinine restrictions like this? Thankfully, I've got to the stage where I can tell mine to bog off, because they're not only telling me what to do, but how to do it; and in that case, they can get a darn junior who will do exactly what they're told and not rock any boats.

And they'll probably get precisely the solution they asked for. Whether or not it's the right one is a totally different matter...

I refer you to my signature quote below.

Winston
 
William Brogden
Author and all-around good cowpoke
Rancher
Posts: 13078
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, if you made the class you don't want people to directly use an abstract class, would that satisfy your requirement?

Bill
 
Anayonkar Shivalkar
Bartender
Posts: 1558
5
Eclipse IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
William Brogden wrote:Well, if you made the class you don't want people to directly use an abstract class, would that satisfy your requirement?

Sorry - didn't understand this

When a user has access to my jar, it has access to all public classes, public method etc. So I doubt if abstract class will help here.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Anayonkar Shivalkar wrote:When a user has access to my jar, it has access to all public classes, public method etc. So I doubt if abstract class will help here.

Sure it will, because clients can't then instantiate objects of those classes. Unfortunately, they can create anonymous ones if they really want to crack it.

The basic problem, as I see it, is that you (or someone else) made fundamental errors when they wrote the system, and you're now trying to come up with a solution that prevents anyone exploiting those errors without refactoring. You're further hamstrung by ridiculous limitations on HOW you can do it by people who plainly have no concept of the scale of the problem.

Sounds like a recipe for disaster to me.

My advice: If it ain't broke; don't fix it. If you DO want to fix it; do it properly.

Winston
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!