File uploading with fupfup

One thing I do now and then is transfer files from my smartphone to my desktop computer and then from there to my server.

A common situation is if I’ve taken pictures of a project to document it and include in a blog post. I’ve always thought this felt clunky and involved quite a lot of friction, especially how most of the ways I transfered the pictures entailed some type of history: whether emailing myself or using the private messenger Signal’s Notes to self function. Transferring using something that has persistent history means that I often feel the need to clean it up. (And sometimes Signal’s desktop client stops working until I’ve downloaded the latest update…). There’s also still that extra step of transferring from the recipient computer and onto my server. Annoying!

So I made a little thing I’m calling fupfup to solve this, because OF COURSE. I think it’s fun and enjoyable to explore the design space of a problem and to also create the solution itself, especially for the small problems I encounter in day-to-day life. These kinds of projects also present an opportunity to tack onto the problem a new topic, technology, or way of doing things.

fupfup’s simple upload screen

Simple login with TOTP

Since this project involves uploading files to my server I wanted to take care as for how to do that. I wanted to put in place some mechanism of restricting who or what could upload files to fupfup’s upload directory, but without that part becoming ungainly.

One thing I didn’t want to involve in this particular solution was having to remember or track a password (otherwise HTTP Basic Auth is a very pragmatic option). I decided to try out using a TOTP, or Time-based one-time-password.

A little bit about TOTP

If you’ve scanned a QR code with an app like Authy, Google Authenticator or similar and then had the app generate numeric codes (6-8 numbers long) then you’ve used a TOTP.

The gist is that a library which implements TOTP basically does one thing: generate some credentials using cryptography. These credentials can then be used to derive a numeric code which can be validated server-side. Actually a TOTP library does one other thing, which is represent those credentials as a QR code, since QR code scanning is the normal flow of onboarding the credentials to a second device. So one part of the credentials stay on the server, used to authenticate the incoming passcode for a given user, and the other goes to the second device by way of QR code.

Typically TOTP is used as a multi-factor authentication mechanism, in addition to e.g. a password, but I don’t see why I couldn’t use it as a simple login system. Happily for me using TOTP for fupfup turned out to be a breeze! Since this use case was for uploading from my phone, using an authenticator app felt like working with the grain of the context.

Using fupfup

What I’ve developed is a two-part solution. One part cli to generate the credentials and output a QR code and, separately, one part HTTP server that handles authentication and accepts uploads. I wanted to keep the two separate to limit the attack surface; exposing account creation to the wider web didn’t seem like it would gain me anything other than headaches :)

When I want to log in I go to a special route, open my authenticator app, copy fupfup’s current passcode, paste it into fupfup’s form and tap log in. This sets a session cookie on my browser which is checked when I try to upload something. From here on out, I can upload files as desired!

Before I push this live I want to add further restrictions, like limiting the rights of the user running this particular HTTP server, as well as look into enabling quotas to limit the maximum usable disk space permissible for that user. For periods when I’m not going to use this I might also just keep the service down to further limit the possibility of an attack. I also want to write some small scripts that can be run on all the images in the upload directory to remove location data (while keeping EXIF’s orientation data intact!) and to normalize the width and height to mitigate the ludicrous defaults chosen by smartphone manufacturers.

Anyway, TOTP was breezy to put into practice and I now have a much easier way to get files from my phone to my server, and a bit of TOTP know-how in my back pocket for future projects!