Banning java reflection in coding

Hi

In my project, I am disallowing code entries to use reflection on other objects to steal data.
Is it possible to see in a split second if this cheating has occurred?
If one class extends a class, if I make all the data I want to conceal, private / protected from children. Reflection can be used to discern this data? But, Must I just disallow anything that starts "import java.lang.reflect." ? Then private and protected will be enforced in the parent class?

Is reflection the only way to steal data members from other objects in the JVM?

Thanks
beavoidAsked:
Who is Participating?
 
CEHJConnect With a Mentor Commented:
http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#getDeclaredFields() would need to be called to break encapsulation. Simply ensure that a SecurityManager is in place (don't allow the code to run otherwise) and deny access
0
 
beavoidAuthor Commented:
Do I create the security manager in the class constructor? to completely protect its data? What does it do to the JVM?

I have a game class that maintains the state of a game (position of objects)

I dont want any classes that extend this class to be able to see its data (game state)
If I do private, protected data members, reflection can sniff them out?

What else is there?

What does the data protection code look like? Does the JVM then know who to protect?
Thanks
0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
beavoidAuthor Commented:
Thanks CEHJ

I may be wrong, but that link seemed only to be a good discussion.

How do I guarantee that a class A that extends B can't read any of the specified data members in class B, even with reflection, so, private is truly meaningful, even for extending classes.

Do I specify this in B's constructor, or in main() ?
Can I ban any descendants, extenders that use java.lang.reflect  ?
how?
what would any of this code be?
Maybe I can make the class B completely unreadable, and only have accessor methods?

Thanks
0
 
CEHJConnect With a Mentor Commented:
On closer inspection, the link above is not very practical about installing the security manager. This one is:

http://journals.ecs.soton.ac.uk/java/tutorial/networking/security/index.html
0
 
beavoidAuthor Commented:
Well, here are the definitions on wikipedia

private -
The private keyword is used in the declaration of a method, field, or inner class; private members can only be accessed by other members of their own class.
protected -
The protected keyword is used in the declaration of a method, field, or inner class; protected members can only be accessed by members of their own class, that class's subclasses or classes from the same package.[18]

That sounds like private is what I want, cause children can't see its data.

So, if my game state Class's Object locations are private, the extending class can't see that data without accessing methods? How do I disallow reflection?
Does the security manager have a checkUsage type method for classes that extend themselves, reflection?
0
 
mccarlConnect With a Mentor IT Business Systems Analyst / Software DeveloperCommented:
@beavoid,

Here is a concise example showing the installation of a default security manager that will deny attempts to use reflection to access a private field. If you run it as is, it shows the normal behaviour that allows relection to change the accessibility of private fields, and returns the value. Uncomment line 9 to install the security manager and deny that access. As you can see from the stack trace, it is a "checkPermission()" method call on the SecurityManager that is called with a ReflectPermission type permission and a name of "suppressAccessChecks" as the argument. (Note that you may have to subclass the SecurityManager class and define your own security policy for some/all of the other checks that it does, so that existing functionality is still permitted, ie. this is a JVM wide SecurityManager and so installing this will/may have other side effects)
package testReflectionSecurity;

import java.lang.reflect.Field;

public class TestReflectionSecurity {
    
    public static void main(String[] args) throws SecurityException, IllegalArgumentException, NoSuchFieldException, IllegalAccessException {
        
//        System.setSecurityManager(new SecurityManager());
        
        System.out.println("The int is: " + (new Sub()).attemptRestrictedAccess());
    }
    
    public static class Super {
        private int privateField = 42;
    }
    
    public static class Sub extends Super {
        public int attemptRestrictedAccess() throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
            Field field = getClass().getSuperclass().getDeclaredField("privateField");
            field.setAccessible(true);
            return field.getInt(this);
        }
    }
}

Open in new window

0
 
mccarlConnect With a Mentor IT Business Systems Analyst / Software DeveloperCommented:
Oh, and yes you would probably set the SecurityManager fairly early in your code, at least before any possibly malicious code gets a chance to run and get a reference to the super classes private fields.
0
 
beavoidAuthor Commented:
So, the very first line in the game-state class's constructor?
Sounds right

It looks like..


System.setSecurityManager(new SecurityManager());

Makes it so that children need

Field field = getClass().getSuperclass().getDeclaredField("privateField");
            field.setAccessible(true);
            return field.getInt(this);

To access private data members,
Does byte code disclose the precise names of data members? What if a cheat doesn't know the exact name of my data members? So, all my spiderX[] spiderY[] arrays are safe if they don't know the data member's name?

Thx
0
 
CEHJConnect With a Mentor Commented:
Makes it so that children need

Field field = getClass().getSuperclass().getDeclaredField("privateField");
No, it makes it that it won't happen even IF the field name is known. You'll get an exception, something like

Exception in thread "main" java.security.AccessControlException: access denied ("java.lang.reflect.ReflectPermission" "suppressAccessChecks")

Open in new window


Of course it must be said that they could use  your classes in their own app, without a SecurityManager
0
 
mccarlIT Business Systems Analyst / Software DeveloperCommented:
So, the very first line in the game-state class's constructor?
Sounds right
No! That could well be too late. Some malicious code could still have retrieved a reference to the game state's "class" which is used to find the private data members and to get a reference to them and make them accessible BEFORE the constructor of that game state class is called.

Also, as I said that SecurityManager affects the ENTIRE application, so it would make sense to install it in a place that is more common to the entire application. I don't know anything of the architecture of your code but I would say that early on in a "main()" function would be an appropriate location.
0
 
mccarlIT Business Systems Analyst / Software DeveloperCommented:
What if a cheat doesn't know the exact name of my data members?
There is also a ".getDeclaredFields()" method so that code can get an array of ALL fields, from which they could get the names & types of the fields and then potentially deduce what are the important ones.
0
 
beavoidAuthor Commented:
So, in all,

this code to attempt illegal action :

public int attemptRestrictedAccess() throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
            Field field = getClass().getSuperclass().getDeclaredField("privateField");
            field.setAccessible(true);
            }

Tries to steal 'privateField' from its super, but then designates it as accessible,

Should I steal all of my wanted-secure data members and set them all as
 field.setAccessible(false); - maybe do it in its own constructor?

Will the getDeclaredFields() still show up my secret fields once they are false-accessible?

?

The simulations will be run on my machines, so native code or similar is not really possible.

Thanks
0
 
mccarlConnect With a Mentor IT Business Systems Analyst / Software DeveloperCommented:
Should I steal all of my wanted-secure data members and set them all as
 field.setAccessible(false); - maybe do it in its own constructor?
No, it isn't the actual field that is being set as accessible or not, it is the Field reference. Take this example...
Field fieldRef1 = getClass().getSuperclass().getDeclaredField("privateField");
fieldRef1.setAccessible(true);
Field fieldRef2 = getClass().getSuperclass().getDeclaredField("privateField");
fieldRef2.setAccessible(false);

fieldRef1.getInt(this);   // This line will work
filedRef2.getInt(this);   // This line WON'T work, and the order of the above has no impact either

Open in new window

Hope that makes it clear on what .setAccessible() really means.

As has already been stated, installing the SecurityManager is how you stop any code from being able to call  ".setAccessible(true)" on a field reference.

Will the getDeclaredFields() still show up my secret fields once they are false-accessible?
You have got this around the wrong way, you would need to call .getDeclaredFields() or .getDeclaredField("myField") before you have a Field object that you can call .setAccessible(false) on. I guess this is an extension of what I tried to explain above, that "accessible or not" is a property of just the Field reference object not the actual field in the class in question.

As an aside, if you changed that question to a more appropriate one like so, "Will the getDeclaredFields() still show up my secret fields once a SecurityManager has been installed?", then the answer to that is YES. You can't stop any code from enumerating the fields in any class of your app. The SecurityManager only stops the ".setAccessible(true)" call from succeeding and therefore from being able to access the value of your fields.
0
 
mccarlIT Business Systems Analyst / Software DeveloperCommented:
An interesting question is, in what scenario/context are you thinking about all these issues? From previous questions, I am assuming that this "game state" that you are worried about exists only on your server? So how would any malicious code be running that code potentially even attempt to access your private data?
0
 
beavoidAuthor Commented:
I am realizing that for a big war RTS, like a typical huge Starcraft game, my game state arrays can't fit in the unit x, y locations and other needed game state data easily into a UDP packet. - With a 4 byte integer. What if 200 plus units' data needs to be transferred. So, I am thinking of sticking with the simpler, game state on clients concept, only because sending just keyboard and mouse directives is simpler than an entire game state. Or am I not thinking right? Giant games don't seem practical with game state on server? Also, huge UDP messages are risky.
?
0
 
CEHJCommented:
What if 200 plus units' data needs to be transferred.
You only need to send the game state deltas, using some kind of binary diff system

So, I am thinking of sticking with the simpler, game state on clients concept
That will simply give you a different problem - that of making the clients responsible for synching state. How are you going to do that - p2p or through the server? If the latter, the burden is not much different, and could even be heavier
0
 
beavoidAuthor Commented:
Thx
When I did it before,

The server distributes movement messages from a client to each other client. Every client knows what the other clients were doing in that frame and updates their game state from small UDP messages. A movement message must be received at each client per frame. When I did it this way once, it worked perfectly, massive unit movement was not a problem. I didn't send deltas, only destination X's and Y's, the client updating the unitX[], unitY[] per frame.
Either way, x,y on server, or this, the clients maintain unitX[] and unitY[]

I only want to make the unitX[] and unitY[] arrays unreadable by extending classes, and apparently private or protected isn't enough. If I send just the deltas, which is appealing, then can't the unitX[] still be reflected or stolen?

Thanks
0
 
beavoidAuthor Commented:
Can I instruct a class to be un-reflection-able ?
0
 
CEHJCommented:
Can I instruct a class to be un-reflection-able ?
We're going around in circles. You can only do it to a certain extent, by using ... a SecurityManager

I only want to make the unitX[] and unitY[] arrays unreadable
That's a bit confusing - isn't that precisely what's holding the game state (or part of it)? The clients will have to read it to use it won't they?
0
 
beavoidAuthor Commented:
Yes, the clients themselves will need to read it, so private there will be relevant,

but I don't want anyone that extends the client to read unitX outright. What if that unit is in the fog of war?
because the person extending the client class could decide to make a radar like window revealing all the locations of the objects, even unseeable objects.
0
 
mccarlIT Business Systems Analyst / Software DeveloperCommented:
As CEHJ touched on, once all this code is on the client side, a malicious user can do much more than just "extend your class"! They could rewrite it, they could run it without using a SecurityManager, they could just implement their own code that emulates your network protocol to build their own view of the game state, etc, etc, etc. All those things are why you would have initially been advised about keeping the game state on the server, IF minimising cheating was one of your higher priorities.
0
 
CEHJCommented:
Indeed, though why they would do that is mysterious ...
0
 
beavoidAuthor Commented:
I said elsewhere that I was unhappy with sending UDP packets of the game state and was corrected by only needing to send deltas. So, I only need deltas for units that have moved out of the fog of war? What if 100s or dozens of units are seeable. It will blowout my packet size. That makes the old "Send the server only user keyboard /  mouse commands to be bounced to other clients." - more appealing.

Another problem is that I only have 2 machines on my desk. I'm using my Macbook to code my server, and a PC for the clients. The PC clients often blow up with errors, on lines dealing with serverSocket.receive() etc. So, hosting 2 clients on one machine must be a problem.

How do pro's do this sort of thing?
0
 
beavoidAuthor Commented:
I mean clientSocket.receive() blows up on client coding machine. Sorry.
0
 
CEHJCommented:
That's all very vague ;) We need to see exceptions etc. (in a new question)
0
 
beavoidAuthor Commented:
Thanks
0
 
CEHJCommented:
:)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.