gpt4 book ai didi

java - SerializationProxy 的字节流攻击 : is it safer?

转载 作者:行者123 更新时间:2023-12-02 00:29:20 25 4
gpt4 key购买 nike

帖子结构:

  1. 场景
  2. 问题
  3. 代码和输出
  4. 其他信息/评论

<强>1。场景鉴于我可以编辑(Serialized 类的)(私有(private)嵌套)SerializedProxy 的序列化字节流来打破 SerializedProxy 本身的不变量,因此我可以更改正在反序列化的实例。

在这种情况下,我可以访问 SerializedProxy 类的序列化形式,对正在序列化的类进行字节流攻击同样容易而无需在 readResolve() 中强制执行不变量

<强>2。问题

SerializationProxy 方法声称的安全性(针对字节流攻击)是否纯粹基于这样的假设:攻击者始终无法获得 SerializedProxy 的序列化形式或源代码的内容?如果没有,我是否误解或错过了这里的某些实现部分?

3.代码 (注意:Serializer 是一个 util 类,它将序列化对象写入文件。)

3.1 将代理序列化为值 5

    import java.io.Serializable;
import java.io.InvalidObjectException;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class SerializationProxyTest implements Serializable
{
final int id;

private SerializationProxyTest(int val)
{
id = val;
}

private void writeObject() throws InvalidObjectException, IOException
{
throw new InvalidObjectException("Invalid object called for Serialization: proxy not found.");
}


private Object writeReplace()
{
System.out.println("writeReplace 1 ");
return new SerializationProxy(this);

}

private static class SerializationProxy implements Serializable
{
final int id;

SerializationProxy(SerializationProxyTest obj)
{
this.id = obj.id;
}

/* private void writeObject(ObjectOutputStream oos) throws IOException
{

oos.defaultWriteObject();

} */

private Object readResolve()
{
System.out.println("readResolve step 1 ");
return new SerializationProxyTest(this.id);
// return "Something Else!";

}
}

public static void main(String[] args) throws IOException, ClassNotFoundException
{

Serializer.serializeObject(new SerializationProxyTest(5));

SerializationProxyTest spt = (SerializationProxyTest) Serializer.deserializeObject("/home/code/java/serialized_proxy_class.ser");

System.out.println("stored variable is: " + spt.id);
}
}

3.1输出:

   [java]$ java SerializationProxyTest
writeReplace 1
readResolve 1
object is: SerializationProxyTest@4eec7777
stored variable is: 5

aced 0005 7372 0029 5365 7269 616c 697a 6174 696f 6e50 726f 7879 5465 7374 2453 6572 6961 6c69 7a61 7469 6f6e 5072 6f78 793b 8ab7 89f9 dd6d aa02 0001 4900 0269 6478 7000 0000 05

3.2 更改序列化的 SerializedProxy 将变量的值更改为 6

aced 0005 7372 0029 5365 7269 616c 697a 6174 696f 6e50 726f 7879 5465 7374 2453 6572 6961 6c69 7a61 7469 6f6e 5072 6f78 793b 8ab7 89f9 dd6d aa02 0001 4900 0269 6478 7000 0000 06

3.3 通过反序列化来初始化 Serialized 类更改的 SerializedProxy:SerializationProxyTest 类使用 6 而不是 5 进行初始化。

                SerializationProxyTest spt = (SerializationProxyTest) Serializer.deserializeObject("/home/code/java/serialized_proxy_class.ser");

System.out.println("stored variable is: " + spt.id);

[java]$ java SerializationProxyTest
writeReplace 1
readResolve 1
object is: SerializationProxyTest@4eec7777
stored variable is: 6

4.附加信息/注释:SerializedProxy 方法的某些固有“安全性”的假设只是阅读“Effective Java”时产生的好奇心。这里做出的另一个假设是,即使不了解类结构,攻击者也可以通过反复试验对字节流进行有效的更改。

最佳答案

反序列化时,串行代理必须强制执行与构造函数相同的不变量(或者静态创建方法的不变量,如果您要走这条路线)。这通常是通过串行代理使用公共(public)构造函数(或方法)创建真实对象来实现的。

在问题的代码中,id 始终为 5 的不变量存在于静态创建方法 (main) 中。串行代理代码不使用它。

注意:您的 SerializationProxyTest 是可子类化的。 Java 字节码不要求类具有构造函数,因此基类不需要具有可访问的构造函数。一般来说,您的类的任何非最终公共(public)或 protected 方法都可以被重写。

另请注意,《Effective Java》第 3 版的序列化章节中有更正 - 不要使用早期版本。

关于java - SerializationProxy 的字节流攻击 : is it safer?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58028028/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com