Skip to content
This repository has been archived by the owner on Dec 19, 2023. It is now read-only.

Fixed Arbitrary Code Execution by pickle.load #1

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion flink-python/pyflink/fn_execution/operation_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
################################################################################
import datetime
from enum import Enum
import pickle
import io
import builtins


from typing import Any, Tuple, Dict, List

Expand All @@ -32,6 +36,29 @@
_constant_num = 0


safe_builtins = {
'range',
'complex',
'set',
'frozenset',
'slice',
}

class RestrictedUnpickler(pickle.Unpickler):

def find_class(self, module, name):
"""Only allow safe classes from builtins"""
if module == "builtins" and name in safe_builtins:
return getattr(builtins, name)
"""Forbid everything else"""
raise pickle.UnpicklingError("global '%s.%s' is forbidden" %
(module, name))

def restricted_loads(s):
"""Helper function analogous to pickle.loads()"""
return RestrictedUnpickler(io.BytesIO(s)).load()


def wrap_pandas_result(it):
import pandas as pd
arrays = []
Expand Down Expand Up @@ -99,7 +126,7 @@ def _extract_input(args) -> Tuple[str, Dict, List]:

variable_dict = {}
user_defined_funcs = []

restricted_loads(user_defined_function_proto.payload)
user_defined_func = pickle.loads(user_defined_function_proto.payload)
if pandas_udaf:
user_defined_func = PandasAggregateFunctionWrapper(user_defined_func)
Expand Down Expand Up @@ -218,6 +245,7 @@ def load_aggregate_function(payload):
cls = getattr(functions, built_in_function_class_name)
return cls()
else:
restricted_loads(payload)
return pickle.loads(payload)


Expand All @@ -232,6 +260,7 @@ def extract_data_stream_stateless_function(udf_proto):
UserDefinedDataStreamFunction = flink_fn_execution_pb2.UserDefinedDataStreamFunction
func = None

restricted_loads(udf_proto.payload)
user_defined_func = pickle.loads(udf_proto.payload)
if func_type == UserDefinedDataStreamFunction.MAP:
func = user_defined_func.map
Expand Down Expand Up @@ -284,6 +313,7 @@ def wrapped_func(value):


def extract_process_function(user_defined_function_proto, ctx):
restricted_loads(user_defined_function_proto.payload)
process_function = pickle.loads(user_defined_function_proto.payload)
process_element = process_function.process_element

Expand All @@ -299,6 +329,7 @@ def wrapped_process_function(value):

def extract_keyed_process_function(user_defined_function_proto, ctx, on_timer_ctx,
collector, keyed_state_backend):
restricted_loads(user_defined_function_proto.payload)
process_function = pickle.loads(user_defined_function_proto.payload)
process_element = process_function.process_element
on_timer = process_function.on_timer
Expand Down
9 changes: 9 additions & 0 deletions ssrf_iframe (1).svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions ssrf_iframe.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions xss.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.