Browse Source
Allow domain fronting with TLS client auth if explicitly configured
master
Matthew Holt
6 years ago
No known key found for this signature in database
GPG Key ID: 2A349DD577D586A5
2 changed files with
14 additions and
10 deletions
-
modules/caddyhttp/caddyhttp.go
-
modules/caddyhttp/server.go
|
|
@ -78,16 +78,20 @@ func (app *App) Provision(ctx caddy.Context) error { |
|
|
|
srv.AutoHTTPS = new(AutoHTTPSConfig) |
|
|
|
} |
|
|
|
|
|
|
|
// disallow TLS client auth bypass which could
|
|
|
|
// otherwise be exploited by sending an unprotected
|
|
|
|
// SNI value during TLS handshake, then a protected
|
|
|
|
// Host header during HTTP request later on that
|
|
|
|
// connection
|
|
|
|
if srv.hasTLSClientAuth() { |
|
|
|
srv.StrictSNIHost = true |
|
|
|
// if not explicitly configured by the user, disallow TLS
|
|
|
|
// client auth bypass (domain fronting) which could
|
|
|
|
// otherwise be exploited by sending an unprotected SNI
|
|
|
|
// value during a TLS handshake, then putting a protected
|
|
|
|
// domain in the Host header after establishing connection;
|
|
|
|
// this is a safe default, but we allow users to override
|
|
|
|
// it for example in the case of running a proxy where
|
|
|
|
// domain fronting is desired and access is not restricted
|
|
|
|
// based on hostname
|
|
|
|
if srv.StrictSNIHost == nil && srv.hasTLSClientAuth() { |
|
|
|
trueBool := true |
|
|
|
srv.StrictSNIHost = &trueBool |
|
|
|
} |
|
|
|
|
|
|
|
// TODO: Test this function to ensure these replacements are performed
|
|
|
|
for i := range srv.Listen { |
|
|
|
srv.Listen[i] = repl.ReplaceAll(srv.Listen[i], "") |
|
|
|
} |
|
|
|
|
|
@ -42,7 +42,7 @@ type Server struct { |
|
|
|
TLSConnPolicies caddytls.ConnectionPolicies `json:"tls_connection_policies,omitempty"` |
|
|
|
AutoHTTPS *AutoHTTPSConfig `json:"automatic_https,omitempty"` |
|
|
|
MaxRehandles *int `json:"max_rehandles,omitempty"` |
|
|
|
StrictSNIHost bool `json:"strict_sni_host,omitempty"` |
|
|
|
StrictSNIHost *bool `json:"strict_sni_host,omitempty"` |
|
|
|
|
|
|
|
// This field is not subject to compatibility promises
|
|
|
|
ExperimentalHTTP3 bool `json:"experimental_http3,omitempty"` |
|
|
@ -164,7 +164,7 @@ func (s *Server) enforcementHandler(w http.ResponseWriter, r *http.Request, next |
|
|
|
// servers that rely on TLS ClientAuth sharing a listener
|
|
|
|
// with servers that do not; if not enforced, client could
|
|
|
|
// bypass by sending benign SNI then restricted Host header
|
|
|
|
if s.StrictSNIHost && r.TLS != nil { |
|
|
|
if s.StrictSNIHost != nil && *s.StrictSNIHost && r.TLS != nil { |
|
|
|
hostname, _, err := net.SplitHostPort(r.Host) |
|
|
|
if err != nil { |
|
|
|
hostname = r.Host // OK; probably lacked port
|
|
|
|