PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Aktualisieren des JSON-Felds in Postgres

Kein eval ist nötig. Ihr Problem ist, dass Sie den Wert nicht als JSON-Objekt decodieren.

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)

Nicht nur das, sondern auch die Verwendung von eval um json zu decodieren ist gefährlich und unzuverlässig. Es ist unzuverlässig, weil json ist nicht Python, es wird einfach die meiste Zeit ein bisschen so ausgewertet. Es ist unsicher, weil man nie weiß, was man auswertet. In diesem Fall sind Sie weitgehend durch den json-Parser von PostgreSQL geschützt:

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__...

... aber es würde mich nicht wundern, wenn jemand einen eval unterschieben kann darüber hinaus ausnutzen. Die Lektion hier also:Verwenden Sie nicht eval .