Thoughts on securely posting to Gopher through Gopher by Christopher Williams 2025-04-18b I’m sure a number of Gopherites have come up with the idea of posting content to their Gopher holes through Gopher itself (using a type 7 menu item, most likely). I’ve kicked around the idea myself. The only hesitation I have with it is... how do I ensure that only I can post something? As we’re all aware, there is absolutely no encryption with Gopher (I’m going to pretend the “gophers” scheme didn’t exist, and according to some people it shouldn’t). So how can my Gopher server know that I’m the one posting and not some script kiddie who happened to find my posting endpoint (which shouldn’t be too difficult to find through packet sniffing)? The answer: authentication! Most modern cryptographic systems (e.g., TLS) provide two main features: privacy and authentication. Privacy ensures that nobody else can read the messages sent from A to B, and authentication ensures that messages from A actually came from A. Cryptographic systems also commonly ensure that a previous message from A cannot be reused as if it were a new message; this vulnerability is known as a replay attack. Can we have authentication without privacy? We sure can! So we can send a message along with a password, right? Er, um, yes, that works, for small values of “works”. The password can be sniffed and re-used to post other “authenticated” messages. It doesn’t really authenticate the message itself. What if we use one-time passwords? Now we’re getting somewhere! A time-based one-time password (TOTP) would be better still as it’s automatically generated and varies over time. How does TOTP work? In a word, magic. Actually, it relies on two sides of a communication (a server and a client, for example) having a shared secret (i.e., a key). The shared secret is combined with the current time (typically updated every 30 seconds) and hashed, and then a few digits are taken from the hash and used as the password. Assuming both sides have the same time and the same key, they will generate the same passwords. Real-life authentication systems often permit passwords from one or more past or future time periods to allow a client’s clock to be slightly off, but this reduces security somewhat. TOTP is defined by RFC 6238[1], so it’s no secret or proprietary thing. TOTP apps are basically standard fare these days. Google Authenticator is a big name, but Microsoft has their own (I don’t care enough to find out its name), and I use an app called 2FA Authenticator (2FAS) and a CLI program called 2FA by Russ Cox (of Go fame). So here’s what I propose: 1. Set up a TOTP authenticator on both the client and the server using a shared key. 2. Have a Gopher endpoint that takes a message the user wants to post. 3. When the user posts a message, hold the message somehow and ask for a TOTP. 4. When a valid TOTP is provided, the held message will be posted. A simple way to do this is by saving the “search request” data (the message to post) to a temporary file, named after the hash of its contents, and then return a new menu to the client with a type 7 item with the hash encoded in the selector and asking for a TOTP. When a valid TOTP is submitted to that selector, the message contained in the file named by the hash is posted. The TOTP is also saved temporarily (up to 30 seconds) to prevent its reuse within its validity period. (Any temporary files older than _x_ minutes can be removed periodically since they’ll be stale and useless, where _x_ is say 10.) This process still has a downside—the message can be altered between the client and the server, for example. This can be fixed by requiring authentication on the message itself, such as with a signature (e.g., a signed hash). After sending a message, the server could require a valid signature and then finally a TOTP. The issue is that this requires setting up a public/private key (storing the public key on the server) and having a way to sign a message on the client (with the private key) and verifying it on the server (with the public key). A TOTP authenticator app is very common; public-key signing apps, not so much (at least from what I’ve seen). (Also, if the message itself were authenticated, a TOTP may not be necessary. A submitted message can be saved as above and then posted if a valid signature is then provided. Each valid signature would then have to be saved to prevent replay attacks. Or each message must have the current time prepended or appended to it, and said time must be close to the current time or else it’ll be discarded. Perhaps a TOTP is not such a bad idea after all.) I’m not sure how prevalent this problem is (altering messages requires a man in the middle rather than just an observer), and the mitigation for it is more involved than using a simple TOTP, so I’m not sure it’s even worth doing. I’m still working out some of these ideas and trying to see what works and is practical and necessary. Thoughts? Questions? Let me know![2] ------------------------------------------------------------ References ------------------------------------------------------------ [1] gopher://asciz.com/0/rfc/rfc6238.txt [2] gopher://asciz.com/7/feedback