https://docs.microsoft.com/en-us/dotnet/api/system.servicepr...
You've definitely outlined the risk clearly of allowing a client to specify anything arbitrarily.
I once wrote a sudo implementation for Windows Vista / Windows 7 and first attempt used named pipes communicating to a windows service that did some token manipulation to execute things as the user (but with elevated token attached as well). There be (security) dragons.
I like using named pipes and they are a great IPC mechanism for communicating amongst processes of the same privilege level. I would not use them for message passing between processes of different privilege levels.
The server needs to call ImpersonateNamedPipeClient() on the incoming client connection to assume the client’s security token, that would lower the server’s privilege to the level of the client. That’s it!
A guest level client can connect to the server. The server’s privilege becomes guest, and cannot access any resources that guest has no permission to access.
[1] https://docs.microsoft.com/en-us/windows/win32/api/namedpipe...
Then the only thing the user-mode application can send are just flags (integers) that the service has already pre-determined what it will do in response.
Here's an article: https://www.codeproject.com/Articles/24434/How-to-Write-Wind...
And here's a succinct example: https://stackoverflow.com/a/5805700
Consider that if a user-mode application can send messages to a privileged process (like a Windows service).
What prevents any user-mode application from doing that? And if your Windows service is running as "NT_AUTHORITY/SYSTEM" and even executes privileged commands, well you might find you've got a simple privilege escalation vuln.
Remember, secure your named pipes...especially when the named pipe server runs as SYSTEM.
- https://stackoverflow.com/a/59983266
- https://versprite.com/blog/security-research/vulnerable-name...