Force HTTPS for backend connections in old-style configurations.

Prevents clients from sending a HTTP auth URL to trigger an insecure
connection from the signaling server to Nextcloud.
This commit is contained in:
Joachim Bauch 2021-07-07 09:16:59 +02:00
parent 2662d49017
commit ec71f29fee
No known key found for this signature in database
GPG Key ID: 77C1D22D53E15F02
5 changed files with 66 additions and 1 deletions

View File

@ -87,6 +87,9 @@ func TestPostOnRedirect(t *testing.T) {
config := goconf.NewConfigFile()
config.AddOption("backend", "allowed", u.Host)
config.AddOption("backend", "secret", string(testBackendSecret))
if u.Scheme == "http" {
config.AddOption("backend", "allowhttp", "true")
}
client, err := NewBackendClient(config, 1, "0.0")
if err != nil {
t.Fatal(err)

View File

@ -41,6 +41,8 @@ type Backend struct {
secret []byte
compat bool
allowHttp bool
maxStreamBitrate int
maxScreenBitrate int
@ -61,6 +63,17 @@ func (b *Backend) IsCompat() bool {
return b.compat
}
func (b *Backend) IsUrlAllowed(u *url.URL) bool {
switch u.Scheme {
case "https":
return true
case "http":
return b.allowHttp
default:
return false
}
}
func (b *Backend) AddSession(session Session) error {
if session.ClientType() == HelloClientTypeInternal || session.ClientType() == HelloClientTypeVirtual {
// Internal and virtual sessions are not counting to the limit.
@ -102,6 +115,7 @@ type BackendConfiguration struct {
func NewBackendConfiguration(config *goconf.ConfigFile) (*BackendConfiguration, error) {
allowAll, _ := config.GetBool("backend", "allowall")
allowHttp, _ := config.GetBool("backend", "allowhttp")
commonSecret, _ := config.GetString("backend", "secret")
sessionLimit, err := config.GetInt("backend", "sessionlimit")
if err != nil || sessionLimit < 0 {
@ -116,6 +130,8 @@ func NewBackendConfiguration(config *goconf.ConfigFile) (*BackendConfiguration,
secret: []byte(commonSecret),
compat: true,
allowHttp: allowHttp,
sessionLimit: uint64(sessionLimit),
}
if sessionLimit > 0 {
@ -150,6 +166,8 @@ func NewBackendConfiguration(config *goconf.ConfigFile) (*BackendConfiguration,
secret: []byte(commonSecret),
compat: true,
allowHttp: allowHttp,
sessionLimit: uint64(sessionLimit),
}
hosts := make([]string, 0, len(allowMap))
@ -286,6 +304,8 @@ func getConfiguredHosts(backendIds string, config *goconf.ConfigFile) (hosts map
url: u,
secret: []byte(secret),
allowHttp: parsed.Scheme == "http",
maxStreamBitrate: maxStreamBitrate,
maxScreenBitrate: maxScreenBitrate,
@ -341,6 +361,10 @@ func (b *BackendConfiguration) GetBackend(u *url.URL) *Backend {
s += "/"
}
for _, entry := range entries {
if !entry.IsUrlAllowed(u) {
continue
}
if entry.url == "" {
// Old-style configuration, only hosts are configured.
return entry

View File

@ -101,6 +101,28 @@ func TestIsUrlAllowed_Compat(t *testing.T) {
}
config := goconf.NewConfigFile()
config.AddOption("backend", "allowed", "domain.invalid")
config.AddOption("backend", "allowhttp", "true")
config.AddOption("backend", "secret", string(testBackendSecret))
cfg, err := NewBackendConfiguration(config)
if err != nil {
t.Fatal(err)
}
testUrls(t, cfg, valid_urls, invalid_urls)
}
func TestIsUrlAllowed_CompatForceHttps(t *testing.T) {
// Old-style configuration, force HTTPS
valid_urls := []string{
"https://domain.invalid",
}
invalid_urls := []string{
"http://domain.invalid",
"http://otherdomain.invalid",
"https://otherdomain.invalid",
"domain.invalid",
}
config := goconf.NewConfigFile()
config.AddOption("backend", "allowed", "domain.invalid")
config.AddOption("backend", "secret", string(testBackendSecret))
cfg, err := NewBackendConfiguration(config)
if err != nil {
@ -119,22 +141,32 @@ func TestIsUrlAllowed(t *testing.T) {
{"https://domain.invalid/bar/", string(testBackendSecret) + "-bar"},
{"https://domain.invalid:443/bar/", string(testBackendSecret) + "-bar"},
{"https://domain.invalid/bar/folder/", string(testBackendSecret) + "-bar"},
{"http://domain.invalid/baz", string(testBackendSecret) + "-baz"},
{"http://domain.invalid/baz/", string(testBackendSecret) + "-baz"},
{"http://domain.invalid:80/baz/", string(testBackendSecret) + "-baz"},
{"http://domain.invalid/baz/folder/", string(testBackendSecret) + "-baz"},
{"https://otherdomain.invalid/", string(testBackendSecret) + "-lala"},
{"https://otherdomain.invalid/folder/", string(testBackendSecret) + "-lala"},
}
invalid_urls := []string{
"http://domain.invalid",
"http://domain.invalid/",
"https://domain.invalid",
"https://domain.invalid/",
"http://domain.invalid/foo",
"http://domain.invalid/foo/",
"https://domain.invalid:8443/foo/",
"https://www.domain.invalid/foo/",
"https://domain.invalid/baz/",
}
config := goconf.NewConfigFile()
config.AddOption("backend", "backends", "foo, bar, lala, missing")
config.AddOption("backend", "backends", "foo, bar, baz, lala, missing")
config.AddOption("foo", "url", "https://domain.invalid/foo")
config.AddOption("foo", "secret", string(testBackendSecret)+"-foo")
config.AddOption("bar", "url", "https://domain.invalid:443/bar/")
config.AddOption("bar", "secret", string(testBackendSecret)+"-bar")
config.AddOption("baz", "url", "http://domain.invalid/baz")
config.AddOption("baz", "secret", string(testBackendSecret)+"-baz")
config.AddOption("lala", "url", "https://otherdomain.invalid/")
config.AddOption("lala", "secret", string(testBackendSecret)+"-lala")
cfg, err := NewBackendConfiguration(config)

View File

@ -77,6 +77,9 @@ func CreateBackendServerForTestFromConfig(t *testing.T, config *goconf.ConfigFil
t.Fatal(err)
}
config.AddOption("backend", "allowed", u.Host)
if u.Scheme == "http" {
config.AddOption("backend", "allowhttp", "true")
}
config.AddOption("backend", "secret", string(testBackendSecret))
config.AddOption("sessions", "hashkey", "12345678901234567890123456789012")
config.AddOption("sessions", "blockkey", "09876543210987654321098765432109")

View File

@ -68,6 +68,9 @@ func getTestConfig(server *httptest.Server) (*goconf.ConfigFile, error) {
return nil, err
}
config.AddOption("backend", "allowed", u.Host)
if u.Scheme == "http" {
config.AddOption("backend", "allowhttp", "true")
}
config.AddOption("backend", "secret", string(testBackendSecret))
config.AddOption("sessions", "hashkey", "12345678901234567890123456789012")
config.AddOption("sessions", "blockkey", "09876543210987654321098765432109")