mirror of
https://github.com/rclone/rclone.git
synced 2026-10-28 06:18:39 -04:00
fstests: check a root starting with // can't move the remote to another host GHSA-xqmq-v4wj-rw5m CVE-PENDING
Add an integration test which starts a listener on localhost, makes the remote with roots naming that listener and checks that nothing connects to it. The listener replies with junk so a backend which does connect fails at once rather than retrying a closed connection.
This commit is contained in:
1 parent
28562c8a79
commit
f33fa3872f
1 file changed
+45
@@ -597,6 +597,51 @@ func Run(t *testing.T, opt *Opt) {
|
||||
}
|
||||
})
|
||||
|
||||
// TestFsRootCannotChangeHost tests that a root beginning with //
|
||||
// is treated as a path and can't move the remote to a host of the
|
||||
// attacker's choosing.
|
||||
//
|
||||
// A root beginning with // is a network-path reference under the
|
||||
// URL standard so a backend which resolves its root as a URL
|
||||
// reference against a configured URL could send requests, and
|
||||
// whatever credentials go with them, to the host named in the root.
|
||||
t.Run("FsRootCannotChangeHost", func(t *testing.T) {
|
||||
skipIfNotOk(t)
|
||||
if !strings.HasSuffix(remoteName, ":") {
|
||||
t.Skip("root of a path based remote can't be a network-path reference")
|
||||
}
|
||||
ln, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
require.NoError(t, err)
|
||||
defer func() { _ = ln.Close() }()
|
||||
var connections atomic.Int32
|
||||
go func() {
|
||||
for {
|
||||
conn, err := ln.Accept()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
connections.Add(1)
|
||||
// Reply with junk so the client fails at once rather than retrying a closed connection
|
||||
_, _ = conn.Write([]byte("\x00\xff\x00\xff junk\n"))
|
||||
_ = conn.Close()
|
||||
}
|
||||
}()
|
||||
host := ln.Addr().String()
|
||||
for _, root := range []string{
|
||||
"//" + host + "/",
|
||||
"//" + host + "/" + subRemoteLeaf + "/",
|
||||
"//user:pass@" + host + "/",
|
||||
} {
|
||||
remote := remoteName + root
|
||||
f, err := fs.NewFs(context.Background(), remote)
|
||||
if err == nil {
|
||||
// Not all backends contact the remote in NewFs
|
||||
_, _ = f.List(context.Background(), "")
|
||||
}
|
||||
assert.Equal(t, int32(0), connections.Load(), "remote %q connected to the host named in its root", remote)
|
||||
}
|
||||
})
|
||||
|
||||
// TestFsRmdirEmpty tests deleting an empty directory
|
||||
t.Run("FsRmdirEmpty", func(t *testing.T) {
|
||||
skipIfNotOk(t)
|
||||
|
||||
Reference in new issue
Block a user