Background
In Java 101, we are taught:
A String is immutable.
Yes. Good. Thanks.
Then we go to Java 102 (or, possibly, to Java 201), and find:
A String is not really immutable: you can change it with reflection.
Oh. Good. Either pretty cute or immeasurably perverse, depending on your perspective.
These things have so far been discussed endlessly about stack overflows and elsewhere. I take this for granted in formulating this question.
I am interested to ask:
Question
Once we find that String not really immutable, what are the implications for how we should write our code?
Let me make this more specific in two ways.
JVM Sandbox
Is it possible for a malicious class to use this trick to violate the security of the JVM and get up to tricks that it should not do? Are there any places in the JDK, for example, where a String returned from a method and is safe only if it cannot be changed?
Here's a promising start:
String prop = "java.version";
This is done to retrieve the system property from the JVM returned as String , and then change the String ; the consequence is that the underlying property also changes. Could this be used to cause chaos?
I'm not sure. It is worth noting that you must have the correct permissions to reflect. Is a security game already on this? This allows me to do without the right to change security properties, but can this be expected or is this a problem?
Are there any ways to extend this to make something much worse?
Defensive cloning
We are always told that it is recommended to clone arrays and other objects before passing them to methods that can modify them if we do not want them to be changed. This is just good coding practice. This is your own stupid mistake if you give someone the only copy of your array and it gets back in a mess.
But it looks like the same argument should apply to String ! I have never heard anyone say that we must clone a String before passing it to a method written by another. But how could it be otherwise if String is as volatile as an array?
Argument for Clone Protective Strings
If defensive cloning is due to the fact that he does not know what the method can do with the things we transmit, and if what we transfer is volatile, then we should clone it. If the code may be malicious, it may modify String ; therefore, when it is important that the String remains unchanged, we need to make sure that we are sending a copy, not the real thing.
This is not to say that untrusted code should run under a security manager if we do not trust it to not do bad things in String . If this were true for String , this would be true for an array; but no one ever says that cloning arrays and other objects should only be done when you also block the code with the security manager.
Argument Against Clone Protective Strings
An array can only be modified using sloppy encoding; in other words, it may be changed unintentionally. But nobody changes String unintentionally: this can only be done with the help of vile tricks, which means that the programmer tried to break immutability.
This makes two cases different. We really do not have to pass an array, not even a clone of it, to encode that we do not trust at any level. You are not loading the library from somewhere dodgy, and then you think that everything is in order, because you cloned your array. You clone defensively because you think that a programmer may make mistakes or make different assumptions from you about what is valid with the data that you send. If you are concerned that the code might change String behind your back, you really shouldn't run the code at all. All you achieve by cloning a String is overhead.
Answer?
How should we think about this? Is it possible to break the JVM sandbox using these tricks? And should we code defensively in the light of the variability of a String , or is it all a red herring?