> However [alternatives'] pages are laden with ads, have a poor UI, and you can't know for sure if they really are actually encrypting / deleting anything.
There has been a private zero-knowledge pastebin for years: zerobin, forked into privatebin now (https://zerobin.net/). In fact the original is almost 10-years old but hasn't displayed a single ad, has been open source the whole time, has had time to iron out a lot of bugs and has a better UX than this: it doesn't need cookies to work.
In terms of security, zerobin encrypts/decrypts everything in the browser. The server has no knowledge of the content. In contrast, burnernote receives the content _and_ the password in cleartext and encrypts/hashes them.
Unfortunately, as long as there's a server you will have to trust it. In both cases you have to rely on something other than code and HTTPS to know if your content actually remains private or not
This is awesome feedback and client side encryption is 100% on its way. I just put this together over the weekend and then put around places like this for feedback.
First of all, this is a cool idea. I always love to see something private and encrypted.
But I found some concerns and ideas about your project (and I think you may can fix these):
0. This has XSS vulnerability. If attacker writes down this memo:
<script>do_the_evil_things()</script>
and passes to people, they might be unknowingly attacked(get tracked by attacker their IP/Browser fingerprint, mine cryptocurrencies for attacker, etc...)
1. This basically works under server-side encryption. When user type their text in the website, it is encrypted with the secret key on your config file and saved on the database. This is only effective when attacker only succeeds to crack the database. Also, you can read the text. I know you won't, but you know, cryptographers don't trust anyone.
If you want to mitigate this, you might want to learn about end-to-end encryption. In short: the hash of the private link is the secret key. The browser randomly generate the key and encrypt/decrypt the text. The server only receives/saves the ciphertext.
2. AES-256-CBC is unsafe because it provides confidentiallity and not authenticity.[1] This means the attacker who can only crack the database can edit the ciphertext to pseudo-arbitrary plaintext under certain circumstance without knowing of the key. Also under another circumstance, attacker can use 'Padding oracle attack' to recover the ciphertext. it seems your service is not in this case: Laravel's encryption is AES-256-CBC + MAC, which mitigates this problem. So this is safe, but next time, if you write some crypto-related things without Laravel, you'd better use some high-level library such as libsodium or sjcl.
3. This service uses CloudFlare. Using CloudFlare might be safe on small project because they have rock solid WAF to prevent general attacks. But it may be unsafe for a whistleblower from NSA: when it matters with state-sponsered attackers or law enforcements, CloudFlare can be attacked/warranted. Then it becomes another attack vector.
Again, your service and idea are cool. But you should remember that this area is full of land mines, dragons, and dinosaurs with laser guns.
Your point on cloudflare is something I'm grappling with for an application I'm working on. On one hand I would love the simplicity of something like cloudflare pages or vercel etc. Their preview links on pull requests and automatic deployments would make frontend work very convenient. But on the other hand I have exactly your concerns about warrants. Is there some nice middle ground to avoid completely manual builds and deployment on a VM? Maybe some convenient CI, but this service would also need an ssh key to be able to deploy, so we're in a similar situation again I suppose.
Edit: I spent some time thinking about it and might as well document it here if someone finds it interesting.
For context, my application does client side encryption with keys stored only in the browser. The catastrophic case would be if the frontend application is modified to extract those keys. That's why I don't necessarily trust a hosted option (which typically needs control of the SSL certificate as well).
Instead I would like to serve the client from a server under my control.
One solution is to use Github Actions and have it automatically deploy via ssh. This doesn't really increase my attack surface, since the code is already at Github anyway. So if this platform is compromised / warranted they could modify my application to their liking.
A second solution would be to use any CI service and restrict the capabilities of the ssh key in the `authorized_keys` to only trigger a fixed command without actually being able to log in. The command would pull the code / image and deploy. This way a compromised key could only be used to trigger a new deployment of authentic code, not inject malicious code.
This is good! As I said in another post, the reason I posted this here was to get feedback and improve. All of these points are excellent and I will address them and get back to you.
- This is symmetric encryption via AES-GCM, but asymmetric should work similar
- In-browser randomness (for key generation) is somewhat questionable, so try to read more about this topic
- This is meant as an intro to the topic - real security takes much more, like thinking about secure key storage, backup/recovery keys, etc.
FYI if I post 1MB of data it explodes and dumps a full stack trace. May not be something you want exposed.
SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'note' at row 1 (SQL: insert into `notes` (`note`, `password`, `user_id`, `token`, `updated_at`, `created_at`) values ...SNIP...
> On clicking the link and opening your note, it is deleted instantly and completely from our database. Gone forever.
I worry about using such services when it comes to sending the note links over email or chat platforms, where the messaging platform may crawl the link and have the content destroyed before the human user has had a chance to see it. Has anyone encountered this on other secret sharing platforms? Using a password that’s not part of the link would prevent from that happening, but I see that it’s optional in this solution.
Yes, this is an issue. I wrote my own service that I run on my own web server for this type of message. Outlook webmail includes a convenient link preview by default. When someone opened the link, the message was already deleted. I solved it by emailing a link to the link.
It's not the ability to display alerts that is concerning, but rather, the ability to run untrusted Javascript. This was a proof of concept that showed that it has a serious XSS vulnerability
haha ok this is something I will remedy. As stated in other replies, the reason for posting here was to get feedback and improve the product (I just put to together over the weekend there)
Hello, the way that privnote deals with it is by showing a page asking "Do you want to read this note and burn it?". That will solve the issue of preview apps expiring your notes.
This is what I done! I realised this morning as I was in a McDonalds drive thru queue how easy it would be to solve just by adding an "are you sure" screen.
Very cool, but the FAQ doesn’t address the questions people will ask: open source is fine, but what guarantee do we have that the source code matches the deployed code? Or that the deployment is done in a secure environment?
For an app that exists solely on the client it’s easy to provide a md5 hash that can be verified.
This was and still is a popular solution if you torrent to make sure you’re getting what the original seeder intended. The same philosophy applies here.
Yeah I wondered this myself and my colleagues at the day job and myself were kinda stumped. How does any OSS prove that the repo linked is what is actually deployed?
You have to implement the encryption logic client side. But then now the client has to verify the JavaScript they receive upon visiting the URL matches what is published in the open repository.
I’m not sure what convenient method exists to do this for the client. You’d have to compare hashes and idk how that could be done in a easy and trustworthy manor.
AES-CBC for quick and dirty encryption can be a red flag: the scheme needs to include an encrypt-then-MAC phase or it'll be vulnerable to padding oracle attacks. I tried to do a quick scan of the code[1] to determine whether it does that, but I couldn't locate it, possibly because my PHP comprehension is terrible.
Update: As far as I can tell, this is the encryption encrypoint[1]. It does seem to be vulnerable to a padding oracle attack, unless the `$request->note` parameter is something much more complicated than it appears to be (i.e., it appears to be the plaintext).
It's always great to see people experiment with encryption (and burn-after-use schemes are very cool!) but, absent of further information, I think it's actively dangerous to encourage people to use this.
Edit: It might also be a stretch to call this a "burn-after-use" scheme: there's no affirmative proof of a note's destruction on the server side. It seems to just update the database to mark the note as empty and deleted[2].
Another update: it looks like it uses Laravel's encryption API under the hood, which does indeed perform encrypt-then-MAC[1]. So this is probably not vulnerable to a padding oracle attack. But that wasn't obvious from the description, and it gave me a decent fright :-)
It's a very good thing that it isn't susceptible to that particular weakness, as that would have been a disastrous one. But there are a lot of things that are left to be desired about this setup:
1. Message secrecy and the soundness of the encrypt-then-MAC protection seem to be partially, if not completely, dependent on the `APP_KEY` that you generated and are currently running the service with. For all anyone knows, that `APP_KEY` is all zeroes or comes from a bad RNG source. A better scheme wouldn't introduce a fundamental dependency on untrusted server randomness.
2. Message deletion is unsound: I have no proof that a note being "deleted" means that it's actually purged from your storage. I'm decently sure proving that is actually impossible in the general case, which is another reason why it's dangerous to have the note's encryption handled on the server side.
3. The "password" functionality seems to just be a string comparison against a DB-stored password. It's not mixed into the secret material for encryption at all. It's hashed at least, which is good, but it doesn't look like it's salted, which is bad.
My point was that it's a claim that's impossible to formally prove: we don't really know how to do formal proofs of destruction, at least not with the scheme you're using.
But even beyond that, there are a lot of weaknesses in this setup. I'll post a list of them in response to the other comment you left, since they'll be more relevant there.
> What else would you like to see here?
Frankly, you should either disable this service or put a big red banner on it explaining that it it (1) hasn't been audited, and (2) doesn't encrypt messages on the client side. As it is, people are going to make incorrect and potentially dangerous assumptions about the privacy of data they put on your service.
Please don't take that as a personal rebuke, because it isn't! I just don't want you to be the most recent person in a long lineage of developers to be publicly burned for teaching themselves applied cryptography.
I just want to say @gigamick these burn systems are powerful.
You might get divorced some day. You might have a business partner subpoena your old gmail account. ALL those emails/texts will be turned over, ALL those emails/texts will get leaked. Use something like this! Make the message burn after reading.
Very zeitgeisty :), I've created something similar a while ago (https://tmp.page), the idea was to have expiring web pages, with a nice API. Our FEs are quite similar, yours is nicer tough :).
> However [alternatives'] pages are laden with ads, have a poor UI, and you can't know for sure if they really are actually encrypting / deleting anything.
There has been a private zero-knowledge pastebin for years: zerobin, forked into privatebin now (https://zerobin.net/). In fact the original is almost 10-years old but hasn't displayed a single ad, has been open source the whole time, has had time to iron out a lot of bugs and has a better UX than this: it doesn't need cookies to work.
In terms of security, zerobin encrypts/decrypts everything in the browser. The server has no knowledge of the content. In contrast, burnernote receives the content _and_ the password in cleartext and encrypts/hashes them.
Unfortunately, as long as there's a server you will have to trust it. In both cases you have to rely on something other than code and HTTPS to know if your content actually remains private or not