place where things are hidden or stashed away
Gömma is a Django based file hosting service I created for personal use. It's inspired by my friends similar project "Jemma". The front-end is similar, but he wasn't willing to share the back-end so I had to come with my own implementation.
Please visit the site at gm.hehexd.fi
The source code is available on GitHub.
Files are stored on the filesystem and things like file name, upload date, "stashed" name, IP, and hashes are stored in a PostgreSQL database. The stashed name is a random string that is used to access the file to have shorter URLs. The user can also set their own stashed name if they want to. This might offer an attack vector through SQL injection, so the stashed name is sanitized with Django's slugify function. This also prevents any url funkiness.
Other hardening that was done is not allowing more than 50 files at once and not allowing files larger than 1024MB. The file size limit is enforced both in the Django back-end as well as Nginx. Rate limiting is also implemented through Nginx.
I decided against auth due to the fact that this is only for personal use and I don't want to deal with user management. The files are not private, but the stashed name is a random string that is hard to guess, so it's not likely that someone would stumble upon them. In general services like these should be used with the assumption that other people can also access them, so no sensitive files should be uploaded. Another way a person might stumble upon files is through the "recent uploads" section, which shows the 10 most recent uploads from the same IP. This might be problematic if on public Wi-Fi or behing a CGNAT.
If more than one file is uploaded at once, they are zipped together and served as a single file. This is done to save space and make it easier to download multiple files at once.
Not sure how great of an idea it is to expose these here :D
The VPS only has 40GB of disk space and there are no checks in place in case it's filling up, which will cause a failure at some point
Performance wise it might be quite poor. I don't have the means to test multiple users sending (and zipping) multiple files at the same time. At some point Gunicorn will most likely get saturated
A big vulnerability that I hadn't considered immediately, but seems quite obvious in hindsight, is only serving safe MIME type files inline. At first I used Python mimetypes.guess() to check if a valid MIME type existed and if it did, serve it inline, otherwise octet-stream. This is a HUGE vulnerability, letting malicious users upload .html or .js files and serve them on my site to unknowing users.
Now there is a list of confirmed safe mime types that are served inline, and all others are served as octet-stream.
If you have any questions about this project or would like to collaborate, feel free to reach out: