I was looking at ways to fix #23689 (making net/http respond nicely to clear-text HTTP clients sending requests to HTTPS servers) and of the many possible ways to fix it, most are gross.
I don't really want to make crypto/tls aware of HTTP semantics.
I don't want to add a HandshakeOptions
I don't want to add a hook to Conn or Handshake to alter alert-sending behavior based on the content
Writing an alternate net.Listener or net.Conn wrapper type doesn't help, because net/http accepts any ol' net.Listener and then type-checks the responses for *tls.Conns. (please avoid talking about making that an interface in this bug)
exposing tls.Conn's underlying Conn, even with a bunch of documented warnings.
The only thing non-offensive way I can see to fix this is to add:
package tls
// PeekHandshake can be called before a handshake to return some number of bytes from the// the underlying net.Conn, before the handshake is processed. The bytes should not be mutated// or retained, and PeekHandshake should not be called concurrently with any other operations.func (c*Conn) PeekHandshake() ([]byte, error) { ... }
Then net/http can call PeekHandshake before its Handshake and see if it starts with GET or HEAD or POST, etc, and return a nice 400 message.
exposing tls.Conn's underlying Conn, even with a bunch of documented warnings.
I'm not sure I understand, if you don't have the underlying Conn, how are you going to send the 400 response?
Writing an alternate net.Listener or net.Conn wrapper type doesn't help, because net/http accepts any ol' net.Listener and then type-checks the responses for *tls.Conns. (please avoid talking about making that an interface in this bug)
(Linking to #21753 as the place to have that discussion.)
I was looking at ways to fix #23689 (making net/http respond nicely to clear-text HTTP clients sending requests to HTTPS servers) and of the many possible ways to fix it, most are gross.
You would think that https://golang.org/pkg/crypto/tls/#RecordHeaderError as returned by https://golang.org/pkg/crypto/tls/#Conn.Handshake would be sufficient, but Handshake sends a record alert error to the client before returning, so the connection already has binary gibberish written on it (as far as the HTTP/1.x plaintext client is concerned).
The options I didn't like:
The only thing non-offensive way I can see to fix this is to add:
Then
net/http
can callPeekHandshake
before itsHandshake
and see if it starts withGET
orHEAD
orPOST
, etc, and return a nice 400 message.Open to naming suggestions.
/cc @FiloSottile @agl
The text was updated successfully, but these errors were encountered: