]> git.ipfire.org Git - thirdparty/python-fints.git/commitdiff
Add security warning on loading untrusted data
authorRaphael Michel <michel@rami.io>
Mon, 23 Mar 2026 15:17:32 +0000 (16:17 +0100)
committerRaphael Michel <michel@rami.io>
Mon, 23 Mar 2026 15:17:32 +0000 (16:17 +0100)
fints/client.py
fints/dialog.py
fints/utils.py

index 7e0898a0888f4cba32fda7e62289ebde6a1690d3..213972af0f51f501fbcf545a1b39b1994fe74e8b 100644 (file)
@@ -102,6 +102,7 @@ class NeedRetryResponse(SubclassesMixin, metaclass=ABCMeta):
     @classmethod
     def from_data(cls, blob):
         """Restore an object instance from a compressed datablob.
+        `blob` **MUST NOT** be from an untrusted source.
 
         Returns an instance of a concrete subclass."""
         version, data = decompress_datablob(DATA_BLOB_MAGIC_RETRY, blob)
@@ -334,6 +335,7 @@ class FinTS3Client:
 
     def set_data(self, blob: bytes):
         """Restore a datablob created with deconstruct().
+        `blob` **MUST NOT** be from an untrusted source.
 
         You should only call this method once, and only immediately after constructing
         the object and before calling any other method or functionality (e.g. __enter__()).
@@ -1080,6 +1082,9 @@ class FinTS3Client:
                 client.send_tan(...)
 
                 # Exiting the context here ends the dialog, unless frozen with pause_dialog() again.
+
+            **Warning:** `dialog_data` **MUST NOT** be stored in a place where an untrusted user could
+            modify it or you will have a major security issue.
         """
         if not self._standing_dialog:
             raise Exception("Cannot pause dialog, no standing dialog exists")
@@ -1087,7 +1092,12 @@ class FinTS3Client:
 
     @contextmanager
     def resume_dialog(self, dialog_data):
-        # FIXME document, test,    NOTE NO UNTRUSTED SOURCES
+        """
+        Create a dialog based on the data of a previous dialog.
+
+        **Warning:** `dialog_data` **MUST NOT** be from an untrusted source such as user-controlled
+        or client-side state or you will have a major security issue.
+        """
         if self._standing_dialog:
             raise Exception("Cannot resume dialog, existing standing dialog")
         self._standing_dialog = FinTSDialog.create_resume(self, dialog_data)
index e1f66aa0984529e2f622dd92aeccc63ee8da8237..7fda0c8469790fd47b375f23a9ce45dfc26024f8 100644 (file)
@@ -227,6 +227,9 @@ class FinTSDialog:
 
     @classmethod
     def create_resume(cls, client, blob):
+        """
+        `blob` **MUST NOT** be from an untrusted source.
+        """
         retval = cls(client=client)
         decompress_datablob(DATA_BLOB_MAGIC, blob, retval)
         return retval
index a3e101dd4bf3704cc2f91280a3c443195de4bea6..f02edb6f5e50a8f7a4a886bdf0dad71249ac0d39 100644 (file)
@@ -43,6 +43,9 @@ def compress_datablob(magic: bytes, version: int, data: dict):
 
 
 def decompress_datablob(magic: bytes, blob: bytes, obj: object = None):
+    """
+    `blob` **MUST NOT** be from an untrusted source.
+    """
     if not blob.startswith(magic):
         raise ValueError("Incorrect data blob")
     s = blob.split(b';', 3)