Granny's Programming Pearls
"inside of every large program is a small program struggling to get out"
JavaRanch.com/granny.jsp
The moose likes Java in General and the fly likes Reflection Mechansim to access private data. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Reflection Mechansim to access private data." Watch "Reflection Mechansim to access private data." New topic
Author

Reflection Mechansim to access private data.

dinesh Venkatesan
Ranch Hand

Joined: Oct 12, 2006
Posts: 134
Hi All,

Please look at the following code:

import java.lang.reflect.*;
import java.util.*;
public class CountModifier {
public static void main(String[] args) {
try {
List<String> nameList = new LinkedList<String>();
nameList.add("1");
nameList.add("2");
System.out.println(nameList.size());
Class listClass = Class.forName("java.util.LinkedList");
Field sizeField = listClass.getDeclaredField("size");
sizeField.setAccessible(true);

//The Size of the list is modified to 5.
//But the actual number of elements in the list is 2.

sizeField.setInt(nameList,5);
System.out.println(nameList.size());
}catch(Exception e) {
e.printStackTrace();
}
}
}

So running this code illegaly changes the private datamember "size" in the LinkedList class in an unacceptable manner. Can it be considered as a security Loophole or does it have anyother meaning?

Please clarify.

Thanks in advance!!

yours,
dinesh.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Your code only works when the installed security manager allows it. For example, it won't work in an unsigned applet.


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
I think of it as fairly serious "cheating" to get around the intent of the original class designers. they obviously didn't want you to change this field and they are under no obligation to make sure that changing it works now or will do the same thing in the next release. Still, I've done it a time or two mice elf.

And, yes, it could be a security hole if you can change your permissions to do some secured operation.


A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
dinesh Venkatesan
Ranch Hand

Joined: Oct 12, 2006
Posts: 134
Thanks guys, But is there any way to bring it to the notice of the Java Language Designers?
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 42609
    
  65
I wouldn't call this a bug, it's just how reflection works. As Ilja points out, a security manager can be used to disallow this behavior. If then it was still possible, that would be a bug.


Ping & DNS - my free Android networking tools app
D Rog
Ranch Hand

Joined: Feb 07, 2004
Posts: 472

It's lovely Java interview question. Is Java String immutable class? It is unless security manager allows that.


Retire your iPod and start with HD Android music player Kamerton | Minimal J2EE container is here | Light weight full J2EE stack | and build tool | Co-author of "Windows programming in Turbo Pascal"
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by dinesh Venkatesan:
Thanks guys, But is there any way to bring it to the notice of the Java Language Designers?


I'm sure they are very aware of it already. It works that way by design.
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 42609
    
  65
In the presence of a security manager, the code would need java.lang.reflect.ReflectPermission to execute.

Some reading about the security manager and permissions will help make you acquainted with those concepts.
Rahul Bhattacharjee
Ranch Hand

Joined: Nov 29, 2005
Posts: 2308
Originally posted by D Rog:
It's lovely Java interview question. Is Java String immutable class? It is unless security manager allows that.


String immutability has got nothing to do with securitymanager.


Rahul Bhattacharjee
LinkedIn - Blog
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

Originally posted by Rahul Bhattacharjee:


String immutability has got nothing to do with securitymanager.


Well, yes, it does actually; have you read all of this thread? If the installed (or null) SecurityManager allows it, you can use reflection to modify the contents of a java.lang.String or of any other object, making Strings, in fact, mutable (which is just an English word meaning "can be changed.")


[Jess in Action][AskingGoodQuestions]
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Ernest, you are right if you see it as just an english word.

In my opinion, it would be fair (or at least useful) to say that both "mutable" and "immutable" are technical terms with a definition that allows String to be an immutable class even in the presence of reflection.
dinesh Venkatesan
Ranch Hand

Joined: Oct 12, 2006
Posts: 134
I am wondering what may be the reasons for the Java designers for not implementing a SecurityManager to protect such unacceptable modifications to the privat fields such as the "size" value of the LinkedList class or the "detailMessaage" attribute of the Throwable class. Knowing these details may give better understanding of the working principles. Thats why i posted this question. Thanks for all for sharing your valuable thoughts.

dinesh.
Rahul Bhattacharjee
Ranch Hand

Joined: Nov 29, 2005
Posts: 2308
Originally posted by Ernest Friedman-Hill:
have you read all of this thread?

yes ,I have gone through the thread.But when I saw the word String and mutable , I took the literal meaning and replied.My bad.

Yes indeed , every object in java is mutable ,in case of security manger being null , or if it allows.
[ December 20, 2006: Message edited by: Rahul Bhattacharjee ]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Dinesh, I think the idea here is that if you're running an application on your box, by default it's already got access to things that you don't want a hostile program to have access to. E.g. it can read or write files on your hard drive, or send e-mail or HTTP requests to the outside world. If you're running hostile code on your box, your security is already compromised. Now in the case of an applet, that's a bit different because the idea is that you could have downloaded that thing from anywhere, and it needs to be treated as potentially hostile. So security managers for applets are by default much more cautious that security managers for applications, disallowing both private variable access and most filesystem access. Similarly, security managers in web servers are also more cautious than for applications.

The other thing here is that the idea of having private variables is not primarily there for security - it's there to encourage you to make code more maintainable. It's a good general rule that classes should not directly access each other's private data. But it's not an absolute rule, and there are occasionally exceptions. One example is serialization - it's sometimes very useful to be able to convert an object to bytes. But it would be somewhat more difficult to do this if you were forced to create public access methods for every bit of data in the class. So serialization relies on the ability to access private data from another class. (And since I just recommended it in another thread, so does XStream.)


"I'm not back." - Bill Harding, Twister
dinesh Venkatesan
Ranch Hand

Joined: Oct 12, 2006
Posts: 134
Thanks Jim, Thank you very much for your valuable inputs.
dinesh Venkatesan
Ranch Hand

Joined: Oct 12, 2006
Posts: 134
Hi Jim,

One more request! Could you please guide me writing a class say Account which has the private data member balance, so that nobody can modify it except through the interface i provide for them.

Here is the code i developed so far.

import java.io.*;
public class Account {
private double balance;
private String customerName;
private boolean isAuthenticated;


public Account() {
balance = 0.0;
customerName=new String();
isAuthenticated = false;
}

public void setBalance(double balance) throws Exception {
System.out.print("Enter the private key: ");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
if( br.readLine().equals("abc123")){
isAuthenticated=true;
}
if( isAuthenticated ) {
this.balance = balance;
}else {
System.out.println("Not An Authenticated User");
}
}

public void setCustomerName(String aCustomerName) {
customerName = aCustomerName;
}

public double getBalance() {
return balance;
}

public String getCustomerName() {
return customerName;
}
}

import java.lang.reflect.*;
public class AccountHolder {
public static void main(String[] args) {
try {
Account myAccount = new Account();
myAccount.setCustomerName("dinesh.Venkatesan");
myAccount.setBalance(50000);
System.out.println(myAccount.getBalance());

Class accountClass = Class.forName("Account");
Field balanceField = accountClass.getDeclaredField("balance");
balanceField.setAccessible(true);
balanceField.setInt(myAccount,5000000);
System.out.println(myAccount.getBalance());
}catch(Exception e) {
e.printStackTrace();
}
}
}

Thanks in Advance!
dinesh.
dinesh Venkatesan
Ranch Hand

Joined: Oct 12, 2006
Posts: 134
Some comments about the code i submitted in the last post:

1) The two classes are stored in seperate files.

2) The Account Holder class first tries to set the balance through the setBalance() method. Where i will make sure that it is authenticated and then allowing to set the balance.

3)Then i am trying to set the balance illegaly using the Reflection.

4)Let us consider a hacker with malicious intention trying to develop the AccountHolder class then how can i thwart him?

thanks,
dinesh.
Rahul Bhattacharjee
Ranch Hand

Joined: Nov 29, 2005
Posts: 2308
This might work and please let me know if it really works.

The only solution to this I see as by using the SecurityManager.

Write the methods in the interface (class that would act as the interface to Account class , not literal java interaces ) class such that the code is within the method is somethink like the following.

<taken from javadoc1.4 of AccessController>



And grant this piece the required permission (java.lang.reflect.ReflectPermission ) , so that only this code can use reflection and no other.

Experts : please correct me if I am worng.I am new to security and never got a chance in my career to implement anything in this line.
 
wood burning stoves
 
subject: Reflection Mechansim to access private data.