How to make a function accessible to certain classes only? - java

I am working on an API for a software so my users can extend it without modifying the source code. But, I want only certain functions to be accessed by certain classes for security reasons. Is there anyway to do this? Also, I have no code because I have no idea on how to do this.
Thanks! -Trent

I have two thoughts on this, one is that you can look at how Minecraft Forge created their plugin API.
Another way is to have a limited API between your core code and the actual plugins, but, you need to be careful of the platform. For example, if you write the core application in Java or C#, then I can use Aspect Oriented Programming (AOP) to bypass your security and have my code change the behavior of yours.
If you use functional programming (FP) languages, then you can protect more from this type of approach, if you also are not using languages on these platforms, but they are not perfect.
So, there is a trade-off between power and convenience, so how useful do you want your application to be, and how secure?
One possible solution that may work is if you go with something similar to Minecraft, though I doubt they do this, but, give a stub application to the user. They can extend it with plugins, and the interface functions they can modify are in the stub. When the program starts, the plugins are loaded, and the interface may be modified or extended, but, then the core program is pulled down and put into the stub, and then the actual program runs. The core program can be recompiled and manipulated so method names are changed, so reflection is harder to use, but taking this approach, and doing it well, would be hard.
BTW, I like Alex T's response, I just gave different terms to some of his, such as AOP instead of reflection and immutability is part of FP.
You mention jar, which means you are using something that runs on a JVM, so you may want to read up on AspectJ, as it can significantly alter the behavior of applications. You can have private methods, but I can put code that runs instead of yours, or change the parameters or the return value before or after the method is called.

To protect variables inside of classes, you can make them private, and accessible via getter and setter methods with varying levels of protection. This also applies to classes themselves; if you wanted to prevent the user from being able to instantiate a class, you could mark the class' constructor as protected to allow instantiation only within it's package.
If you wanted to hide the implementation details of a class altogether, you could declare the class as class X instead of public class X, which would hide methods from the API for standard development.
This will quickly get you the behaviour you're after, but there's an aspect of Java called reflection, which allows an executable Java program to analyze and manipulate it's own implementation; in this regard, no field or method is ever completely safe.
You can also safeguard variables by providing access to them via 'immutable' Objects; these are objects designed to forbid the caller from modifying the original source contents.

Related

Access a method in same project but different package

Is it possible to access a method in different package but same project without making the method public or inheritance? I'm looking for something similar to friendly assemblies in C#.
Is it possible to access a method in different package but same project without making the method public or inheritance?
Sortof, yes - you can use reflection to get the method that you're after, call setAccessible(true) on the method to suppress the access checks, then invoke it from wherever you like.
But...
I'm looking for something similar to friendly assemblies in C#.
This isn't it, a similar feature simply doesn't exist in the Java language. The above reflection trick should really be treated as nothing more than a hack, and certainly not something you'd want to use in production code unless there really was no other feasible option.

Marking indirect usages of classes, methods etc

Is there a standard way in Java to mark classes, methods etc. that are used by other parts of the program in indirect ways (think: reflection) which are not discoverable by the usual search-functions of IDEs?
In one particular example I have a bunch of classes with a couple of hundred small validation methods. Validation occurs basically by listing all methods of those classes via reflection and executing one by one them on the given object. (It's more complicated than that, but that's the underlying idea)
Now my IDE understandably marks each and everyone of those methods as "unused" because there are never directly called, only via reflection.
A similar problem occurs in another part of the program where several dozen helper classes reside, some of which are almost certainly unused and could be deleted. But: In some rare cases the fields of these classes are accessed via reflection and the usual search functions of the IDE cannot find these usages (again: very understandably so).
I know that it is impossible for the IDE to solve this problem without outside help. Hence my question whether there are already established ways like annotations for example to clearly mark these cases. Of course I could define such an annotation myself, but I'd rather go with an accepted standard if one exists.
Is there even an IDE that can recognise them and warn me automatically if I'm doing stuff like that?
No, there is not a standard way to mark indirect control flow (reflection, Android intents, callbacks, etc.).
There are some tools that provide their own ways to analyze indirect control flow.
For example, the Checker Framework's reflection resolution uses the #MethodVal annotation to indicate the possible targets of a reflective invocation. It also has ways to indicate Android intents.
You typically annotate those classes with #SuppressWarnings("unused") to get rid of IDE warnings

How can I intercept a method call to a library class in Java or Android?

I have a library class that is a singleton and does NOT implement any interface (So I'm assuming I cannot use dynamic proxies). But, I need the same functionality as the dynamic proxy. I need to hijack the call, log some data and pass on the call to the library as is.
Is it possible to do this without having to use AspectJ or Spring AOP? (I'm not sure how to use these frameworks, but I will have to look into it if there is no other way).
You can provide your own implementation of the same class, with the same name and package, and try to put it into classpath first. The calling code with such classpath will pick the intercepting class first, and the intercepting class can call others classes of the actual package to provide its actual functionality.
Best would be to remove the overridden class from the library .jar with archive tool.
You could change the import statements in the classes that call f() so that they see a different class that implements f(). The implementation of that class would do the logging and call the real f().
Still requires some editing, but less than changing every call.
BTW: Depending on the size of the project, you may want to consider making wrappers to that "black box" anyway, if this type of requirement will be ongoing.
Like I started in my comment wrapper all the classes you implement from the external library. Then call the external library from your own classes this way you can log in the function(s) you want. If you use the same function name then you don't have to change what you call you only have to change your import(s). Most IDEs provide mass name replace so it shouldn't be too big of a burden it will be tedious however.

Modify android internal class(es) / Call Handling

Since the whole Android stuff is open source I was thinking about to do some minor modifications in a few internal classes from the com.android.internal.telephony package and of course then I would love if somehow my application could use the modified classes. I was thinking about replacing the classes with the original ones at runtime by using reflection or other kind of unknown java tricks :D ...maybe what I'm trying to do is impossible :( I don't know that's why I'm asking.
Note: The changes in the internal classes would not change their functionality in any way, its more about extending their functionality so even if other apps would use the modified versions it would not break them!
Why I want to do it? What I'm trying to achieve ?
Well i would like to modify the com.android.internal.telephony.gsm.CallTracker internal class so i could do proper call handling (call blocking etc..)
Maybe if you know about another way how to do what I want to I would like to hear about it :)
Note2: I know about the method when you handle the android.intent.action.PHONE_STATE, action , but its simply too late to react when this action is broadcasted. I'm really looking for a better solution even if that solution involve ugly hacks :)
As always thanks for all your replies...
You cannot do this :) I'll let you imagine what would happen if any application was allowed to freely replace core parts of the system. You can download the Android source code and you can modify it and you can upload the modifications to your phone (if your phone is rooted/unlocked) but you cannot apply such modifications with a simple app.
Changing a classes functionality (methods, byte code) after a class ha been loaded is impossible. Reflection/Invocation does not affect classes but static fields and instances only.
Your looking at a way to add additional methods or change existing methods of a running system, because the classes in question probably will be loaded already when your 'hacking' application is executed.
The only technical approach that I see is to change the classes in advance and deploy a modified system. I'm just ignoring possible licensing issues and security at the moment. But even with this way, your software would depend on a custom OS, a branch from some andorid version, disconnected from official updates, and you'd have to ask your customers to install a custom OS with, say, unknown features.
Sidenote - I'm very happy, that this is really impossible, otherwise my mobile would already be full of trojans, viruses, etc...
Romain is correct you can't and shouldn't try to change existing system classes.
That said, implementing call screening as you suggest should be possible by creating a replacement to the dialer application that handles phone calls.
Specifically the intent ACTION_ANSWER should be handled by your application, which could then either implement a dialer-like interface or open the dialer app (or any other call manager) explicitly.
There are actually ways to hack on Android framework classes, it just depends on which ones you want to hack.
You must extend the class you intent to hack on.
If you want to override package private methods and/or access package private variables you can put your class in the same package.
You can use reflection.
I've actually had to do this to work around bugs. Romain is correct, to an extent. It all depends on the structure of the code you are trying to hack on. You definitely can't hack on Android internals, but you can hack on other framework classes like Activity, View, etc.

Outside classes accessing package-private methods

Suppose I have a class in my package org.jake and it has a method with default access (no modifier). Then the method is visible inside the package only.
However, when someone receives the jar of my framework, what is to stop them from writing a new class, declaring its package as org.jake, and using my supposedly invisible method?
In other words, is there anything I can do to prevent this?
You could seal the package in your jar file. It's not bullet-proof though.
The main thing is not to rely on access modifiers etc from a security point of view to start with, really. If someone is running the code with unrestricted permissions, they're going to have access to all kinds of things. Access modifiers really just help to stop people from accidentally shooting themselves in the foot.
If someone is willing to put classes in your package to circumvent your encapsulation, they're clearly ignoring your best intentions - I say let 'em get on with it, but don't provide support for that scenario.
There is nothing you can do to prevent this. Even private members can be accessed via reflection. You should consider the access modifiers in java to be merely suggestive.
First off, this is the “DRM” scenario: ultimately, someone determined enough can defeat any protections you put in place by supplying a funky modified runtime or other such things. The reverse scenario – where the runtime is trusted but some of the packages are not – is tackled properly by Java through the use of suitable ClassLoader restrictions, but that can only work where there's something that can enforce the restrictions in a trusted fashion; that's why your scenario is basically doomed.
However, if we assume that the runtime itself is trustable then you could try, in your super-secret method, getting the stack trace of the currently executing stack (see stackoverflow.com/questions/1069066/… for how) and testing to see whether the caller of the current method is one that you trust to get access. A security manager would be even more suitable, but you can't trust the environment to have one of those installed that you like (it's much more clearly under the control of the attacker). Note that I have not tried the options in this paragraph!
The other alternative is to put your secrets on a service you control and only offer remote access to them. Or stop worrying about using technical mechanisms to deal with a problem that is fundamentally about business and legal issues (e.g., why are you dealing with people you can't trust?)
I'd say simply do not allow them to run code where it can call yours, i.e. in the same JVM. You could instead consider offering only a (web)service they can call externally. I'm not very up to date on the best ways to implement this though.

Categories

Resources