Эффективный элемент Java 76: Сериализация и безопасность. Как именно хакер получает ссылки на внутренние поля Date неизменяемого объекта Period?

Хотя я понимаю общий смысл этого элемента, мне интересно понять, как именно хакер получает внутренние ссылки изменяемого объекта Period. Он искажает внутренние поля даты с помощью этих ссылок, поэтому важно понять, как именно он получает эти ссылки. Я читал и перечитывал пример и код, но не мог понять этого тонкого момента.

Блох говорит:

Можно создать изменяемый экземпляр Period, создав поток байтов, который начинается с действительного экземпляра Period, а затем добавляет дополнительные ссылки к закрытым полям Date, внутренним для экземпляра Period. Злоумышленник считывает экземпляр Period из ObjectInput-Stream, а затем считывает «мошеннические ссылки на объекты», которые были добавлены к потоку. Эти ссылки дают злоумышленнику доступ к объектам, на которые ссылаются частные поля Date в объекте Period. Изменяя эти экземпляры Date, злоумышленник может изменить экземпляр Period. Следующий класс демонстрирует эту атаку:

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);
    }
  }
}

Что здесь происходит в этой части?

/*
 * 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

И как это поможет хакеру получить ссылки?

И позже в коде, как start = (Date) in.readObject(); дает ему внутренние ссылки на создаваемый объект Period?


person Saurabh Patil    schedule 26.08.2016    source источник


Ответы (1)


Хакер использует тот факт, что он создал поток, поэтому он знает макет.

В частности, хакер знает, что 5-й объект, записываемый в поток, — это объект Date, на который ссылается Period.start, а 4-й объект — это объект Date, на который ссылается Period.end.

Сериализация Java для своих целей позволяет помещать «ссылки» в поток. В противном случае было бы невозможно сериализовать два объекта, указывающих на один и тот же объект.

Вставляя эти «ссылки» в поток (ссылки на 4-й и 5-й объекты), хакер получает доступ к экземплярам Date, хранящимся в Period.

Однако я не уверен, как хакер будет изменять эти экземпляры.

person Community    schedule 26.08.2016