D
dimitrik107
Why String is immutable? Is there simple explanation I can't find it?
For the same reason Integer is immutable: that's how the author(s) decidedWhy String is immutable? Is there simple explanation I can't find it?
Why String is immutable? Is there simple explanation I can't find it?
Why String is immutable? Is there simple explanation I can't find it?
Why String is immutable? Is there simple explanation I can't find it?
Why String is immutable? Is there simple explanation I can't find it?
The second reason has to do with the Java security model. When a
security policy is installed, certain restrictions can be enforced on --
for example -- which files can be read, which hosts can be connected to
over the network, and so on. The immutable String class ensures that
security-sensitive APIs only have to check the file name or host name
once, and can then rely on it to stay the same. A mutable String class
would introduce a race condition where the application (in another
thread) could modify the file name after the security check, but before
the file is actually opened, and thus circumvent the security mechanism.
Matt said:The second reason has to do with the Java security model. When a
security policy is installed, certain restrictions can be enforced on --
for example -- which files can be read, which hosts can be connected to
over the network, and so on. The immutable String class ensures that
security-sensitive APIs only have to check the file name or host name
once, and can then rely on it to stay the same. A mutable String class
would introduce a race condition where the application (in another
thread) could modify the file name after the security check, but before
the file is actually opened, and thus circumvent the security mechanism.
Hi, I wholeheartedly agree with your first point of it being the only
sane way to implement Strings from a design point of view, but I'm less
sure about relying on this for security. The underlying char[] is still
writable if you try a bit harder. I expect the method below could be
forbidden with the right security policy (ReflectPermission
seems to be granted by default on my system) but I suspect you could
still access the field directly if you craft your own byte code?
import java.lang.reflect.Field;
public class StringImmutabilityTest {
public static void main(String[] args) throws Exception {
String fileNameToServe = "/ftp/readme";
char[] injection = "/etc/passwd".toCharArray();
Field f = fileNameToServe.getClass().getDeclaredField("value");
f.setAccessible(true);
char[] val = (char[]) f.get(fileNameToServe);
System.arraycopy(injection, 0, val, 0, injection.length);
System.out.println(fileNameToServe);
}
}
Of course, you're probably doomed the moment you allow untrusted code
into your VM anyway!
By the way, calling new String(String) on any untrusted Strings will
probably keep you a little safe from this.
Matt
Why String is immutable? Is there simple explanation I can't find it?
Matt Rose said:Hi, I wholeheartedly agree with your first point of it being the only
sane way to implement Strings from a design point of view, but I'm less
sure about relying on this for security. The underlying char[] is still
writable if you try a bit harder. I expect the method below could be
forbidden with the right security policy (ReflectPermission
seems to be granted by default on my system) but I suspect you could
still access the field directly if you craft your own byte code?
Of course, you're probably doomed the moment you allow untrusted code
into your VM anyway!
Chris said:Matt Rose said:Hi, I wholeheartedly agree with your first point of it being the only
sane way to implement Strings from a design point of view, but I'm less
sure about relying on this for security. The underlying char[] is still
writable if you try a bit harder. I expect the method below could be
forbidden with the right security policy (ReflectPermission
seems to be granted by default on my system) but I suspect you could
still access the field directly if you craft your own byte code?
Everything is granted by default. The point is that if you install a
security manager, you can control this stuff. There are some
permissions that can never be granted to security-sensitive code; but
you just don't grant those permissions. One of those is
ReflectPermission("suppressAccessChecks"), which covers the call to
setAccessible.
Not at all. That's what applets do, millions of times per day. If you
were right, then someone could really cause havoc around the world.
You're not right, though.
Matt Rose said:Does this get checked by the GETFIELD opcode? I can't find any
indication that it does in the VM spec but I haven't tested it. I never
normally get involved with bytecode.
Chris said:As long as we're on the topic, it should be mentioned that the
discussion of private fields might be misleading. From a security
standpoint, private is actually considerably less interesting than
package-access restrictions. The Java compiler routinely generates
hidden package-access methods that allow access to private fields
(particularly when dealing with nested classes), so relying on private
access is not safe. Building a secure API requires placing classes in a
sealed package, and then ensuring that all protected or public access
meets the security requirements. Since the core API packages are
sealed, this is exactly what happens here.
Babu Kalakrishnan said:One query in connection with that last statement. Remember seeing an
article a while back about how easy it is to crack an encrypted
classloader by replacing one of the classes in rt.jar with a modified
version (the ClassLoader class). If the rt.jar file is indeed sealed,
would this be allowed ?
(Isn't there some restriction that every class
in a package must be signed by the same signer?)
Also, is there a way for an application program to determine if it is
indeed running under a JVM whose core library is sealed?
Chris said:Nope. All that's required is that the line "Sealed: true" in the JAR
manifest. Package signing is a different matter. If the JVM loads a
class from a JAR file with "Sealed: true" in the manifest, then it will
ensure that it does not (and has not, in the past) load a class in the
same package from a different JAR file.
Chris said:Nope. All that's required is that the line "Sealed: true" in the JAR
manifest. Package signing is a different matter. If the JVM loads a
class from a JAR file with "Sealed: true" in the manifest, then it will
ensure that it does not (and has not, in the past) load a class in the
same package from a different JAR file.
Chris Smith said:The getfield opcode is checked by the bytecode verifier when the class
is loaded. If it tries to access a field to which it doesn't have
access permission, the verifier will throw a java.lang.VerifyError, and
the class will fail to load.
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.