Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Securing the named pipe used by WCF

am newbie to both WCF and Named pipes.

I need a way to securely communicate between a UI application and Windows Service on the same machine. Here's what I need: - Client UI application needs to send (push) various message types to the Windows Service. - Client UI app needs will receive various message types from the service (pushed or pulled).

(message here is simply a structured serialized data).

Now all this exchange should happen only under authorized user account (which might be different from service account). So I was thinking of ACLing a named pipe for both the service and user account.

However, the named pipe supports streams only. I have multiple types of messages that need to be exchanged over the named pipe, which means I need to define them and serialize/deserialize them.

To circumvent this, I thought of using WCF (for serialization and RPC support) over named pipes. Also host WCF service in the Windows service.

Question 1) Is this a good approach ? I hesitate in using http or tcp below WCF as communication must remain within the machine.

Question 2) If and how can I ACL the named pipe that WCF would use ? Is this something that I can control ? I feel ACLing the name pipe with specific SIDs provides me better security as opposed to implementing an authentication scheme between client and server.

Thanks for any pointers, suggestions! Sameer

like image 252
Sameer Avatar asked Feb 25 '11 21:02

Sameer


2 Answers

1) I think this is a good approach. Your thinking is spot on.

2) As you seem to have already discovered, my blog post here shows you one way to set the ACL on the pipe created by the WCF NetNamedPipe binding. It involves using reflection to fill in the gap in the Microsoft's implementation, which was obviosuly intended originally to support a direct mechanism for setting the ACL, but didn't get finished properly.

Derive a AclSecuredNamedPipeBinding from CustomBinding and a corresponding AclSecuredNamedPipeTransportBindingElement from NamedPipeTransportBindingElement. The binding element has a list of of SecurityIdentifier:

internal List<SecurityIdentifier> AllowedUsers { get { return _allowedUsers; } }
private List<SecurityIdentifier> _allowedUsers = new List<SecurityIdentifier>();

The BuildChannelListener<TChannel>(BindingContext)-method is overridden to set the private property AllowedUsers:

public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
{
  private static Type namedPipeChannelListenerType 
          = Type.GetType("System.ServiceModel.Channels.NamedPipeChannelListener, System.ServiceModel", false);
  IChannelListener<TChannel> listener = base.BuildChannelListener<TChannel>(context);
  PropertyInfo p = namedPipeChannelListenerType.GetProperty(
          "AllowedUsers", BindingFlags.Instance|BindingFlags.NonPublic);
  p.SetValue(listener, _allowedUsers, null);
  return listener;
}

If you go this route, be sure also to patch the "squatting vulnerability" as explained in a later post.

like image 130
Chris Dickson Avatar answered Sep 28 '22 00:09

Chris Dickson


Came across these posts which is very helpful: Exploring the WCF Named Pipe Binding - Part 3 - Chris Dickson's Blog

like image 21
Sameer Avatar answered Sep 28 '22 00:09

Sameer