• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Reflection Mechansim to access private data.

 
dinesh Venkatesan
Ranch Hand
Posts: 134
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your code only works when the installed security manager allows it. For example, it won't work in an unsigned applet.
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
dinesh Venkatesan
Ranch Hand
Posts: 134
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks guys, But is there any way to bring it to the notice of the Java Language Designers?
 
Ulf Dittmer
Rancher
Posts: 42967
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
D Rog
Ranch Hand
Posts: 472
Linux Objective C Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's lovely Java interview question. Is Java String immutable class? It is unless security manager allows that.
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Rancher
Posts: 42967
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 2308
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24208
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.")
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 134
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 2308
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.)
 
dinesh Venkatesan
Ranch Hand
Posts: 134
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Jim, Thank you very much for your valuable inputs.
 
dinesh Venkatesan
Ranch Hand
Posts: 134
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 134
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 2308
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic