From e2c1a23be25795d98b65fb4d89a731df82a865c8 Mon Sep 17 00:00:00 2001 From: lik <1178981326@qq.com> Date: Mon, 21 Oct 2019 21:29:20 +0800 Subject: [PATCH] =?UTF-8?q?Update=2088=20=E5=81=9A=E6=B3=95=E4=BA=8B=20->?= =?UTF-8?q?=20=E5=81=9A=E6=B3=95=E6=98=AF=20=EF=BC=9B=20=E5=A6=82=E6=9E=9C?= =?UTF-8?q?=E5=AE=83=E5=A5=BD=E6=B1=89=E4=BA=86=E7=A7=81=E6=9C=89=E7=9A=84?= =?UTF-8?q?=E5=8F=AF=E5=8F=98=E5=AD=97=E6=AE=B5=20->=20=E5=A6=82=E6=9E=9C?= =?UTF-8?q?=E5=AE=83=E5=8C=85=E5=90=AB=E4=BA=86=E7=A7=81=E6=9C=89=E7=9A=84?= =?UTF-8?q?=E5=8F=AF=E5=8F=98=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/notes/88. 保护性的编写 readObject 方法.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/notes/88. 保护性的编写 readObject 方法.md b/docs/notes/88. 保护性的编写 readObject 方法.md index 23c2fb3..b7b5c7b 100644 --- a/docs/notes/88. 保护性的编写 readObject 方法.md +++ b/docs/notes/88. 保护性的编写 readObject 方法.md @@ -91,7 +91,7 @@ private void readObject(ObjectInputStream s) } ``` -  尽管这样的修成避免了攻击者创建无效的 `Period` 实例,但是这里依旧隐藏着一个更为微妙的问题。通过伪造字节流,要想创建可变的 `Period` 实例仍是有可能的,做法事:字节流以一个有效的 `Period` 实例开头,然后附加上两个额外的引用,指向 `Period` 实例中两个私有的 `Date` 字段。攻击者从 `ObjectInputStream` 读取 `Period` 实例,然后读取附加在其后面的「恶意编制的对线引用」。这些对象引用使得攻击者能够访问到 `Period` 对象内部的私有 `Date` 字段所引用的对象。通过改变这些 `Date` 实例,攻击者可以改变 `Period` 实例。如下的类演示了这种攻击方式: +  尽管这样的修成避免了攻击者创建无效的 `Period` 实例,但是这里依旧隐藏着一个更为微妙的问题。通过伪造字节流,要想创建可变的 `Period` 实例仍是有可能的,做法是:字节流以一个有效的 `Period` 实例开头,然后附加上两个额外的引用,指向 `Period` 实例中两个私有的 `Date` 字段。攻击者从 `ObjectInputStream` 读取 `Period` 实例,然后读取附加在其后面的「恶意编制的对线引用」。这些对象引用使得攻击者能够访问到 `Period` 对象内部的私有 `Date` 字段所引用的对象。通过改变这些 `Date` 实例,攻击者可以改变 `Period` 实例。如下的类演示了这种攻击方式:   ```java public class MutablePeriod { @@ -162,7 +162,7 @@ Wed Nov 22 00:21:29 PST 2017 - Sat Nov 22 00:21:29 PST 1969   虽然 Period 实例被创建之后,他的约束条件没有被破坏。但是要随意修改它的内部组件仍然是有可能的。一旦攻击者获得了一个可变的 `Period` 实例,就可以将这个实例传递给一个「安全性依赖于 Period 的不可变性」的类,从而造成更大的危害。这种推断并不牵强:实际上,有许多类的安全性就是依赖于 String 的不可变性。 -  问题的根源在于,`Period` 的 `readObject` 方法并没有完成足够的保护性拷贝。 **当一个对象被反序列化的时候,对于客户端不应该拥有的对象引用,如果那个字段包含了这样的对象引用,就必须做保护性拷贝,这是非常重要的。** 因此,对于每个可序列化的不可变类,如果它好汉了私有的可变字段,那么在它的 `readObject` 方法中,必须要对这些字段进行保护性拷贝。下面的这些 `readObject` 方法可以确保 `Period` 类的约束条件不会遭到破坏,以保持它的不可变性: +  问题的根源在于,`Period` 的 `readObject` 方法并没有完成足够的保护性拷贝。 **当一个对象被反序列化的时候,对于客户端不应该拥有的对象引用,如果那个字段包含了这样的对象引用,就必须做保护性拷贝,这是非常重要的。** 因此,对于每个可序列化的不可变类,如果它包含了私有的可变字段,那么在它的 `readObject` 方法中,必须要对这些字段进行保护性拷贝。下面的这些 `readObject` 方法可以确保 `Period` 类的约束条件不会遭到破坏,以保持它的不可变性: ```java // readObject method with defensive copying and validity checking