Files
rclone/backend/pcloud/pcloud_internal_test.go
Nick Craig-Wood 3760671b36 pcloud: only accept pCloud hosts from the hostname in the OAuth callback
When pCloud redirects the browser back to rclone's local OAuth
callback server it adds a `hostname` parameter saying which regional
API host (api.pcloud.com or eapi.pcloud.com) the account lives on.
rclone used this for the token exchange and saved it in the config as
the host for all of the remote's later traffic, without checking it.

This only accepts a well formed hostname within pCloud's own domain,
lower cased, failing the config with an error otherwise, and adds a
unit test for the check. This is defence in depth for GHSA-hvpr-p4pv-4f46
2026-10-08 22:49:33 +01:00

47 lines
1.2 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package pcloud
import (
"testing"
"github.com/stretchr/testify/assert"
)
// TestCallbackHostname checks that only hosts within pCloud's domain
// are accepted.
func TestCallbackHostname(t *testing.T) {
for _, test := range []struct {
in string
want string // "" means an error is expected
}{
{"", defaultHostname},
{"api.pcloud.com", "api.pcloud.com"},
{"eapi.pcloud.com", "eapi.pcloud.com"},
{"EAPI.pCloud.COM", "eapi.pcloud.com"},
{"new-region.api.pcloud.com", "new-region.api.pcloud.com"},
{"pcloud.com", ""},
{".pcloud.com", ""},
{"-.pcloud.com", ""},
{"a-.pcloud.com", ""},
{"a..pcloud.com", ""},
{"api.pcloud.com.", ""},
{"api.pclоud.com", ""}, // Cyrillic о
{"127.0.0.1:18443", ""},
{"evil.example.com", ""},
{"api.pcloud.com.evil.example.com", ""},
{"api.pcloud.com:443", ""},
{"api.pcloud.com/path", ""},
{"user@evil.example.com#.pcloud.com", ""},
{"evil.example.com?.pcloud.com", ""},
} {
t.Run("["+test.in+"]", func(t *testing.T) {
got, err := callbackHostname(test.in)
if test.want == "" {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
assert.Equal(t, test.want, got)
})
}
}