Privatebin: Self-destroying mechanism can be circumvented

Created on 6 Feb 2017  Â·  16Comments  Â·  Source: PrivateBin/PrivateBin

From https://github.com/PrivateBin/PrivateBin/issues/156#issuecomment-270299282 I can conclude the self-destroying mechanism ("burn after reading") is only triggered via JS after the decryption. This is good to prevent false-positive destroying of the pastes, however it also makes the whole self-destroy mechanism somewhat senseless.

So let's take a threat model here: Alice wants to send a paste via Skype to Bob. Mallory (name him Skype or so 😆) is known for intercepting and clicking links - for link preview purposes as he/they says/say, but he/it could do anything.
Alice is aware of this and thus chooses to sent self-destroying pastes, so that - as she thinks - the paste is either deleted upon the first visit of Mallory (so that Bob would notice this and could alarm you) or Bob can decrypt and receive it without any problems.

To understand the attack better, let's assume Mallory is a person (not a bot), which forwards the messages. This is how he can circumvent the whole self-destroy mechanism:

  1. Alice sends the message, naturally it includes the decryption key in the #hash
  2. Mallory assumes that it is a self-destroyable message, cURLs the URL, but does not yet do anything with it
  3. Mallory forwards the message to Bob
  4. Bob successfully opens and decrypts the message in it's browser, afterwards it is deleted
  5. Mallory can now decrypt the message (he's got the cyphertext - from CURL - and the key - from the hash) without letting anyone know that he intercepted it. Either Mallory uses an offline browser (e.g.) or just a custom decryption script.

Result: Bob & Alice both think the message was transferred securely and nobody intercepted it. They can even assure that Bob read it and it was really self-destroyed by clicking the link again. (It should return an error.)
In fact, however, Mallory intercepted and decrypted the message secretly.


Certainly this is not good and I can image no other threat model, for which you would need the "destroy after reading" feature. If you can imagine another one, please comment.

So how can be fix it?

  • 1: We could just revert https://github.com/elrido/ZeroBin/issues/11. However this could of course made bots (aka Chuck, without any malicious intent) to destroy the pastes before reading.
  • 2: We could do 1, but use leave it optional. I'd really don't like this as we should provide security by default and web admins should not have to enable an option to provide a protection against a basic threat model.
  • 3: Just as OneTimeSecret does it, we could show a button the user has to press ("Show paste") before the actual cyphertext is downloaded. And when it is downloaded it must be immediately removed from the server.
  • 4: Remove "burn after reading" entirely as it is insecure (I'd rather avoid this 😑)
  • x: No other idea… Anyone has one?

As for 3 we would basically use https://privatebin.net/?5fb735cb0d412320#tw…= as it is, but with https://github.com/elrido/ZeroBin/issues/11 reverted by auto-deleting an paste after receiving it. Then we could e.g. use https://privatebin.net/?button&5fb735cb0d412320#tw…=, which would only show a button for the user. When clicked, it redirects the user to https://privatebin.net/?5fb735cb0d412320#tw…=.

Or, we could of course also "trigger" the button automatically, so that the actual ciphertext (which is currently included in the HTML as cipherdata) is just loaded via JS directly after the site is loaded. As bots hopefully won't execute JavaScript we should be on the save side. (I hope…)
Actually this would also solve https://github.com/PrivateBin/PrivateBin/issues/159. 😀

EDIT: made public, 2017-02-07

bug securitprivacy

Most helpful comment

As a short term measure I will implement an option to choose the behaviour in the server configuration. But for a final solution the password dialog needs to be changed, so that users get a chance to type in another password if the accidentally mistyped. With the current behaviour the paste could not be reloaded when one would revert to the server side deletion. I'll leave that part to @rugk who is more JS-versed then me.

All 16 comments

It is absolutely no secret, that if any malicious attacker has access to key (the hash part of the URL) then he/she/it can decrypt the content (its the second bullet point in our main readme in the "what it doesn't provide" part). It is up to the user to chose a safe way to share the paste URL in a fashion that it won't be intercepted by any malicious attacker. We do advise to use a password for added protection, which voids this scenario if the password is shared on a secondary communication channel.

Hence you might not want to send your URL via Skype, burn-after-reading or not. This "problem" is a general problem that isn't solved by PrivateBin at all. PrivateBin mainly aims to provide server admins a tool for them to plausibly deny any knowledge of (possibly illegal) contents of the pastes or the discussions.

IMHO this is not a vulnerability. If at all, we need to better clarify this point in the README or add a warning before or below any generated paste URL, as it seems imperative for how one would use the generated paste URLs.

Yes, all things you talk about of course apply, but again extend the thread model. Maybe I forgot some things to mention. So 1. We trust the server (maybe self hosted, e.g.) 2. The two partners cannot exchange a password. 3. Forget all the encryption. It does not matter here.

So the only way for the ones is to use the "burn after reading" option. But with this vulnerability here for an attacker it does not make any difference whether the user uses this feature or not. That is what I mean with it does not work as expected, it basically does not work at all if it can be circumvented.

Now please read the thread model description again, I gave above.

This leaves us with only two secure options:

  • Remove the feature entirely as it provides no security (maybe only a false sense of security, which is way worse!) OR
  • Fix it (I've proposed some ideas how to do so in the first post)

So what would you rather do? Fix a feature so it works as expected or remove it?

Only clarifying this in the Readme would make no sense, as we would have to write: "Hey, we support this feature - you can see it in the UI - but it is useless as it does not work and an attacker can circumvent it."
That's not acceptable at all, because it basically means: "Hey this is vulnerable (meaning: we could actually fix it, but we did not care…), but we let users their false sense of security?"

To shorten this whole thing: If you take the behaviour I described in the first post here as expected, why should one use the "burn after reading" option? What sense would this option make?

I still do not see how this is a new scenario. If you share the paste URL with hash (the key of the paste) and don't additionally set a password, any service you use to share the URL over (email provider, chat (app) provider, etc.) can decrypt your paste.

If you want to protect against this type of attack, you would have to make the password mandatory. The server does not know if a password was used, so users could still create non-password-protected pastes using alternative UIs.

Hi,

I agree with rugk. For me when I see (or my recipient sees) "Paste does not exist, has expired or has been deleted" I know that my message has been intercepted. This is extremely valuable information. Even though it's bad that an attacker has my info, at least now I know that the channel I used to send the link is not secure, and that will help me in the future.

Forcing destruction is an effective way to detect the presence of mass snooping where URLs are visited on mass scale and their contents are saved in databases indefinitely. This detection works only if self-destruction is forced.

Thanks for this statement. I actually plan to implement/fix this soon.

Wow. My jaw dropped when I read this issue. This means that the burn-after reading feature is not only useless, but actually worse than useless -- because it gives the users a false sense of security. The whole point of BAR, and I'd argue that it's what most people would intuitively assume, is that the content can be accessed only once. It should be implemented at a very low level -- whenever the data is accessed the very first time, it must be destroyed.

As far as user-interface goes, I'd suggest that #3 makes the most sense.

As a short term measure I will implement an option to choose the behaviour in the server configuration. But for a final solution the password dialog needs to be changed, so that users get a chance to type in another password if the accidentally mistyped. With the current behaviour the paste could not be reloaded when one would revert to the server side deletion. I'll leave that part to @rugk who is more JS-versed then me.

Ok, done. For those that don't like this behaviour, you can now use instantburnafterreading to revert to the previous default of instantly deleting such a paste.

Note that this of course still does not protect you from someone snooping on your pastes (as mentioned, not a use case for PrivateBin). If you share your links publicly or in Skype or Office365 or similar privacy agnostic services, then expect your paste to be publicly readable. Use a password under such circumstances and share that over another channel.

In short: PrivateBin is designed to give the server operator zero knowledge of your pastes content, not to keep the pastes content a secret to anybody else. That is what the password protection is for.

I'll leave it to @rugk to implement any JS-side UI improvements to clarify the use of this feature and handle edge-cases as the password dialog only showing once with the above option enabled (#215).

Wait, I've got a PR ready. See the branch…

Very rough idea... what could be done to actually force burn-after-reading.

When paste is created:

  1. Generate HMAC from random salt, paste key & password
  2. Store nonce & HMAC with paste

When paste is requsted:

  1. Server sends salt to the client
  2. Client computes HMAC using provided salt, known paste key & password, sends it to the server.
  3. If stored HMAC matches, return paste and delete it.

Server still has no information which could be used to decrypt message, while it is able to verify that the client is really the intended recipient - thus it is safe to delete the paste.

In this scenario, the "password" does not have to be shared over another channel, it could be used purely to protect against multiple readers, it could be even "implicit" (i.e. derived from salt in some way but user still has to click something to actually retrieve the paste).

Did I miss something?

As far as I see this solution makes only sense for password-protected pastes. It would assure the paste is only deleted when the user knows the password.
That is an idea, but I don't think really necessary. I mean if an attacker just wants to "DOS" the messages they could just prevent them from being sent in the original communication channel.

IMHO, it makes sense - as currently anyone (MitM case) is able to retrieve password protected paste (and probably brute-force simple password in offline mode, or get it in some other way later), while with this solution - only one recipient will be able to retrieve the paste.

"instantburnafterreading", unfortunately, is not really a solution and even not a workaround - as anything that is sniffing links (skype, telegram, whatsapp, antivirus etc) will kill the paste.

Ah, okay, protection against brute-force is a good argument. I've opened a new issue for that: https://github.com/PrivateBin/PrivateBin/issues/245

Beast question, but, in the example, it is question of cURL the url of the destructible message.
Did you try to do it?
How would you do
Does JavaScript come into consideration? If yes, should you use an API for cURL using PHP / JavaScript?

For my part, I tried to wild cURL, and, I only get the main instance page.

If you knew how to detail the method for cURL a destructible privatebin (in middle man mode therefore) it would be interesting.
Anyway, by reading, we understand that for a good security, it will be necessary at least, in any case currently, to integrate a password in the message.

I discussed it with a penguin colleague who told me about OTP, to get a unique password. It seems to me that this uses PGP / GPG.
I found this not necessarily easy to integrate but he tells me that it is rather easy and transparent for the user, who identifies himself with his private keys, and, who receives a temporary password.

I do not know the OTP mechanism, therefore, I do not know if this method could reinforce the security of a password protected message, but, this would add a layer of security, but, just as much work for the deployment.

OTP : https://wiki.visionduweb.fr/index.php?title=Sommaire_S%C3%A9curit%C3%A9#Les_mots_de_passe_.C3.A0_usage_unique_:_One_Time_Password

28 #188

NB : Another proposal that I have just received, concerning security, would be to give a false message to an identity that does not match. We would then think more of a password failure.

NB : Another propose the 2fa usage.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Forza-tng picture Forza-tng  Â·  5Comments

elrido picture elrido  Â·  4Comments

aryasenna picture aryasenna  Â·  7Comments

Kcchouette picture Kcchouette  Â·  5Comments

Haocen picture Haocen  Â·  5Comments