Security holes : messages not deleted in the database and the server

I’m very disappointed, Delta Chat seems to have been created by people who don’t know anything about security. In 30 minutes of testing I found security holes that should never be there.

**1-**When deleting a conversation, the messages still remain on the mail server (test carried out on an Android phone and a Windows desktop). On the two mailboxes ( server for both) the messages are not deleted on the server.

**2-**When deleting a conversation in Delta Chat Android or Delta Chat Windows, the messages are marked as deleted in the database (qb.sqlite on windows) but a simple hexadecimal search shows that they are still in the database . They can be recovered. The PRAGMA secure delete direction is not even enabled in the code.
In addition, the VACUUM sqlite command to purge the database is not even executed when launching the Windows or Android application.

**3-**The database on the phone or Desktop is not even encrypted with a user password and the option does not exist.
If someone has access to the phone or the computer they can retrieve all the messages.
In addition, the password for the mailboxes is written in clear in the database.
The thief will therefore no longer have access to the entire email box.
It really sucks as a security!

1 Like

This is by design, deleting a chats deletes messages locally, not remotely. Deleting individual messages schedules a job to delete them remotely too. I am not sure right now why this is the case, but changing it will probably cause problems with users using another client side-by-side with DC and having all messages to a particular user deleted is probably not expected when you delete a conversation with a contact.

Edit: also note that in multi-device setup the conversation will not be deleted from your other device. And your server (most likely Dovecot) will by no means securely delete the messages, it will do it in the fastest way possible.

PRAGMA secure_delete=on is enabled here:

If it does not work for some reason it is a bug indeed. I have just checked my account database with a command-line tool and it says secure_delete PRAGMA is enabled.

$ sqlite3 ac0/db.sqlite 'pragma secure_delete'

Note that messages are stored in “blobs” outside the database, so secure_delete is not protecting outgoing message contents from being persisted to disk (if they are encrypted, they are stored in encrypted form though), and may not even protect the database for some filesystems. The only bulletproof solution I see is to always use full disk encryption provided by your operating system.

Edit: even the page you linked to says the same: “Be aware that SQLite cannot securely delete information from the underlying storage device. If the write operation causes the filesystem to allocate a new device-level block, the old data may still exist on the raw device.”. Storage encryption is better done at the operating system level.

VACUUM is executed periodically during “housekeeping” job.

See related feature request about local encryption:

Encrypting the database makes some sense if you store everything in the database and want to have encrypted backups, you can simply re-encrypt the key with a new passphrase and copy the rest of the database. But it does not make the data on device more secure unless you keep asking the user for passphrase each time and user actually uses secure passphrase. It’s not really usable, this is why I think it’s not available in Signal, but only in Signal fork Molly. So I think we should encourage users to use filesystem-level encryption rather than trying to implement local encryption into the core.

1 Like

I just tested, messages are actually deleted from the database. strings -a db.sqlite | grep message_contents does not show the message after deleting a conversation, stopping the app and starting it again.

The reason message deletion is not applied immediately is that DELETE command is stored into file db.sqlite-wal which is only applied to the database eventually, but not immediately after deleting the conversation. When WAL is actually applied to the database (triggered by restarting the app, but this will happen eventually anyway as WAL size is limited), plaintext message contents is not in the file anymore.


It is nice to see a response like this, with so much respect for a user that it is clearly seen that their intention is more, to criticize and judge the work and effort of others, than to help and improve the development of the project.


You are right!
The fool he made is colossal, he criticizes without having read the code! :joy::rofl:
If he had been more humble and asked for information, he would have avoided making a fool of himself :rofl:

I can put up with a harsh tone of the original message and don’t expect users to read the code.

Double-checking that secure deletion still works after recent attempts to move to sqlx implementation of SQLite interface and following refactoring was not a bad idea, would be bad if it was broken in the process.

First “issue” is not a security issue from my point of view and I have no idea if users expect messages to be deleted on the server. It is easy to make “delete chat” to also delete messages, but it is a destructive operation and it’s very likely other users will complain then they clicked a single button and DC deleted months of backlog from the server.

As for third point, I still think local encryption is not worth it and should be done on the operating system level. However, there is a relevant issue about encrypting backups:

As over-the-network secure transfer is planned but not implemented yet (only the first step of moving to streamable tar backup format is done) and may not work when your devices use different networks, such as your local LAN, cellular network, VPNs etc., I think it’s important to have encrypted backups.


when a chat is deleted on a device, why not to ask the user confirmation for deletion on the server?
“deleted all theses messages on the server yes/no?”

why not allow optional encryption of the database with a password at startup.
the user must activate the database encryption by setting up a password in options

having all messages to a particular user deleted is probably not expected when you delete a conversation with a contact.

Could you explain why?
when you delete a chat, you except the messges will be deleted locally and on the server too.
what is the purpose of keeping encrypted messages on the imap server, messages that will never be used for anything again ?

Delta Chat has an option of showing classical emails, so you can use it as an email client, for example to receive mailing lists and newsletters. Enhancements to this mode have been the focus of the latest releases: E-mail compatibility releases - Delta Chat

If you start running out of space on the phone, you might want to delete an archive of some newsletter on your phone, but still refer to it from web interface or classical mail client such as Thunderbird later. To do it, you delete the mailing list chat on your phone. If you didn’t expect that it will delete the whole archive of newsletter on the server, there is now no way to recover it.