4

While I understand the overall point this item makes, I'm interested in understanding in depth how exactly the hacker gets the internal references of the mutable Period object. He corrupts the internal Date fields through these references so it's important to understand how exactly he gets hold of these references. I have read and reread the example and code but couldn't get this subtle point.

Bloch says:

It is possible to create a mutable Period instance by fabricating a byte stream that begins with a valid Period instance and then appends extra references to the private Date fields internal to the Period instance. The attacker reads the Period instance from the ObjectInput- Stream and then reads the “rogue object references” that were appended to the stream. These references give the attacker access to the objects referenced by the private Date fields within the Period object. By mutating these Date instances, the attacker can mutate the Period instance. The following class demonstrates this attack:

public class MutablePeriod {
  // A period instance
  public final Period period;

  // period's start field, to which we shouldn't have access 
  public final Date start;

  // period's end field, to which we shouldn't have access 
  public final Date end;

  public MutablePeriod() {
    try {
      ByteArrayOutputStream bos =
        new ByteArrayOutputStream();
      ObjectOutputStream out =
        new ObjectOutputStream(bos);
      // Serialize a valid Period instance 
      out.writeObject(new Period(new Date(), new Date()));

      /*
       * Append rogue "previous object refs" for internal 
       * Date fields in Period. For details, see "Java
       * Object Serialization Specification," Section 6.4. 
       */
      byte[] ref = { 0x71, 0, 0x7e, 0, 5 }; // Ref #5                
      bos.write(ref); // The start field
      ref[4]=4; //Ref#4
      bos.write(ref); // The end field
      // Deserialize Period and "stolen" Date references
      ObjectInputStream in = new ObjectInputStream(
      new ByteArrayInputStream(bos.toByteArray()));
      period = (Period) in.readObject();
      start  = (Date)   in.readObject();
      end    = (Date)   in.readObject();
    } catch (Exception e) {
      throw new AssertionError(e);
    }
  }
}

What's going on in this part here?

/*
 * Append rogue "previous object refs" for internal 
 * Date fields in Period. For details, see "Java
 * Object Serialization Specification," Section 6.4. 
 */
byte[] ref = { 0x71, 0, 0x7e, 0, 5 }; // Ref #5                
bos.write(ref); // The start field
ref[4]=4; //Ref#4
bos.write(ref); // The end field

And how does it help the hacker to get the references?

And later in the code how does start = (Date) in.readObject(); give him internal references of the Period object that is created?

dimo414
  • 47,227
  • 18
  • 148
  • 244
Saurabh Patil
  • 4,170
  • 4
  • 32
  • 33

1 Answers1

1

The hacker takes advantage of the fact that he created the stream, so he knows the layout.

In particular, the hacker knows that the 5th object written to the stream is the Date object referenced to by Period.start and the 4th object is the Date object referenced by Period.end.

Java serialization, for its own purposes, allows placing "references" into a stream. Otherwise, it would be impossible to serialize two objects pointing to same object.

By inserting those "references" into the stream (references to 4th and 5th object), the hacker gains access to the instances of Date held by the Period.

I am not sure how hacker would go about mutating those instances, though.