原型链污染(更新中)
python原型链污染
简介:
Python原型链污染是对类属性值的污染,且只能对类的属性来进行污染而不能够污染类的方法。
代码
1 2 3 4 5 6 7 8 9 10 11
| def merge(src, dst): for k, v in src.items(): if hasattr(dst, '__getitem__'): if dst.get(k) and type(v) == dict: merge(v, dst.get(k)) else: dst[k] = v elif hasattr(dst, k) and type(v) == dict: merge(v, getattr(dst, k)) else: setattr(dst, k, v)
|
hasatter(object,name)
两个参数,一个object
对象,另一个是字符串。如果字符串是对象的一个属性,则返回True,否则返回False。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| def merge(src, dst): """ 递归地将源字典 `src` 合并到目标对象 `dst` 中。
参数: - src (dict): 源字典,包含要合并的键值对。 - dst (object): 目标对象,可以是字典或具有属性的对象。
说明: - 如果 `dst` 是字典,则将 `src` 中的键值对合并到 `dst` 中。 - 如果 `dst` 是对象,则将 `src` 中的键值对作为属性合并到 `dst` 中。 - 如果 `src` 中的值是字典且 `dst` 中对应的值也是字典,则递归合并。 """ for k, v in src.items(): if hasattr(dst, '__getitem__'): if dst.get(k) and type(v) == dict: merge(v, dst.get(k)) else: dst[k] = v elif hasattr(dst, k) and type(v) == dict: merge(v, getattr(dst, k)) else: setattr(dst, k, v)
|
- 可以通过对
src
的控制,来实现dst
值的控制,达到污染目的。
示例用法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| dst_dict = {'a': 1, 'b': {'c': 2}} src_dict = {'b': {'d': 3}, 'e': 4} merge(src_dict, dst_dict) print(dst_dict)
class MyClass: pass
dst_obj = MyClass() dst_obj.a = 1 dst_obj.b = MyClass() dst_obj.b.c = 2
src_dict = {'b': {'d': 3}, 'e': 4} merge(src_dict, dst_obj) print(dst_obj.a) print(dst_obj.b.c) print(dst_obj.b.d) print(dst_obj.e)
|
解释:
merge
函数可以处理字典到字典的合并,也可以处理字典到对象的合并。
- 如果目标对象是字典,则直接更新字典中的键值对。
- 如果目标对象是普通对象,则将字典中的键值对作为属性设置到对象中。
- 如果遇到嵌套的字典,则会递归地进行合并。