Java 为什么在反序列化中不使用反射可能导致远程代码执行?

Java 为什么在反序列化中不使用反射可能导致远程代码执行?,java,.net,reflection,deserialization,setter,Java,.net,Reflection,Deserialization,Setter,我在blackhat的“json攻击”谈话中读到,当使用反序列化库时,它可能会使用反射(“使用反射填充所有字段或属性成员”)或setter来构造对象。根据谈话,使用反射并不危险(也不会直接导致远程代码执行),因为它不会调用任何方法 这让我对一件事感到好奇: 为什么使用反射不危险?(因为它最终也构造了一个对象。在我看来,它和使用setter一样) 谢谢使用反射虽然比setters慢,但可以确保唯一的操作是更改字段。我们无法确保setter实现这一点,因为它们的代码可能与设置值不同。这种形式的语句存

我在blackhat的“json攻击”谈话中读到,当使用反序列化库时,它可能会使用反射(“使用反射填充所有字段或属性成员”)或setter来构造对象。根据谈话,使用反射并不危险(也不会直接导致远程代码执行),因为它不会调用任何方法

这让我对一件事感到好奇:

为什么使用反射不危险?(因为它最终也构造了一个对象。在我看来,它和使用setter一样)


谢谢

使用反射虽然比setters慢,但可以确保唯一的操作是更改字段。我们无法确保setter实现这一点,因为它们的代码可能与设置值不同。

这种形式的语句存在根本性问题

首先,“使用反射”一词毫无意义,因为它不能说明使用了什么反射

您可以使用反射来创建对象,使用反射来设置字段,或者使用反射来调用方法。只有在用于设置字段时,才可以安全地假定它不会调用未知代码

但是,您想知道为什么在这里忽略对象的构造是对的。如果允许外部文件(如json)的内容驱动任意类的实例化,那么执行它们的构造函数就已经很危险了。但是,如果应用程序告诉库要实例化哪些类型,而不允许其他类型,这并不罕见

但是,如果我们事先知道哪些类型可以实例化,并且这些类型是安全可靠的,那么我们就不清楚为什么应该不信任它们的setter方法。事实上,setter方法可以验证输入并防止非法状态,而通过反射设置字段将绕过它,并可能创建否则不可能的结果

这甚至不一定是故意的攻击。一个类可能使用了不同的内部状态,但仍然提供了向后兼容的API,包括setter方法。因此,使用反射直接设置字段可能会造成危害,因为使用专用的setter方法将完美地工作


简而言之,外部输入必须经过验证,无论您使用什么方法来处理它。

请阅读:我明白了,所以它取决于对象本身的setter