Tidak ada eval Dibutuhkan. Masalah Anda adalah Anda tidak mendekode nilai sebagai objek json.
CREATE OR REPLACE FUNCTION json_update(data json, key text, value json)
RETURNS json AS
$BODY$
from json import loads, dumps
if key is None: return data
js = loads(data)
# you must decode 'value' with loads too:
js[key] = loads(value)
return dumps(js)
$BODY$
LANGUAGE plpythonu VOLATILE;
postgres=# SELECT json_update('{"a":1}', 'a', '{"innerkey":"innervalue"}');
json_update
-----------------------------------
{"a": {"innerkey": "innervalue"}}
(1 row)
Tidak hanya itu, tetapi menggunakan eval untuk memecahkan kode json berbahaya dan tidak dapat diandalkan. Tidak dapat diandalkan karena json bukan Python, itu hanya terjadi untuk mengevaluasi sedikit seperti itu hampir sepanjang waktu. Ini tidak aman karena Anda tidak pernah tahu apa yang mungkin Anda evaluasi. Dalam hal ini Anda sebagian besar dilindungi oleh parser json PostgreSQL:
postgres=# SELECT json_update(
postgres(# '{"a":1}',
postgres(# 'a',
postgres(# '__import__(''shutil'').rmtree(''/glad_this_is_not_just_root'')'
postgres(# );
ERROR: invalid input syntax for type json
LINE 4: '__import__(''shutil'').rmtree(''/glad_this_is_not_...
^
DETAIL: Token "__import__" is invalid.
CONTEXT: JSON data, line 1: __import__...
... tapi saya sama sekali tidak terkejut jika seseorang dapat menyelipkan eval mengeksploitasi melewati itu. Jadi pelajarannya di sini:jangan gunakan eval .