feat: Use random filename suffixes for blobstorage (#4309)

Recently there was an accident with a chatbot that replaced its avatar set from the command line
with an unrelated avatar of a contact. Both the `selfavatar` setting and the contact avatar `i`
param pointed to `$BLOBDIR/avatar.png` at the time it was detected. How this happened is unclear,
but it is possible that `avatar.png` was removed, unmounted or otherwise not detected by the core,
and the core stored avatar received from the contact as `avatar.png`, while `selfavatar` config
still pointed to `$BLOBDIR/avatar.png`.

Such bugs are unavoidable even if the core itself has no bugs as we cannot rely on blobdir not
reside on the faulty network filesystem, being incorrectly backed up and restored etc., so we should
assume that files may be randomly removed. Then there may be dangling `$BLOBDIR/...` references in
the database which may accidentally point to unrelated files, could even be an `avatar.png` file
sent to the bot in private.

To prevent such bugs, we add random filename suffixes for the blobdir objects. Thanks to the added
Param::Filename these random suffixes aren't sent over the network.
This commit is contained in:
iequidoo
2023-07-25 20:37:48 -03:00
parent 5c0ab4b7a9
commit 7358c33e45
8 changed files with 119 additions and 97 deletions

View File

@@ -50,8 +50,8 @@ class TestOnlineInCreation:
src = tmp_path / "file.txt"
src.write_text("hello there\n")
msg = chat.send_file(str(src))
assert msg.filename.startswith(os.path.join(ac1.get_blobdir(), "file"))
assert msg.filename.endswith(".txt")
assert msg.file_path.startswith(os.path.join(ac1.get_blobdir(), "file"))
assert msg.file_path.endswith(".txt")
def test_forward_increation(self, acfactory, data, lp):
ac1, ac2 = acfactory.get_online_accounts(2)
@@ -99,9 +99,9 @@ class TestOnlineInCreation:
lp.sec("wait1 for original or forwarded messages to arrive")
received_original = ac2._evtracker.wait_next_incoming_message()
assert cmp(received_original.filename, orig, shallow=False)
assert cmp(received_original.file_path, orig, shallow=False)
lp.sec("wait2 for original or forwarded messages to arrive")
received_copy = ac2._evtracker.wait_next_incoming_message()
assert received_copy.id != received_original.id
assert cmp(received_copy.filename, orig, shallow=False)
assert cmp(received_copy.file_path, orig, shallow=False)