NFS Backups and Xen Orchestra



  • I want to confirm a couple things about Xen Orchestra and NFS backups.

    1. 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 as root 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 (where blah is a correctly formatted /etc/shadow entry).

    I could potentially create a rule in my /etc/sudoers file to allow the unprivileged www 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 be sudo mount, instead of mount.

    1. 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?


  • XCP-ng Team

    Hi,

    1. Ping @julien-f about this
    2. 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

  • XO Team

    Hi,

    XO can use sudo mount: https://github.com/vatesfr/xen-orchestra/blob/bf763d2cf474293e5a0fa1f3a06fd1733a495b34/packages/xo-server/config.toml#L114 🙂

    I 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 complete

    Now, 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.


  • XO Team

    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 use spawn which does not do any arguments parsing, those are passed verbatim to the underlying command (probably via a call to execvp).

    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?
    xoa-backup.png


  • XCP-ng Team

    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.


  • XCP-ng Team

    Doc now updated with 2 pictures here: https://xen-orchestra.com/docs/proxy.html#architecture


Log in to reply
 

XCP-ng Pro Support

XCP-ng Pro Support