0

I am using a global EventWaitHandle to implement an inter-process handshake for a named pipe. The server (running as service with admin priviliges) opens the EventWaitHandle while the client checks for the open handle before connecting to the named pipe.

Using both with the same priviliges, its fine. Running the server as admin and client normal results in: System.UnauthorizedAccessException: Access to the path 'Global\DEMO_CONNECTION_OPEN_HANDLE' is denied.

I am using .NET Standard 2.0. Hence, simple solutions such as EventHandleRights are not available. Is there any way to set access rights (e.g. while creating the handle) or elevate the client code for the EventWaitHandle only?

Example code server:

var handshakeHandle = new EventWaitHandle(false, EventResetMode.ManualReset,
    String.Format(@"Global\{0}", $"{ConnectionName.ToUpper()}_CONNECTION_OPEN_HANDLE"));

CreateServerPipe(ConnectionName);

handshakeHandle.Set();
await serverStream.WaitForConnectionAsync();
handshakeHandle.Reset();

Example code client:

// Results in Exception:
var handshakeHandle = EventWaitHandle.OpenExisting(
    String.Format(@"Global\{0}", $"{ConnectionName.ToUpper()}_CONNECTION_OPEN_HANDLE"));

CreateClientPipe(ConnectionName);

if (!handshakeHandle.WaitOne(millisecondsTimeout))
    throw new TimeoutException($"Cannot access within timeout.");

clientStream.Connect(millisecondsTimeout);

Any hint is much appreciated!

Edit: Any recommendation for a different approach than EventWaitHandle to implement an inter-process handshake is welcome.

00zetti
  • 114
  • 8
  • 2
    .NET Standard is only used for libraries. This isn't a .NET Standard issue though. Normal and elevated applications can't communicate directly. Services *shouldn't* run with high privileges either. They should run under an account with minimal privileges that has permissions to just the things this service needs. Why are you trying to run your service as an administrator at all? Why not use the minimal `Local Service` account? Or a virtual account? – Panagiotis Kanavos Dec 16 '22 at 13:03
  • @PanagiotisKanavos I am writing a communication library. The server and client executables use it. The code above is the foundation. I got the request from a coworker who stumbled across this since we don't know under which cicurmstances any user might use this (e.g. using as system service). So this may be for discussion (for improvements), but the general question is still valid since we do not know how the user may use the lib. – 00zetti Dec 16 '22 at 13:34
  • You *should* know because it *does* affect the library. Applications on different privilege levels can't communicate just like that. That would be a huge security hole - some malware could sent commands to a privileged service and cause havoc. In any case [this was asked in the past](https://stackoverflow.com/questions/2590334/creating-a-cross-process-eventwaithandle). The answer is to specify looser access rules when creating the handle. That *does* affect the final service though, so it should be configurable. One could even see this as a potential vulnerability – Panagiotis Kanavos Dec 16 '22 at 13:46
  • @PanagiotisKanavos Unfortunately, the linked answer is not available anymore in .net standard, that's why I highlighted netstandard20. I'll try to build this as an extension from the decompiled .netframework version. – 00zetti Dec 16 '22 at 14:01
  • 1
    That's another problem with this requirement - .NET Standard is cross-platform but you ask for Windows-specific functionality. You can't use Windows-specific features in a cross-platform library. The NuGet packages that offer platform-specific features put the cross-platform pats in a .NET Standard assembly and include platform-specific features in runtime-specific assemblies – Panagiotis Kanavos Dec 16 '22 at 14:10
  • Why do you need a handshake for a named pipe at all? – Stephen Cleary Dec 16 '22 at 14:31
  • @StephenCleary While looking for potential attack vectors (unfortunately, I did't find the source right away), I stumbled across checking if a) there is an open pipe available and b) is this pipe created by a myself. So I check with the server, if there is an existing pipe, and with the client I check for the additional handshake to see if its my pipe (and the server is offering one). https://stackoverflow.com/questions/31848075/way-to-check-if-namedpipeserverstream-started-in-client-side – 00zetti Dec 16 '22 at 14:57

0 Answers0