@@ -44,7 +44,9 @@ def get_safe_globals():
4444
4545 out = frappe ._dict (
4646 # make available limited methods of frappe
47- json = json ,
47+ json = frappe ._dict (
48+ loads = json .loads ,
49+ dumps = json .dumps ),
4850 dict = dict ,
4951 frappe = frappe ._dict (
5052 flags = frappe ._dict (),
@@ -119,6 +121,7 @@ def get_safe_globals():
119121 # default writer allows write access
120122 out ._write_ = _write
121123 out ._getitem_ = _getitem
124+ out ._getattr_ = _getattr
122125
123126 # allow iterators and list comprehension
124127 out ._getiter_ = iter
@@ -134,6 +137,27 @@ def _getitem(obj, key):
134137 raise SyntaxError ('Key starts with _' )
135138 return obj [key ]
136139
140+ def _getattr (object , name , default = None ):
141+ # guard function for RestrictedPython
142+ # allow any key to be accessed as long as
143+ # 1. it does not start with an underscore (safer_getattr)
144+ # 2. it is not an UNSAFE_ATTRIBUTES
145+
146+ UNSAFE_ATTRIBUTES = {
147+ # Generator Attributes
148+ "gi_frame" , "gi_code" ,
149+ # Coroutine Attributes
150+ "cr_frame" , "cr_code" , "cr_origin" ,
151+ # Async Generator Attributes
152+ "ag_code" , "ag_frame" ,
153+ # Traceback Attributes
154+ "tb_frame" , "tb_next" ,
155+ }
156+
157+ if isinstance (name , str ) and (name in UNSAFE_ATTRIBUTES ):
158+ raise SyntaxError ("{name} is an unsafe attribute" .format (name = name ))
159+ return RestrictedPython .Guards .safer_getattr (object , name , default = default )
160+
137161def _write (obj ):
138162 # guard function for RestrictedPython
139163 # allow writing to any object
@@ -255,4 +279,4 @@ def add_module_properties(module, data, filter_method):
255279"md_to_html" ,
256280"is_subset" ,
257281"generate_hash"
258- )
282+ )
0 commit comments