PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Aggiornamento del campo json in Postgres

Nessun eval è obbligatorio. Il tuo problema è che non stai decodificando il valore come oggetto 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)

Non solo, ma usando eval per decodificare json è pericoloso e inaffidabile. Non è affidabile perché json non è Python, capita solo di valutare un po' come se la maggior parte delle volte. Non è sicuro perché non sai mai cosa potresti valutare. In questo caso sei ampiamente protetto dal parser json di 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__...

... ma non sarò affatto sorpreso se qualcuno riesce a inserire un eval sfruttare oltre. Quindi la lezione qui:non usare eval .