From 829757d3bc8196d6520f24479370a9037fbdb4de Mon Sep 17 00:00:00 2001 From: Paul Williams Date: Thu, 27 Feb 2020 23:28:53 +0000 Subject: [PATCH] [FEATURE] Support secure websocket connections. (#656) * Add WSS support for insecure scheme detection WSS connections were broken by the introduction of this check. Adding WSS as a supported scheme for secure connections prevents a 401 being returned for an authorised connection. * Add tests for WSS Also extend HTTPS tests to ensure they do not catch WSS URLs --- internal/handlers/handler_verify.go | 8 ++++++-- internal/handlers/handler_verify_test.go | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/internal/handlers/handler_verify.go b/internal/handlers/handler_verify.go index 05c1312a..ee660b77 100644 --- a/internal/handlers/handler_verify.go +++ b/internal/handlers/handler_verify.go @@ -22,6 +22,10 @@ func isSchemeHTTPS(url *url.URL) bool { return url.Scheme == "https" } +func isSchemeWSS(url *url.URL) bool { + return url.Scheme == "wss" +} + // getOriginalURL extract the URL from the request headers (X-Original-URI or X-Forwarded-* headers). func getOriginalURL(ctx *middlewares.AutheliaCtx) (*url.URL, error) { originalURL := ctx.XOriginalURL() @@ -207,8 +211,8 @@ func VerifyGet(ctx *middlewares.AutheliaCtx) { return } - if !isSchemeHTTPS(targetURL) { - ctx.Logger.Error(fmt.Errorf("Scheme of target URL %s must be 'https' since cookies are "+ + if !isSchemeHTTPS(targetURL) && !isSchemeWSS(targetURL) { + ctx.Logger.Error(fmt.Errorf("Scheme of target URL %s must be secure since cookies are "+ "only transported over a secure connection for security reasons", targetURL.String())) ctx.ReplyUnauthorized() return diff --git a/internal/handlers/handler_verify_test.go b/internal/handlers/handler_verify_test.go index 4eaaaa5c..eaf19392 100644 --- a/internal/handlers/handler_verify_test.go +++ b/internal/handlers/handler_verify_test.go @@ -588,7 +588,29 @@ func TestSchemeIsHTTPS(t *testing.T) { assert.False(t, isSchemeHTTPS( GetURL("http://mytest.example.com/abc/?query=abc"))) + assert.False(t, isSchemeHTTPS( + GetURL("ws://mytest.example.com/abc/?query=abc"))) + assert.False(t, isSchemeHTTPS( + GetURL("wss://mytest.example.com/abc/?query=abc"))) assert.True(t, isSchemeHTTPS( GetURL("https://mytest.example.com/abc/?query=abc"))) } + +func TestSchemeIsWSS(t *testing.T) { + GetURL := func(u string) *url.URL { + x, err := url.ParseRequestURI(u) + require.NoError(t, err) + return x + } + + assert.False(t, isSchemeWSS( + GetURL("ws://mytest.example.com/abc/?query=abc"))) + assert.False(t, isSchemeWSS( + GetURL("http://mytest.example.com/abc/?query=abc"))) + assert.False(t, isSchemeWSS( + GetURL("https://mytest.example.com/abc/?query=abc"))) + assert.True(t, isSchemeWSS( + GetURL("wss://mytest.example.com/abc/?query=abc"))) + +}