Safely send someone a file
A small side project that allows you to upload a single file. You then get a link, and an access code which you can then send to whoever you want to send the file to.
They can use the link and access code to download the file once, after which the file will be deleted.
As best I can remember, it was a shower thought. Because every access code is only usable once to download a file, if you needed another opportunity to download a file (and the feature was available), the system would need to rotate the access code.
Plus there's this YouTube music video by MrWeebl called Rotate Your Owl (for science!).
So there. Hope it's as unfulfilling of an answer as I think it is. 😅
With increasing frequency I have to deal with organisations / companies / government over email where they need to have some sort of proof of ID: applying for a loan, filling out tax documents, etc.
They would tell me "hey can you send me a scan of your passport over email?"
Email is unencrypted, inherently insecure, and I really do not want the scan of my passport to end up in places where they shouldn't be.
Instead I could upload the scan of the passport here, email them a link and the access code, they can download it once, and the link becomes unusable.
That way even if their email account gets breached, or the email is intercepted, by the time someone malicious were to get there, they would be late.
Plus the site is on HTTPS, so +1 for security there.
Me, obviously. 😅 My name is Gabor Javorszky. You can find me on a bunch of places:
I currently work as a senior software engineer at Suborbital Software Systems working in Golang doing stuff around WASM runtimes.
For now please use either my Mastodon, or my Twitter account for such things. You can find the links in the footer. It keeps things easier. I don't want to add my email address to this app because I like my inbox as much spam free as possible (robots harvesting email addresses on pages is a thing, not you spamming me), and creating a contact me page seems overkill for now.
Alternatively if you're in the RWC discord, there. If you don't know which one that is, use Mastodon / Twitter. ☺️
Note that if you do try to bypass that and send me an email you found on my Github / Linkedin, I will ignore it. I put those there so you can verify that I indeed exist and I am who I say I am. Nothing personal. I like to have few avenues to deal with things, otherwise life gets overwhelming, which is not something I want to do if I can avoid it.
There's a scheduled task set up to run every 5 minutes.
When that task runs, it finds all the files that were uploaded more than 24 hours ago and deletes them.
It is 10,000 KiB, or 10,240,000 bytes, or just above 10.24 MiB
For all intents and purposes, it's 10 Mb. Try not to approach that limit.
This limit is mostly in place because currently there's no huge storage attached to the app.
In the future I plan to introduce the ability to register for accounts (free and paid) if you need more control or extra niceties around logs, access rights, and so on. Stay tuned.
You'd need to upload them one by one.
Alternatively you could zip them up and upload the zip as a single file.
This doesn't support multiple file uploads, nor is it something I plan to add. I want to keep this as basic and simple as I can for as long as I can.
On Digital Ocean in the LON1 region - London, United Kingdom.
I haven't figured out how to best answer this in a way that you can be sure that they do get deleted.
The source code is not open source, I do not plan to make it open source for the time being.
Read access to the file system would be a security risk.
From a technical point of view there's a middleware that checks the access token when your user clicks the download link. In that middleware, after the file has been downloaded, the relevant database entry is deleted.
There is also an observer on the database entries: after they are deleted, the file associated also gets hard deleted from the storage.
The scheduled task that removes all files uploaded earlier than 24 hours ago also deletes the found entries one by one, so the same observer also kicks in.
From a regulatory point of view
Because both myself, and the service is within the United Kingdom, I am beholden to the GDPR, which is an excellent framework to help users with their privacy and security issues.
GDPR has a bunch of important principles, of those I picked these two that are most important that apply here:
Excellent questions! Short answers: no backup, yes encryption.
Let's start with the backup. The whole point of this app is that it's transient - nothing gets kept besides what's absolutely necessary.
When doing a backup, if there were any backups, including uploaded files is not necessary, because they are short-lived to begin with. I decided that even if there's catastrophic failure that results in loss of data, the inconvenience that causes you, an anonymous, non-paying user of the service, is far smaller than the extra burden including your files in backups would introduce.
Because of this there's no point in creating a backup at all. The code lives in a private Github repository, so if something terrible happens, I'll deploy it again and start from scratch.
Onto encryption. Some services have client side, transport, and server side encryption baked into them.
Client side encryption means that your browser knows the actual file contents and encrypts it before sending it to the server, so the server has absolutely no idea what the file contains besides probably its original name, size, and extension.
Transport security almost always means the site, and every connection to it, is over HTTPS. I do that too. Everyone should do that always in 2023 and later.
Server side, or "at rest", encryption means that whatever data the server received, it encrypted it before writing it to the storage. In case someone looks at their storage, they won't be able to use any data on it without the proper encryption keys.
Of the above I do two out of three at the time of writing this, on 6th June 2023. Those two are the transport side encryption and the encryption at rest. Implementing client side encryption would complicate the access token part of the system, so it's likely I won't ever do that.
The at rest encryption uses Laravel's `Crypt` facade. Once the file is encrypted, I separate out the random initialization vector, and give that to you as the access token before saving the rest of the data without the IV to the disk. This essentially means I have no idea what the file contains just by looking at the individual files, because I don't have the IV that's necessary to decrypt the file. You do.
This also means that the access token is not only a "soft" check where I see whether a database entry matches, and if so I'll let you have the file. It's a hard requirement. Without it the app can not decrypt the file and can not give you the contents.
Honestly, it probably isn't. I do not have their resources.
It is significantly simpler however, so if you want something that just works without having to go through a bunch of steps to share files using a link, set correct permissions on them, get confirmation from the other party they downloaded it, and then revoke the link, then this is perfect for your use case.
It's a small service that's disposable, doesn't require you to sign up for super basic usage, and you can track down the person who made it.
Plus I don't write PR statements about how your privacy is important to me while not doing anything to actually protect it.
At the end of the day, use the service you trust and feel comfortable using.
You probably noticed there wasn't a cookie popup we're all used to. Not because I "forgot" to add it, but rather, well, because I don't collect any data about you whatsoever.
The only things that do get collected are needed to deliver you the service ("contract" lawful basis for processing data), which is the file. I don't need your consent for that per the ICO's guidance.
Other places I have data about what you do here:
And that's it. I don't have Google Analytics, segment, or any other tracking service installed on the site.
The two cookies you see are both doing the same thing: providing CSRF protection. They regenerate every page load where there's a form present.