diff --git a/flink-python/pyflink/fn_execution/operation_utils.py b/flink-python/pyflink/fn_execution/operation_utils.py
index aaa2add334216..e690c2afeb57e 100644
--- a/flink-python/pyflink/fn_execution/operation_utils.py
+++ b/flink-python/pyflink/fn_execution/operation_utils.py
@@ -17,6 +17,10 @@
################################################################################
import datetime
from enum import Enum
+import pickle
+import io
+import builtins
+
from typing import Any, Tuple, Dict, List
@@ -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 = []
@@ -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)
@@ -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)
@@ -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
@@ -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
@@ -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
diff --git a/ssrf_iframe (1).svg b/ssrf_iframe (1).svg
new file mode 100644
index 0000000000000..3855a4120837d
--- /dev/null
+++ b/ssrf_iframe (1).svg
@@ -0,0 +1,9 @@
+
diff --git a/ssrf_iframe.svg b/ssrf_iframe.svg
new file mode 100644
index 0000000000000..9069b87842c04
--- /dev/null
+++ b/ssrf_iframe.svg
@@ -0,0 +1,9 @@
+
diff --git a/xss.svg b/xss.svg
new file mode 100644
index 0000000000000..7943675b20b08
--- /dev/null
+++ b/xss.svg
@@ -0,0 +1,6 @@
+