Overall the direction seems promising.  Poking at it a bit...

- ReadSerial methods are caller-sensitive and only show a class a view of its own fields. - Invariant checking is separate from deserialization, and does not seem entirely built-in -- subclass constructors seem responsible for asking parents to do validity-checking? - I don't see how this invariant-checking mechanism can enforce invariants between superclass fields and subclass fields. For example:

class A {
    int lower, upper;  // invariant: lower <= upper
}

class B extends A {
    int cur;  // invariant: lower <= cur <= upper
}

To check such an invariant, the serialization library would have to construct the object (in a potentially bad state), invoke the checker at each layer, and then fail deserialization if any checker said no. But, an evil checker could still squirrel away a reference under the carpet.

Another challenge in invariant checking is circular data structures. If you have two objects:

class Brother {
    final Brother brother;
}

that refer to each other, an invariant you might want to check after deserialization is that
  this.brother.brother == this

Obviously you have to patch one or the other instance after construction to retain the circular references; at what point do you do invariant checking?

On 1/1/2015 7:43 AM, Peter Firmstone wrote:
Subclass example:

class SubFoo extends BaseFoo {

public static ReadSerial check(ReadSerial rs){
if (rs.getInt("y") > 128) throw Exception("too big");
return rs;
}

private final int y;

public SubFoo( int x , int y) {
super(x);
this.y = y;
}

public SubFoo( ReadSerial rs ){
super(BaseFoo.check(check(rs)));
// SubFoo can't get at BaseFoo's rs.getInt("x"),
// it's visible only to BaseFoo. Instead SubFoo would get
// the default int value of 0. Just in case both classes have
// private fields named "x".
// ReadSerial is caller sensitive.
this.y = rs.getInt("y");
}
}

Classes in the heirarchy can provide a static method that throws an
exception to check invarients while preventing a finaliser attack. We'd
want to check invarients for other constructors also, but for berevity...

Eg:

class BaseFoo implements Serializable{

public static ReadSerial check(ReadSerial rs) throws Exception
{
if (rs.getInt("x") < 1)
throw IllegalArgumentException("message");
return rs;
}
....


Sent from my Nokia N900.

----- Original message -----
 > So, if I understand this correctly, the way this would get used is:
 >
 > class BaseFoo implements Serializable {
 >          private final int x;
 >
 >          public BaseFoo(ReadSerial rs) {
 >                  this(rs.getInt("x"));
 >          }
 >
 >          public BaseFoo(int x) {
 >                  this.x = x;
 >          }
 > }
 >
 > Right?
 >
 > What happens with subclasses?  I think then I need an extra RS arg in my
 > constructors:
 >
 > class SubFoo extends BaseFoo {
 >          private final int y;
 >
 >          public SubFoo(ReadSerial rs) {
 >                  this(rs.getInt("y"));
 >          }
 >
 >          public BaseFoo(ReadSerial rs, int y) {
 >                  super(rs);
 >                  this.y = y;
 >          }
 > }
 >
 > Is this what you envision?
 >
 >
 >
 >
 >
 > On 12/27/2014 8:03 PM, Peter Firmstone wrote:
 > > Is there any interest in developing an explicit API for
Serialization?:
 > >
 > > 1. Use a public constructor signature with a single argument,
 > > ReadSerialParameters (read only, writable only by the
 > > serialization framework) to recreate objects, subclasses (when
 > > permitted) call this first from their own constructor, they have
 > > an identical constructor signature.  ReadSerialParameters that are
 > > null may contain a circular reference and will be available after
 > > construction, see #3 below.
 > > 2. Use a factory method (defined by an interface) with one parameter,
 > > WriteSerialParameters (write only, readable only by the
 > > serialization framework), this method can be overridden by
 > > subclasses (when permitted)
 > > 3. For circular links, a public method (defined by an interface) that
 > > accepts one argument, ReadSerialParameters, this method is called
 > > after the constructor completes, subclasses overriding this should
 > > call the superclass method.  If this method is not called, an
 > > implementation, if known to possibly contain circular links,
 > > should check it has been fully initialized in each object method
 > > called.
 > > 4. Retains compatibility with current serialization stream format.
 > > 5. Each serial field has a name, calling class and object reference,
 > > similar to explicitly declaring "private static final
 > > ObjectStreamField[] serialPersistentFields ".
 > >
 > > Benefits:
 > >
 > > 1. An object's internal form is not publicised.
 > > 2. Each class in an object's heirarchy can use a static method to
 > > check invarients and throw an exception, prior to
 > > java.lang.Object's constructor being called, preventing
 > > construction and avoiding finalizer attacks.
 > > 3. Final field friendly.
 > > 4. Compatible with existing serial form.
 > > 5. Flexible serial form evolution.
 > > 6. All methods are public and explicitly defined.
 > > 7. All class ProtectionDomain's exist in the current execution
 > > context, allowing an object to throw a SecurityException before
 > > construction.
 > > 8. Less susceptible to deserialization attacks.
 > >
 > > Problems:
 > >
 > > 1. Implementations cannot be package private or private.  Implicit
 > > serialization publicises internal form, any thoughts?
 > >
 > > Recommendations:
 > >
 > > 1. Create a security check in the serialization framework for
 > > implicit serialization, allowing administrators to reduce their
 > > deserialization attack surface.
 > > 2. For improved security, disallow classes implementing explicit
 > > serialization from having static state and static initializer
 > > blocks, only allow static methods, this would require complier and
 > > verifier changes.
 > > 3. Alternative to #2, allow final static fields, but don't allow
 > > static initializer blocks or mutable static fields, similar to
 > > interfaces.
 > >
 > > Penny for your thoughts?
 > >
 > > Regards,
 > >
 > > Peter Firmstone.

Reply via email to