NFS Backups and Xen Orchestra
-
I want to confirm a couple things about Xen Orchestra and NFS backups.
- Running Mount from XOA
When I go to Settings -> Remotes and try to add an NFS remote, it looks like Xen Orchestra wants to run
mount
on the XOA VM to mount it. That implies that the web server is running asroot
or the web server has the ability to invoke commands as root, because only root can mount filesystems. That seems decidedly suboptimal from a security point of view. If I run xo-web as root and there's an input validation error, then I not only have command injection, but I have commands injected that are running as root.Imagine someone types
ver=3; echo blah | tee -a /etc/shadow; :
or similar as their options on the NFS remote. That potentially executes as root and does something nasty (whereblah
is a correctly formatted /etc/shadow entry).I could potentially create a rule in my
/etc/sudoers
file to allow the unprivilegedwww
user to invoke/bin/mount
as root with no password, but I'm still not sure how exposed I would be to command injection. The risk is limited to that one command, but it's still sorta there. We'd have to change the mount command that is executed to besudo mount
, instead ofmount
.- Dataflow
If I follow the flow, the hypervisor will transmit the VM's data for backup to my XOA VM, who in turn writes it out to the NFS volume. If my XOA instance is not on the same network or host, that's a bad idea, right? I mean: it would be better for the host to do the NFS mount from the hypervisor and write the data out to the NFS share directly, wouldn't it? Even if my XOA VM is on the same host, the data is transmitted into the VM and back out again. Do I understand this correctly?
-
Hi,
- Ping @julien-f about this
- That's correct and there's a good reason to that. When we ask XenServer/XCP-ng to export a VM disk, it doesn't push data. It only expose an HTTP handler so we can pull data. Remember that we are doing everything through XAPI and there's 0 SSH calls. So there's no way to ask a host to push data to a NFS host. However, this limitation is solved by using XO proxies, which are available in XOA since last release See https://xen-orchestra.com/docs/proxy.html
-
Hi,
XO can use
sudo mount
: https://github.com/vatesfr/xen-orchestra/blob/bf763d2cf474293e5a0fa1f3a06fd1733a495b34/packages/xo-server/config.toml#L114I don't believe command injection is possible because
mount
is called directly, no shell is used to parse the command line. -
@julien-f Yeah, I have just found the
useSudo
option in the docs. I swear things change fast enough on xen orchestra that "upgrading" almost doesn't make sense. I rebuild it like every 3-6 months and so much changes that it's almost easier to start over. If I had started over and pretended I didn't know anything, I would have read the documentation and seen the useSudo option. That's not a complaint. Fast development and adding features is awesome. -
NodeJS is not my best language. But it looks
_mount.js
uses the execa library to wrap around standard child-process stuff.I did a little bit of code reading and it looks like, ultimately, execa and child-process-promise end up invoking child_process.spawn(), and it seems like spawn() is just an asynchronous wrapper around
child_process.exec()
. This leads me to believe that the input ultimately ends up on a shell command line.According to the docs I found:
child_process.exec()
: spawns a shell and runs a command within that shell, passing the stdout and stderr to a callback function when completeNow, both execa and the child-process-promise library do a lot of parsing of arguments. I can't tell to what extent that parsing and marshalling of command line arguments actually defeats injection attacks. I've done a lot of code review in my day, and sometimes I miss the line that does the work of defeating injection attacks because it is terse and effective. I might have looked right at it and misunderstood its importance.
Like I said, NodeJS and all the modules that are getting loaded in here to make this happen is difficult for me to follow. It's not my strong suit. Sorry if I'm wasting your time because I can't follow the code flow. It looks to me like it all boils down to exec(), and exec() by definition invokes the shell. But maybe we're protected by one of the argument marshalling functions in the call chain.
-
Unless the
shell
option is used, no shell interpreter (Bash,cmd.exe
, etc.) is used, so shell features such as variables substitution (echo $PATH
) are not allowed.-- https://github.com/sindresorhus/execa#execafile-arguments-options
AFAIU,
execa
usespawn
which does not do any arguments parsing, those are passed verbatim to the underlying command (probably via a call toexecvp
).If we would have used the
shell
option, this command would indeed run a shell which would have parsed the command line and therefore be susceptible to injection, but we are not using this -
@olivierlambert The proxy page has a pretty decent diagram for what things look like when there is no proxy. But it doesn't have a diagram for what things look like if there IS a proxy. I'm trying to understand it. Does this diagram capture the two situations?
If you're running 2 sites using a single instance of Xen Orchestra, is this what happens?
-
Indeed, it's on the blog post but not in the doc. It's:
As visible here: https://xen-orchestra.com/blog/backup-proxies/
I'm updating the doc right now.
-
Doc now updated with 2 pictures here: https://xen-orchestra.com/docs/proxy.html#architecture