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