InfiniTec - Henning Krauses Blog

Don't adjust your mind - it's reality that is malfunctioning

Least privilege with Windows Services

Some actions in Windows require the logged on account to have certain privileges. A good explanation about these special permissions can be found on MSDN. The privilege assignment can viewed and modified through either Group Policy (on a domain) or the Local Security Policy (secpol.msc).


The privileges that an account has on a certain application can be monitored with the Process Explorer from Microsoft (former SysInternals). Here is an example of my explorer.exe:


The explorer has a number of privileges, bust most of them are disabled. The SeChangeNotifyPrivilege (which is called "Bypass traverse checking”) is the only one that is enabled by default. All other must be explicitly enabled before actions can be executed which are guarded by the respective privilege. But they also can be disabled for the lifetime of the process. Once turned off, they can’t be turned on again unless the process is restarted.

A rather important privilege, at least for WCF hosts and web server is the “Impersonate a client after authentication”.

Depending on the account your service and/or program is running, the account may have a number of privileges that are not required by your application or service. Especially since there are very mighty privileges such as the “Debug programs” or “Create global objects”. To comply with a least-privilege account, it is a good practice to turn off unnecessary privileges. This is especially true for services or applications which either utilize addins or exchange data over the network.

Unfortunately, there is no managed API available, but the required interop is not very hard. I have wrapped the whole stuff and it’s available from my InfiniTec.Common library. Currently, the latest version is available from CodePlex (its part of my Exchange Push Notification component. Just get the latest build or download the source from the repository). After you have added a reference to your service, it’s a matter of three lines of code to disable all expendable privileges:

   1: var priviliges = new PrivilegeCollection();
   2: priviliges.Refresh();
   3: priviliges.ReducePrivilegesToMinimum();

This call removes all unnecessary priviliges from the current process token. If you are hosting WCF services in your application and need to impersonate the caller, you should leave the “Impersonate a client after authentication” privilege intact. This requirement changes the code to the following three lines of code:

   1: var priviliges = new PrivilegeCollection();
   2: priviliges.Refresh();
   3: priviliges.ReducePrivilegesToMinimum(Privilege.Impersonate);

The InfiniTec.Security.Privilege class contains the internal names of most of the privileges in Windows, and the ReducePrivilegesToMinimum takes a string array as its first parameter, so it is very easy to keep multiple privileges intact.

Enabling a required privilege

It is not enough just to have a certain privilege to execute a secured operation. For example, to shutdown a computer it is not enough to have the "Shutdown the Computer” privilege. A program must explicitly enable it to call the InitiateShutdown function. This can also be easily achieved by executing these lines of code:

   1: var priviliges = new PrivilegeCollection();
   2: priviliges.Refresh();
   4: var privilege = priviliges[Privilege.Shutdown];
   5: privilege.Enable();


Posted by Henning Krause on Tuesday, June 16, 2009 4:23 PM, last modified on Monday, November 29, 2010 8:50 PM
Permalink | Post RSSRSS comment feed