Status codes

Howdy!

I'm working on my own client and figured I'd write on the status codes.
This is something that, I feel, can be simplified. My comments will be
based on two assumptions:
1. Things should be as simple as possible, but not simpler
2. Complexity is a source of bugs and exploits[1]

I understand that there may be some aversion to changing things that
are already pretty well established, but I hope it's not too late and
my arguments will be at least a little bit convincing. :)

Suggestion #0: Strengthen language around status codes

It is softly stated that the second digit is an extension to the status
code. Then valid first digits are laid out. Upon first reading I found
this confusing so I would welcome rephrasing this into something that
states explicitly:
1. All clients and servers must at the very least recognize status codes
10, 20, 30, 40, 50 and 60.
2. Any xy code not recognized by the client can be safely interpreted
as x0 (e.g. 21 can be safely treated as 20, and 45 can be treated like
40 w/o consequences)
3. The status codes section shouldn't use single digits but the core
codes (10, 20, etc.) or as masks (1y, 2y, etc.)
4. Replace the unique phrasing of "range of codes" in section 1.3.1 with
"status code category" used elsewhere (range felt like a broader term
than category and caused me some time to figure out if I'm missing
something important).

Suggestion #1: Remove proxy related codes

Current spec is already something that is likely to be two IETF RFCs
in the future (protocol and document format). Adding proxy support into
the mix complicates things even further. Problems with proxy IMO start
with the fact that it's not clear (to me at least) what sort of proxy
gemini would benefit from; nor is it stated in the spec.

Classical reverse proxy roles of load balancing and caching are possible
but I don't see how these can be implemented w/o expiration mechanisms
added to the spec. It could be done, but I think it should be tackled
in a separate RFC. Forwarding proxy, anonymizing or otherwise is
a possibility but, again, I think this should be an extension that
ends up in a separate spec.

There's also a lot of work that has to be done for the proxy to support
client certificates in various setups (when we want anonymity or not,
where we deal with session certs or permanent ones, and so on), how
various error paths should perform, etc. It's a lot of work and would
definitely need fairly stable clients and some reference proxy
implementation to validate assumptions about what could work.

How server and client certs are handled in the proxy scenario is also
something that I don't think is trivial and as such would require some
legwork to get up and running. So, yeah, I'd cut any mention of proxy
at the moment and with that's codes 43 and 53.

Suggestion #2: Deduplicate client cert errors

Only a single client cert can be sent when establishing the communication
channel. My mental model (correct me if I'm wrong!) is that transient
cert is a session substitute and permanent cert is authentication
mechanism (roughly speaking at least).

Current spec has 3 cert request mechanisms, 3 rejection codes and
a revocation code. This creates numerous corner cases for clients
to handle properly, e.g.

your permanent key? I sure hope the browser doesn't actually delete
the permanent key from the store :)


I'd like to see a single "client certificate rejected" code eliminating
responses that would potentially make no sense.

I feel that differentiating between the types of rejection opens some
opportunity for oracle attacks (i.e. rogue clients can inspect server
cert processing bugs by observing how responses differ for various
crafted requests). In essence I'd cut 64 and 65.

Suggestion #3: Change end of cert session (21) into a redirection

This will probably be a very controversial one but the way I see it
the end of session typically results in the redirection. This lets you
chain requests on logout in a way that enables permanent client key
delivery or temporary key replacement. With current design you serve
a page in a response to a request that displays something and asks
the client to delete the transient cert. If you want to re-establish
some sort of validation from the client, you need a manual intervention
from the user to do that. I'm not sure if my explanation is clear enough,
I can try and expand upon it if needed.

Suggestion #4: Merge different types of server error to prevent leaking
what happened under the hood

HTTP 500 is often seen as an indication of something wrong in the server
application logic. This would be the primary attack vector for someone
trying to compromise the server (even if only DOS it). I don't think it
makes sense to differentiate codes 40-42 with the exception maybe of
a planned maintenance. Basically I'm sort of allergic to disclosing
information about the server state.

The counter argument is likely going to be: there's reason not to give
extra details.

To which I say ;) sure, but you can already do that with <META>.

Suggestion #5: A comment, really

5x codes are by design permanent errors but 51 (HTTP 404 equivalent) is
actually a temporary problem according to the spec.
In fact this is precisely what differentiates it from HTTP 410 GONE
(gemini 52). So there seems to be a design error here but I don't really
know what the correct solution is. Either 5x aren't really permanent
errors (how would they be called then?) or 51 shouldn't be a 5x error
to begin with.

This sums up my thoughts about the status codes. I know this reads very
much like "too complex, cut!" and that kinda is exactly that. But if you
can make things simpler, why not do it? :)

Thanks for reading this, cheers!
-Dom

[1] There's a neat research on exploiting HTTP status codes:
https://www.youtube.com/watch?v=4OztMJ4EL1s

---

Next in thread (2 of 4): 🗣️ Sean Conner (sean (a) conman.org)

View entire thread.