This is a question for operating system security experts.
We have an application using one platform/language, and it has to integrate with a library that uses another platform/language. There is no acceptable linking technology, and for unrelated reasons, we can't migrate either side to have both in a common platform/language.
The proposed solution is to wrap the library in an executable written in the same language of the library, spawn it from the parent application, and use the standard input and output pipes (stdin/stdout) to communicate.
We also have additional precautions, such as:
- The executable that links the library is always signed, and the parent application verifies the file signature before spawning the child process.
- The spawning of child process always uses the absolute path. We bypass the environment PATH variable.
- The parent and child applications are part of the same build and are always deployed together, and this is validated during handshake.
- The protocol is binary and we use either fixed-length or length-prefixed data in all encapsulations. If fixed-length, we always ensure full read before processing. If length-prefixed, we always validate the input length against boundaries, before reading variable-length data.
- The library host executable has no outstanding privilege. It is useless without credentials provided by the caller application. Without those credentials, a malicious actor cannot do anything with the child executable.
- No process is ever forked.
- Security precautions are in place for the machine (anti-malware installed, use only approved software, always headless mode, etc).
That said, given the integration is perhaps unusual in the organization's culture, some members of the team are suggesting a microservice instead, with encrypted TLS communication. The microservice approach feels overkill because it would expose endpoints and that requires proper network isolation, certificates, authentication, etc. Not to mention startup and reliability issues (the microservice would have to start independently, would need a watchdog, etc while the child process can start and terminate on-demand by the parent process).
The main point of contention is the use of the stdin and stdout pipes, and the fact that we don't encrypt this communication. To the best of my knowledge:
- The pipe data resides on a memory buffer that is only visible to the sides of the pipe (parent and child processes). The piped data is never persisted or cloned.
- Operating systems never automatically log or make it easy for administrators to capture pipe communication between two processes. There is not even a Linux or Windows configuration for that, and any tool would require administrative or kernel privileges, like a debugger.
Are those assumptions correct? I would like to learn from operating system experts if stdin and stdout traffic data between two processes is also deemed as sensitive as other forms of shared memory such as memory-mapped files, Unix domain sockets or Windows named pipes, in the sense that it's always well protected from other actors in the machine.