mirror of
https://github.com/rclone/rclone.git
synced 2026-10-28 22:38:53 -04:00
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
47 lines
1.2 KiB
Go
47 lines
1.2 KiB
Go
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)
|
||
})
|
||
}
|
||
}
|