JavaScript strings immutable in Rhino???
Update: Hmmm. I think I'm looking at the wrong thing. This needs more testing/tracing to see exactly whats going on.
Just a quick update from yesterday's post. It appears that Mozilla Rhino (a JavaScript interpreter written in Java) uses Java's String object to represent JavaScript strings inside of the engine. Here is the constructor from /js/src/org/mozilla/javascript/NativeString.java:
69 private NativeString(String s) {
70 string = s;
71 }
This could be bad, depending on what people are storing in JavaScript strings (which are represented as Java String objects). Strings are immutable in Java (and many other languages). You as a developer cannot easily clear out the contents of the String object. As you manipulate a string, mulitple copies are made of its contents. For example consider this Java code:
String foo = "p@$$w0rd";
System.out.print("Your password in upper case is:");
System.out.println(foo.toUpperCase());
There are now two copies of the password string in memory, "p@$$w0rd" and "P@$$W0RD." Noted security expert John Viega has discussed disclosing sensitive data in memory in length.
Why is all of this an issue? Because the JavaScript language spec doesn't provide an information/warnings/guidance about what you should and should not store in JavaScript strings (and really they shouldn't). It's up the designers and implementors of JavaScript interpreters to explain how their interpreter handles data. However I don't now of a single JavaScript interpreter that does this. Rhino certainly contains no warnings that sensitive data should not be stored in JavaScript strings. To make matters more concerning, Rhino is not typically embedded in a web browser where client-side JavaScript strings shouldn't contain sensitive information anyway (yes, I know that web security readers just let out a laugh). Rhino embedded in other programs/projects where the types of data it could be processing are far more diverse than in a web browser and the probability that sensitive data will be present in JavaScript (and thus Java) strings is higher.
All and all, the Mozilla folks should probably modify Rhino so that it uses a StringBuilder Object instead of a String object to represent JavaScript strings. I haven't dug into SpiderMonkey, but hopefully they are clobbering character arrays with junk before freeing it. Interestingly, I just found this article describing situations where compilers will "optimize" memset() calls to override sensitive sting data. Its possible SpiderMonkey leaves sensitive data lying around as well even if they are trying not to!
Billy Hoffman is the lead researcher for SPI Labs.