dynamodb-json
dynamodb-json copied to clipboard
Automatic datetime conversion
dynamodb-json seems to automatically detect strings that look like datetimes and converts them to datetime objects.
https://github.com/Alonreznik/dynamodb-json/blob/master/dynamodb_json/json_util.py#L54
This looks dangerous to me: Imagine having a text field whose content can be freely set by the user (e.g. user biography). If the user maliciously enters the string 2017-04-22T14:41:35.780000
, it will be parsed as datetime and potentially crash the app.
In [1]: from dynamodb_json import json_util as json
In [2]: json.loads({"S": "2017-04-22T14:41:35.780000"})
Out[2]: datetime.datetime(2017, 4, 22, 14, 41, 35, 780000)
I believe an option to disable this behavior would be a good idea. What do you think?
Hi @MartinAltmayer . Thanks for the report.
First of all - a disclaimer: This is only util, which intended to be as lean as possible, and has one goal - convert between valid dict into dynamodb format json.
Regardless that the date you've added is actually a valid datetime in python, and any user input should be validation prior convert (which may make sense of other cases of security, and other applicable methods you have), the string you've added as an example actually represents a datetime, isn't it? Dynamodb doesn't have any extra type besides string (which in some cases represents something else), bytes, or number. Therefore, converting datetime automatically with a very specific and known format seems fine and something can be handled by the app, in order to make sure the dictionary gets the right data type back, and without handling any extra conversions.
However, no problem with adding an option to disable the datetime conversion. I'll pass over it and see if this is applicable to me, or you're always welcome to create a PR for that :)
Thank you Alon
For anyone else running into this problem, instead of using the dynamodb-json library you can just use boto's built-in deserializer: from boto3.dynamodb.types import TypeDeserializer
.
A simple wrapper like this then makes this whole library obsolete:
from boto3.dynamodb.types import TypeDeserializer
class App:
def __init__(self) -> None:
self._dynamo_deserializer = TypeDeserializer()
def _deserialize(self, input: Dict[str, Any]) -> Dict[str, Any]:
return {k: self._dynamo_deserializer.deserialize(v) for k, v in input.items()}