[MISC] Add several logs to help users detect misconfiguration issues (#639)

* Help users detect misconfiguration of their protected domain.

Sometimes users try to visit an URL pointing to a domain which is
not protected by Authelia and thus authentication fails. This log
line will help users detect those cases.

* Add a log to detect bad schemes in target URLs.

This helps users detect when an URL is http while it should be https.
Indeed, cookies are transported solely over a secure connection for
security reasons.
pull/640/head
Clément Michaud 2020-02-18 23:39:07 +01:00 committed by GitHub
parent c578c8651d
commit 6390826618
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 0 deletions

View File

@ -14,6 +14,14 @@ import (
"github.com/valyala/fasthttp"
)
func isURLUnderProtectedDomain(url *url.URL, domain string) bool {
return strings.HasSuffix(url.Hostname(), domain)
}
func isSchemeHTTPS(url *url.URL) bool {
return url.Scheme == "https"
}
// 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()
@ -199,6 +207,20 @@ 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 "+
"only transported over a secure connection for security reasons", targetURL.String()))
ctx.ReplyUnauthorized()
return
}
if !isURLUnderProtectedDomain(targetURL, ctx.Configuration.Session.Domain) {
ctx.Logger.Error(fmt.Errorf("The target URL %s is not under the protected domain %s",
targetURL.String(), ctx.Configuration.Session.Domain))
ctx.ReplyUnauthorized()
return
}
var username string
var groups []string
var authLevel authentication.Level

View File

@ -556,3 +556,39 @@ func TestShouldURLEncodeRedirectionURLParameter(t *testing.T) {
assert.Equal(t, "Found. Redirecting to https://auth.mydomain.com?rd=https%3A%2F%2Ftwo-factor.example.com",
string(mock.Ctx.Response.Body()))
}
func TestIsDomainProtected(t *testing.T) {
GetURL := func(u string) *url.URL {
x, err := url.ParseRequestURI(u)
require.NoError(t, err)
return x
}
assert.True(t, isURLUnderProtectedDomain(
GetURL("http://mytest.example.com/abc/?query=abc"), "example.com"))
assert.True(t, isURLUnderProtectedDomain(
GetURL("http://example.com/abc/?query=abc"), "example.com"))
assert.True(t, isURLUnderProtectedDomain(
GetURL("https://mytest.example.com/abc/?query=abc"), "example.com"))
// cookies readable by a service on a machine is also readable by a service on the same machine
// with a different port as mentioned in https://tools.ietf.org/html/rfc6265#section-8.5
assert.True(t, isURLUnderProtectedDomain(
GetURL("https://mytest.example.com:8080/abc/?query=abc"), "example.com"))
}
func TestSchemeIsHTTPS(t *testing.T) {
GetURL := func(u string) *url.URL {
x, err := url.ParseRequestURI(u)
require.NoError(t, err)
return x
}
assert.False(t, isSchemeHTTPS(
GetURL("http://mytest.example.com/abc/?query=abc")))
assert.True(t, isSchemeHTTPS(
GetURL("https://mytest.example.com/abc/?query=abc")))
}