Let's suppose we have two containers running on a linux box and one has untrusted user data that the other needs to process. What is the most secure way to transfer this data? Is it better to write the data to a shared volume, or send it over the network, or...?
-
1Secure against what? What is your threat model? What asset are you protecting?– vidarloDec 29, 2022 at 15:32
-
I am trying to avoid someone being able to hack the machine because I moved the data in a way that they could exploit. I'm curious if Docker or Containerd might do something unsafe if I use a volume, for instance.– charles harrisDec 29, 2022 at 16:42
-
I wouldn't worry to much about moving the data, but rather using it.– vidarloDec 29, 2022 at 16:45
3 Answers
An important point in this is to realise that containers are essentially just processes running on a host.
Assuming you're using a solution that will always be single host (e.g. Docker with Docker compose), using something like a volume should be fine for most purposes. An attacker who gets privileged access to the host will be able to compromise both containers anyway, so there's no change in threat model by using a shared volume.
If you need more direct communications for your two applications, something like a UNIX socket shared between the two, could also be used, which avoids the need for having anything listening on the network.
All this gets more complex if you expect to ever have to run the two containers on different hosts (e.g. in a Kubernetes cluster) but for single host solutions, it's pretty straightfoward.
It looks like your focus is on making sure that the transfer of untrusted data does not harm the system, and not on preventing others to access the data.
Untrusted data are not a problem if they are only treated as binary objects. The problems instead happen if the data are treated as more than just a sequence of bytes, i.e. if they are interpreted or executed. Therefore the most secure method to transfer these data is to make sure that any parties involved in the transfer will treat the data only as a sequence of bytes without deeper interpretation or execution.
This can be achieved by A) limiting who can access the data and B) making sure that the access is secure (i.e. treated as byte sequence only). A point-to-point transfer like a network connection between producer and consumer of data limits the access to only these parties, so only these needs to be checked for B. When sharing the data with a file system or database there might be more processes involved which access the data (depending on the setup), which also means that more processes need to be checked to handle the data in a secure way.
The answer depends on what you mean by secure.
If the data are a text in some form (plain text, JSON, XML, YAML, HTML, JavaScript) and by secure you mean preventing cross-site-scripting it should be safe to display these data:
- The receiving container should validate if these data contain any script and refuse to accept it or sanitize such data, i.e. remove al pieces that look like code, e.g. remove JavaScript elements, HTML elements, etc.
If the data are binary files like MS Word, MS Excel, PDF and by secure you mean preventing malicious documents:
- Check these files by an antivirus
If the data are application code like .exe, .dll, .so, .sh, .jar and by secure you mean malicious executable code:
- Check these files by an antivirus
Independent on the nature of data:
- The receiving container should have some restrictions for the size of data packages (maximal request size if you use network, maximal file size if you use shared volume). Otherwise it may lead to resource exhaustion attacks.
- If not only the data contents represents risks, but also the sending container, then add also a limit for frequency of requests that the receiving container should accept to prevent resource exhaustion attacks.
-
I think this list misses one important perspective: the data itself might be harmful for its destination. E.g., an API that validates all inputs would help with that. Dec 30, 2022 at 12:34