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
.