Allow domain fronting with TLS client auth if explicitly configured

This commit is contained in:
Matthew Holt 2019-09-17 23:13:21 -06:00
parent 19f36667f7
commit 4c289fc6ad
No known key found for this signature in database
GPG key ID: 2A349DD577D586A5
2 changed files with 14 additions and 10 deletions

View file

@ -78,16 +78,20 @@ func (app *App) Provision(ctx caddy.Context) error {
srv.AutoHTTPS = new(AutoHTTPSConfig) srv.AutoHTTPS = new(AutoHTTPSConfig)
} }
// disallow TLS client auth bypass which could // if not explicitly configured by the user, disallow TLS
// otherwise be exploited by sending an unprotected // client auth bypass (domain fronting) which could
// SNI value during TLS handshake, then a protected // otherwise be exploited by sending an unprotected SNI
// Host header during HTTP request later on that // value during a TLS handshake, then putting a protected
// connection // domain in the Host header after establishing connection;
if srv.hasTLSClientAuth() { // this is a safe default, but we allow users to override
srv.StrictSNIHost = true // 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 { for i := range srv.Listen {
srv.Listen[i] = repl.ReplaceAll(srv.Listen[i], "") srv.Listen[i] = repl.ReplaceAll(srv.Listen[i], "")
} }

View file

@ -42,7 +42,7 @@ type Server struct {
TLSConnPolicies caddytls.ConnectionPolicies `json:"tls_connection_policies,omitempty"` TLSConnPolicies caddytls.ConnectionPolicies `json:"tls_connection_policies,omitempty"`
AutoHTTPS *AutoHTTPSConfig `json:"automatic_https,omitempty"` AutoHTTPS *AutoHTTPSConfig `json:"automatic_https,omitempty"`
MaxRehandles *int `json:"max_rehandles,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 // This field is not subject to compatibility promises
ExperimentalHTTP3 bool `json:"experimental_http3,omitempty"` 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 // servers that rely on TLS ClientAuth sharing a listener
// with servers that do not; if not enforced, client could // with servers that do not; if not enforced, client could
// bypass by sending benign SNI then restricted Host header // 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) hostname, _, err := net.SplitHostPort(r.Host)
if err != nil { if err != nil {
hostname = r.Host // OK; probably lacked port hostname = r.Host // OK; probably lacked port