Question

There are two attacks documented in readObject() methods, one is called BogusPeriod, and the other is...

There are two attacks documented in readObject() methods, one is called BogusPeriod, and the other is called MutablePeriod. Implement either (your choice) of these attacks (basically involves typing in code) and verify that the attack takes place.

0 0
Add a comment Improve this question Transcribed image text
Answer #1

Item 39 contains an immutable date-range class containing mutable private Date fields. The class goes to great lengths to preserve its invariants and its immutability by defensively copying Date objects in its constructor and accessors. Here is the class:

// Immutable class that uses defensive copying

public final class Period {

private final Date start;

private final Date end;

/**

* @param start the beginning of the period

* @param end the end of the period; must not precede start

* @throws IllegalArgumentException if start is after end

* @throws NullPointerException if start or end is null

*/

public Period(Date start, Date end) {

this.start = new Date(start.getTime());

this.end = new Date(end.getTime());

if (this.start.compareTo(this.end) > 0)

throw new IllegalArgumentException(

start + " after " + end);

}

public Date start () { return new Date(start.getTime()); }

public Date end () { return new Date(end.getTime()); }

public String toString() { return start + " - " + end; }

... // Remainder omitted

}

Suppose you decide that you want this class to be serializable. Because the physical representation of aPeriod object exactly mirrors its logical data content, it is not unreasonable to use the default serialized form (Item 75). Therefore, it might seem that all you have to do to make the class serializable is to add the words “implements Serializable” to the class declaration. If you did so, however, the class would no longer guarantee its critical invariants.

The problem is that the readObject method is effectively another public constructor, and it demands all of the same care as any other constructor. Just as a constructor must check its arguments for validity (Item 38) and make defensive copies of parameters where appropriate (Item 39), so must a readObject method. If areadObject method fails to do either of these things, it is a relatively simple matter for an attacker to violate the class’s invariants.

Loosely speaking, readObject is a constructor that takes a byte stream as its sole parameter. In normal use, the byte stream is generated by serializing a normally constructed instance. The problem arises whenreadObject is presented with a byte stream that is artificially constructed to generate an object that violates the invariants of its class. To fix this problem, provide a readObject method for Period that callsdefaultReadObject and then checks the validity of the deserialized object. If the validity check fails, thereadObject method throws an InvalidObjectException, preventing the deserialization from completing:

// readObject method with validity checking

private void readObject(ObjectInputStream s)

throws IOException, ClassNotFoundException {

s.defaultReadObject();

// Check that our invariants are satisfied

if (start.compareTo(end) > 0)

throw new InvalidObjectException(start +" after "+ end);

}

While this fix prevents an attacker from creating an invalid Period instance, there is a more subtle problem still lurking. 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 Periodinstance.

The source of the problem is that Period’s readObject method is not doing enough defensive copying. When an object is deserialized, it is critical to defensively copy any field containing an object reference that a client must not possess. Therefore, every serializable immutable class containing private mutable components must defensively copy these components in its readObject method. The following readObjectmethod suffices to ensure Period’s invariants and to maintain its immutability:

// readObject method with defensive copying and validity checking

private void readObject(ObjectInputStream s)

throws IOException, ClassNotFoundException {

s.defaultReadObject();

// Defensively copy our mutable components

start = new Date(start.getTime());

end = new Date(end.getTime());

// Check that our invariants are satisfied

if (start.compareTo(end) > 0)

throw new InvalidObjectException(start +" after "+ end);

}

Note that the defensive copy is performed prior to the validity check and that we did not use Date’s clonemethod to perform the defensive copy. Both of these details are required to protect Period against attack (Item 39). Note also that defensive copying is not possible for final fields. To use the readObject method, we must make the start and end fields nonfinal.

Here is a simple litmus test for deciding whether the default readObject method is acceptable for a class: would you feel comfortable adding a public constructor that took as parameters the values for each nontransient field in the object and stored the values in the fields with no validation whatsoever? If not, you must provide a readObject method, and it must perform all the validity checking and defensive copying that would be required of a constructor. Alternatively, you can use the serialization proxy pattern (Item 78).

There is one other similarity between readObject methods and constructors, concerning nonfinal serializable classes. A readObject method must not invoke an overridable method, directly or indirectly (Item 17). If this rule is violated and the method is overridden, the overriding method will run before the subclass’s state has been deserialized. A program failure is likely to result.

To summarize, anytime you write a readObject method, adopt the mind-set that you are writing a public constructor that must produce a valid instance regardless of what byte stream it is given. Do not assume that the byte stream represents an actual serialized instance. While the examples in this item concern a class that uses the default serialized form, all of the issues that were raised apply equally to classes with custom serialized forms. Here, in summary form, are the guidelines for writing a bulletproof readObject method:

• For classes with object reference fields that must remain private, defensively copy each object in such a field. Mutable components of immutable classes fall into this category.

• Check any invariants and throw an InvalidObjectException if a check fails. The checks should follow any defensive copying.

• If an entire object graph must be validated after it is deserialized, use the ObjectInputValidation interface [JavaSE6, Serialization].

• Do not invoke any overridable methods in the class, directly or indirectly.

This noncompliant code example fails to defensively copy the mutable Date object date. An attacker might be able to create an instance of MutableSer whose date object contains a nefarious subclass of Date and whose methods can perform actions specified by an attacker. Any code that depends on the immutability of the subobject is vulnerable.

class MutableSer implements Serializable {

  private static final Date epoch = new Date(0);

  private Date date = null; // Mutable component

   

  public MutableSer(Date d){

    date = new Date(d.getTime()); // Constructor performs defensive copying

  }

  private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {

    ois.defaultReadObject();

    // Perform validation if necessary

  }

}

Compliant Solution

This compliant solution creates a defensive copy of the mutable Date object date in the readObject() method. Note the use of field-by-field input and validation of incoming fields. Additionally, note that this compliant solution is insufficient to protect sensitive data (see SER03-J. Do not serialize unencrypted sensitive data for additional information).

private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {

  ObjectInputStream.GetField fields = ois.readFields();

  Date inDate = (Date) fields.get("date", epoch);

  // Defensively copy the mutable component

  date = new Date(inDate.getTime());

  // Perform validation if necessary

}

There is no need to copy immutable subobjects. Also, avoid using the subobject's clone() method because it can be overridden when the subobject's class is not final and produces only a shallow copy. The references to the subobjects themselves must be nonfinal so that defensive copying can occur. It is also inadvisable to use the writeUnshared() and readUnshared() methods as an alternative

One could craft serialized data where the object stored in the date field of the MutableSer class is a Date subclass, MutableDate, which holds a reference to the MutableSer instance (so MutableSer references MutableDate which references MutableSer). When the readObject method calls getTime() on the MutableDate class, it has a fully functional instance of the MutableSer class, with itself (a mutable date) in the date field.

As an example of how to create such serialized data and the auxiliary MutableDate:

public class CreateEvilSerializedData {

  public static void main(String[] args) throws Exception {

    MutableSer ser = new MutableSer(new Date());

         

    MutableDate mutable = new MutableDate();

    mutable.captured = ser;

    // reflection to set a desired value

    Field field = MutableSer.class.getDeclaredField("date");

    field.setAccessible(true);

    field.set(ser, mutable);

         

    FileOutputStream fos = new FileOutputStream("ser07.ser");

    ObjectOutputStream oos = new ObjectOutputStream(fos);

    oos.writeObject(ser);

    oos.close();

  }

  static class MutableDate extends Date {

    private static final long serialVersionUID = 1L;

    Object captured;

    public long getTime() {

      // at this point we have a MutableSer object that's initialized and has

      // a MutableDate as the date

      System.out.println(captured);

      super.setTime(0);

      System.out.println(captured);

      return super.getTime();

    }

  }

}

Add a comment
Know the answer?
Add Answer to:
There are two attacks documented in readObject() methods, one is called BogusPeriod, and the other is...
Your Answer:

Post as a guest

Your Name:

What's your source?

Earn Coins

Coins can be redeemed for fabulous gifts.

Not the answer you're looking for? Ask your own homework help question. Our experts will answer your question WITHIN MINUTES for Free.
Similar Homework Help Questions
  • You are to create a class called Item which contains the following private variables:  string name;  // Will...

    You are to create a class called Item which contains the following private variables:  string name;  // Will be received from files. int weight;  //random number from 1-10 The class Weapon is derived from Item.  The variable for that class is int atk;  //random number from 1-10 The class Armor is derived from Item.  The variable for that class is int def;  //random number from 1-10 You will have 2 files.  One called "Weapons.txt" which has the following: Sword Dagger Bow Lance Mace The "Armors.txt" file...

  • You are to create a class called Item which contains the following private variables:  string name;  // Will...

    You are to create a class called Item which contains the following private variables:  string name;  // Will be received from files. int weight;  //random number from 1-10 The class Weapon is derived from Item.  The variable for that class is int atk;  //random number from 1-10 The class Armor is derived from Item.  The variable for that class is int def;  //random number from 1-10 You will have 2 files.  One called "Weapons.txt" which has the following: Sword Dagger Bow Lance Mace The "Armors.txt" file...

  • •  Physical theft. Someone steals network hardware, like wires, hubs, or other equipment that keeps the network...

    •  Physical theft. Someone steals network hardware, like wires, hubs, or other equipment that keeps the network running. •  Subversion. Someone modifies or otherwise takes over part of the network so that it enables an attack. For example, an attacker might reroute traffic to allow its interception. Note that in networking, this threat involves physical or logical changes to network components. It does not involve changes to network traffic. •  Disclosure. An attacker’s computer intercepts copies of network data intended for others. While...

  • Question 2 : Virus Wars A popular subgenre of strategy game is the so-called Virus War...

    Question 2 : Virus Wars A popular subgenre of strategy game is the so-called Virus War format, where the player is shown a field of cells, each with a virus count, and may attack other cells within a certain range. We are going to write some classes in Python to implement a simple Virus Wars game. 2a) The position class (9 points) Everything within this game is going to require a position, so it makes sense to define it up...

  • Write a Java interface called Salience that includes two methods: setSalience and getSalience. The interface should...

    Write a Java interface called Salience that includes two methods: setSalience and getSalience. The interface should define a way to establish numeric salience among a set of objects. Design and implement a class called Task that represents a task (such as on a to-do list) that implements the Salience interface. Create a driver class to exercise some Task objects.

  • Write a program in python or c++ that has two functions: Function one is called: _encrypt...

    Write a program in python or c++ that has two functions: Function one is called: _encrypt Function Two is called: _decrypt Function one takes plain text ,and assesses the indexed value of each letter in the string. For example, a=1,b=2 . It then adds three to the indexed valus , and produces encrypted text , based off of the plain text. Function two reverse this. here is sample output: _encrypt(‘how do you do’) Unsecured: howdoyoudo Secured: lsahscsyhs _decrypt(‘lsahscsyhs’) Unsecured: lsahscsyhs...

  • I need java code for the following problem. Lab 7: Methods 1. Write a Java program called Numbers that calls the following methods and displays the returned value: Write a method called cubelt that a...

    I need java code for the following problem. Lab 7: Methods 1. Write a Java program called Numbers that calls the following methods and displays the returned value: Write a method called cubelt that accepts one integer parameter and returns the value raised to the third power as an integer. o Write a method called randominRange that accepts two integer parameters representing a range. The method returns a random integer in the specified range inclusive. 2. o Write a method...

  • 1) ALL IN JAVA THANK YOU Design and implement a method that invokes other methods (either...

    1) ALL IN JAVA THANK YOU Design and implement a method that invokes other methods (either predefined in the Java API, or your own helper methods). This is method decomposition. 2) Write or evaluate a comment for a method. Each method should have comments that include its purpose, description of its parameters and return (if any) including data types, and any assumptions.

  • Using Python Write the following well-documented (commented) program. Create a class called Shape that has a...

    Using Python Write the following well-documented (commented) program. Create a class called Shape that has a method for printing the area and the perimeter. Create three classes (Square, Rectangle, and Circle) which inherit from it. Square will have one instance variable for the length. Rectangle will have two instance variables for the width and height. Circle will have one instance variable for the radius. The three classes will have methods for computing the area and perimeter of its corresponding shape....

  • Programming Assignment 1 Write a class called Clock. Your class should have 3 instance variables, one...

    Programming Assignment 1 Write a class called Clock. Your class should have 3 instance variables, one for the hour, one for the minute and one for the second. Your class should have the following methods: A default constructor that takes no parameters (make sure this constructor assigns values to the instance variables) A constructor that takes 3 parameters, one for each instance variable A mutator method called setHour which takes a single integer parameter. This method sets the value of...

ADVERTISEMENT
Free Homework Help App
Download From Google Play
Scan Your Homework
to Get Instant Free Answers
Need Online Homework Help?
Ask a Question
Get Answers For Free
Most questions answered within 3 hours.
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT