Follow up: there are no enumerated instance controls in Java

This is a follow-up to this question Is this solution waterproof?

public final class Thing implements Serializable {

    private static final long serialVersionUID = 1L;

    private static final Thing[] instances = new Thing[2];
    private static int nextOrdinal = 0;

    public static final Thing instance0 = new Thing("whatever0");
    public static final Thing instance1 = new Thing("whatever1");

    private transient final String someState;

    public String someMethod() {return someState;}

    private final int ordinal;

    private Thing(String someState) {
        this.someState = someState;
        this.ordinal = nextOrdinaL++;
        instances[this.ordinal] = this;
    }

    private Object readResolve() throws ObjectStreamException {
        return instances[this.ordinal];
    }
}

Solution

no (although it may be sufficient, it depends on how and where the code is used.)

In item 77: for instance control, the preferred enumeration type is readresolve (effective Java, 2nd ed). Bloch demonstrates how an attacker can have a class like you to return any value The attack relies on hand-made byte input and can run code on the target (therefore, if used in a sandbox environment, some RMI situations, etc., the code may be at security risk) I don't know if this is the only attack - it's the only attack mentioned The solution is to declare that all fields are transient, but you encounter the problem of how to store values

You can use the serialized proxy pattern to solve these problems (item 78 in the book – why every java programmer reading it recommends it)

public final class Thing implements Serializable {
  private static final long serialVersionUID = 1L;
  private static final Thing[] INSTANCES = new Thing[2];
  private static int NEXT_ORDINAL = 0;

  public static final Thing INSTANCE0 = new Thing(
      "whatever0");
  public static final Thing INSTANCE1 = new Thing(
      "whatever1");

  private transient final String someState;

  public String someMethod() {
    return someState;
  }

  private final int ordinal;

  private Thing(String someState) {
    this.someState = someState;
    ordinal = NEXT_ORDINAL++;
    INSTANCES[ordinal] = this;
  }

  private Object writeReplace() {
    return new ThingProxy(this);
  }

  private void readObject(ObjectInputStream stream)
      throws InvalidObjectException {
    throw new InvalidObjectException("Proxy required");
  }

  private static class ThingProxy implements Serializable {
    private static final long serialVersionUID = 1L;
    private final int ordinal;

    private ThingProxy(Thing t) {
      ordinal = t.ordinal;
    }

    private Object readResolve()
        throws ObjectStreamException {
      return INSTANCES[ordinal];
    }

  }

}

Although it is the same as copying any Internet related security, it needs attention I am by no means an expert

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>