Solved

Banning java reflection in coding

Posted on 2013-05-24
28
211 Views
Last Modified: 2013-06-17
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
0
Comment
Question by:beavoid
  • 12
  • 9
  • 7
28 Comments
 
LVL 86

Accepted Solution

by:
CEHJ earned 251 total points
ID: 39194505
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
 

Author Comment

by:beavoid
ID: 39196013
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
 
LVL 86

Expert Comment

by:CEHJ
ID: 39196336
0
 

Author Comment

by:beavoid
ID: 39196483
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
 
LVL 86

Assisted Solution

by:CEHJ
CEHJ earned 251 total points
ID: 39196714
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
 

Author Comment

by:beavoid
ID: 39197111
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
 
LVL 35

Assisted Solution

by:mccarl
mccarl earned 249 total points
ID: 39198358
@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
 
LVL 35

Assisted Solution

by:mccarl
mccarl earned 249 total points
ID: 39198371
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
 

Author Comment

by:beavoid
ID: 39199691
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
 
LVL 86

Assisted Solution

by:CEHJ
CEHJ earned 251 total points
ID: 39199781
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
 
LVL 35

Expert Comment

by:mccarl
ID: 39199992
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
 
LVL 35

Expert Comment

by:mccarl
ID: 39199994
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
 

Author Comment

by:beavoid
ID: 39200111
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
 
LVL 35

Assisted Solution

by:mccarl
mccarl earned 249 total points
ID: 39200129
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
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 35

Expert Comment

by:mccarl
ID: 39200137
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
 

Author Comment

by:beavoid
ID: 39200190
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
 
LVL 86

Expert Comment

by:CEHJ
ID: 39200531
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
 

Author Comment

by:beavoid
ID: 39201629
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
 

Author Comment

by:beavoid
ID: 39202348
Can I instruct a class to be un-reflection-able ?
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 39202516
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
 

Author Comment

by:beavoid
ID: 39202735
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
 
LVL 35

Expert Comment

by:mccarl
ID: 39206793
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
 
LVL 86

Expert Comment

by:CEHJ
ID: 39206987
Indeed, though why they would do that is mysterious ...
0
 

Author Comment

by:beavoid
ID: 39213280
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
 

Author Comment

by:beavoid
ID: 39213729
I mean clientSocket.receive() blows up on client coding machine. Sorry.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 39214016
That's all very vague ;) We need to see exceptions etc. (in a new question)
0
 

Author Closing Comment

by:beavoid
ID: 39253313
Thanks
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 39254019
:)
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Suggested Solutions

Java contains several comparison operators (e.g., <, <=, >, >=, ==, !=) that allow you to compare primitive values. However, these operators cannot be used to compare the contents of objects. Interface Comparable is used to allow objects of a cl…
Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now