Ch 11: Building Secure Serviced Components

Chapter 11 – Building Secure Serviced Components


Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

patterns & practices Developer Center

Improving Web Application Security: Threats and Countermeasures

J.D. Meier, Alex Mackman, Michael Dunner, Srinath Vasireddy, Ray Escamilla and Anandha Murukan
Microsoft Corporation

Published: June 2003

Last Revised: January 2006

Applies to:

  • Enterprise Services (.NET Framework version 1.1)

See the "patterns & practices Security Guidance for Applications Index" for links to additional security resources.

See the Landing Page Landing Page for the starting point and a complete overview of Improving Web Application Security: Threats and Countermeasures.

Summary: This chapter describes how to build secure serviced components for use in Enterprise Services applications. It shows you which assembly level attributes you should use to help automate COM+ catalog configuration. The chapter also covers authorization using COM+ roles and protecting sensitive data passed to and from remote serviced components.


In This Chapter
How to Use This Chapter
Threats and Countermeasures
Design Considerations
Configuration Management
Sensitive Data
Auditing and Logging
Building a Secure Serviced Component
Code Access Security Considerations
Deployment Considerations
Additional Resources

In This Chapter

  • Preventing anonymous access to serviced components
  • Protecting sensitive data
  • Authorizing callers by using Enterprise Services (COM+) roles
  • Using least privileged run-as accounts
  • Securing secrets in object constructor strings
  • Auditing from middle tier serviced components
  • Deployment considerations for serviced components


COM+ infrastructure services, also known as Enterprise Services, can be accessed from managed code. Enterprise Services applications consist of one or more serviced components that are managed classes derived from System.EnterpriseServices.ServicedComponent.

Serviced components are typically used to encapsulate an application's business and data access logic and are used when infrastructure services such as distributed transactions, object pooling, queued components, and others are required in an application's middle tier. Enterprise Services applications often reside on middle-tier application servers as shown in Figure 11.1.


Figure 11.1

Serviced components in a middle-tier Enterprise Services application

How to Use This Chapter

This chapter is developer focused and shows how to build secure serviced components.

To get the most of this chapter:

  • Use this chapter in conjunction with the Enterprise Services section in Chapter 17, "Securing Your Application Server." The section in Chapter 17 describes how to secure the Enterprise Services infrastructure and how to lock down your deployed Enterprise Services application.
  • Use the recommendations covered in Chapter 7, "Building Secure Assemblies." The chapter teaches you secure coding practices that can be applied when you develop serviced component code.

Threats and Countermeasures

The top threats that you must address when building serviced components are:

  • Network eavesdropping
  • Unauthorized access
  • Unconstrained delegation
  • Disclosure of configuration data
  • Repudiation

Figure 11.2 highlights these top threats together with common serviced component vulnerabilities.


Figure 11.2

Enterprise Services threats

Network Eavesdropping

Enterprise Services applications often run on middle-tier application servers, remote from the Web server. As a result, sensitive application data must be protected from network eavesdroppers. You can use an Internet Protocol Security (IPSec) encrypted channel between Web and application server. This solution is commonly used in Internet data centers. Serviced components also support remote procedure call (RPC) packet level authentication, which provides packet-based encryption. This is most typically used to secure communication to and from desktop-based clients.

Unauthorized Access

By enabling COM+ role-based authorization (it is disabled by default on Microsoft Windows 2000 and enabled on Windows Server 2003), you can prevent anonymous access and provide role-based authorization to control access to the restricted operations exposed by your serviced components.

Unconstrained Delegation

If you enable delegation on Windows 2000 to allow a remote server to access network resources using the client's impersonated token, the delegation is unconstrained. This means that there is no limit to the number of network hops that can be made. Microsoft Windows Server 2003 introduces constrained delegation.

Disclosure of Configuration Data

Many applications store sensitive data such as database connection strings in the COM+ catalog using object constructor strings. These strings are retrieved and passed to an object by COM+ when the object is created. Sensitive configuration data should be encrypted prior to storage in the catalog.


The repudiation threat arises when a user denies performing an operation or transaction, and you have insufficient evidence to counter the claim. Auditing should be performed across all application tiers. Serviced components should log user activity in the middle tier. Serviced components usually have access to the original caller's identity because front-end Web applications usually enable impersonation in Enterprise Services scenarios.

Design Considerations

Before you start writing code, there are a number of important issues to consider at design time. The key considerations are:

  • Role-based authorization
  • Sensitive data protection
  • Audit requirements
  • Application activation type
  • Transactions
  • Code access security

Role-Based Authorization

For effective role-based authorization using COM+ roles, ensure that the original caller's security context is used for the call to the serviced component. This allows you to perform granular role-based authorization based on the caller's group membership. If an ASP.NET Web application calls your serviced components, this means that the Web application needs to impersonate its callers before calling your component.

Sensitive Data Protection

If your serviced components handle sensitive data, such as employee details, financial transactions, and health records, consider how to protect the data as it crosses the network. If your application does not run in a secure Internet Data Center (IDC) environment, where IPSec provides transport level encryption, an alternative option is to use RPC encryption. For this you must use the Packet Privacy authentication level. For more information, see the "Sensitive Data" section later in this chapter.

Audit Requirements

To address the repudiation threat, sensitive transactions performed by Enterprise Service components should be logged. At design time, consider the type of operations that should be audited and the details that should be logged. At a minimum, this should include the identity that initiated the transaction and the identity used to perform the transaction, which may or may not be the same.

Application Activation Type

At design time, decide how your serviced component will be activated. You can activate them using an instance of the Dllhost.exe process or you can run them inside the client process. Server applications run out of process in an instance of Dllhost.exe. Library applications run in the client's process address space. Library applications are more efficient due to the lack of inter-process communication. However, they are less configurable and are not protected with process level isolation. Many security settings, such as the authentication and impersonation levels, are inherited from the client process.


If you plan to use distributed transactions, consider where the transaction is initiated and consider the implications of running transactions between components and resource managers separated by firewalls. In this scenario, the firewall must be configured to support the Microsoft Distributed Transaction Coordinator (DTC) traffic.

If your physical deployment architecture includes a middle-tier application server, it is generally preferable to initiate transactions from the Enterprise Services application on the application server and not from the front-end Web application.

Code Access Security

Typically, applications that use serviced components are fully trusted, and as a result code access security has limited use to authorize calling code. However, Enterprise Services demands that the calling code has the necessary permission to call unmanaged code. The main implication of this is that you will not be able to directly call into an Enterprise Services application from a partial trust Web application. The ASP.NET partial trust levels (High, Medium, Low, and Minimal) do not grant the unmanaged code permission. If you need to call a serviced component from a partial trust application, the privileged code that calls your component must be sandboxed. For more information, see "Code Access Security Considerations" later in this chapter.


Enterprise Services applications use Windows authentication. This is either NTLM or Kerberos authentication depending on the client and server operating system. In Windows 2000 or Windows Server 2003 environments, Kerberos authentication is used.

The main issue for you to consider when building serviced components is to ensure that all calls are authenticated to prevent anonymous users from accessing your component's functionality.

Use (At Least) Call Level Authentication

To reject anonymous callers, use at least call level authentication. Configure this setting by adding the following attribute to your serviced component assembly:

[assembly: ApplicationAccessControl(
                Authentication = AuthenticationOption.Call)]
Note   This is equivalent to setting Authentication level for calls to Call on the Security tab of the application's Properties dialog box in Component Services.


Enterprise Services uses COM+ roles for authorization. You can control the granularity of authorization to applications, components, interfaces, and methods. To prevent users from performing restricted operations exposed by your application's serviced components:

  • Enable role-based security.
  • Enable component level access checks.
  • Enforce component level access checks.

Enable Role-Based Security

Role-based security is disabled by default on Windows 2000. The reverse is true on Windows Server 2003. To ensure that role based security is automatically enabled when your component is registered (usually by using Regsvcs.exe), add the following attribute to your serviced component assembly.

[assembly: ApplicationAccessControl(true)]
Note   Using this attribute is equivalent to selecting Enforce access checks for this application on the Security tab of the application's Properties dialog box in Component Services.

Enable Component Level Access Checks

Component level access checks must be enabled in order to support component, interface, or method level role checks. To ensure that component level access checks are automatically enabled when your component is registered, add the following attribute to your serviced component assembly.

[assembly: ApplicationAccessControl(AccessChecksLevel=
Note   Using this attribute is equivalent to selecting Perform access checks at the process and component level on the Security tab of the application's Properties dialog box in Component Services.

Enforce Component Level Access Checks

To allow individual components to perform access checks, you must enforce component level access checks. This setting is only effective if the application-wide security level is set to the process and the component level as described above. To ensure that component level access checks are automatically enabled when your component is registered, add the following attribute to your serviced component classes.

public class YourServicedComponent : ServicedComponent
Note   Using this attribute is equivalent to selecting Enforce component level access checks on the Security tab of the component's Properties dialog box in Component Services.

Configuration Management

In addition to the configurable settings that COM+ provides to administrators through the Component Services tool, developers often perform configuration-related functions in code. For example, the functions might retrieve object construction strings stored in the COM+ catalog. Consider these main issues when you use configuration management with Enterprise Services:

  • Use least privileged run-as accounts.
  • Avoid storing secrets in object constructor strings.
  • Avoid unconstrained delegation.

Use Least Privileged Run-As Accounts

During development, run and test your service components using a least privileged local account instead of the interactive user account. Configure the account as closely as possible to match the run-as account that the administrator is likely to use in the production environment.

Avoid Storing Secrets in Object Constructor Strings

If you store secrets such as database connection strings or passwords in object constructor strings in the COM+ catalog, any member of the local administrators group can view this plaintext data. Try to avoid storing secrets. If you have to store a secret, then encrypt the data. DPAPI is a good implementation option because it allows you to avoid problems associated with key management.

At runtime, retrieve the object construction string and use DPAPI to decrypt the data. For more information about using DPAPI from managed code, see "How to create a DPAPI library" in MSDN article, "Building Secure ASP.NET Applications," at

Note   .NET 2.0 supports managed wrapper to DPAPI through ProtectedData class.
public class YourServicedComponent : ServicedComponent, ISomeInterface
  // The object constructor is called first.
  public YourServicedComponent() {}
  // Then the object construction string is passed to Construct method.
  protected override void Construct(string constructString)
    // Use DPAPI to decrypt the configuration data.

Avoid Unconstrained Delegation

Serviced component clients are authenticated with either NTLM or Kerberos authentication, depending on the environment. Kerberos in Windows 2000 supports delegation that is unconstrained; this means that the number of network hops that can be made with the client's credentials has no limit.

Windows Server 2003 introduces constrained delegation. This allows domain administrators to specify exactly which services can be accessed on a downstream server by a domain account using an impersonated user's security context.

If ASP.NET is the client then you can set the comImpersonation attribute on the <processModel> element in Machine.config to configure the impersonation level:


The impersonation level defined for an Enterprise Services server application determines the impersonation capabilities of any remote server that the serviced components communicate with. In this case, the serviced components are the clients.

You can specify the impersonation level for a serviced component, which applies when the service component is a client, using the following attribute:

[assembly: ApplicationAccessControl(
Note   Using this attribute is equivalent to setting the Impersonation Level value on the Security page of the application's Properties dialog within Component Services.

The following table describes the effect of each of these impersonation levels:

Table 11.1   Impersonation Levels

Impersonation LevelDescription
AnonymousThe server cannot identify the client.
IdentifyThis allows the server to identify the client and perform access checks using the client's access token
ImpersonateThis allows the server to gain access to local resources using the client's credentials
DelegateThis allows the server to access remote resources using the client's credentials (this requires Kerberos and specific account configuration)

For more information, see the "Impersonation" section in Chapter 17, "Securing Your Application Server" and "How to Enable Kerberos Delegation in Windows 2000" in the References section of MSDN article, "Building Secure ASP.NET Applications," at

For more information on using the constrained delegation feature in Windows Server 2003, see "How To: Use Protocol Transition and Constrained Delegation in ASP.NET 2.0."

Sensitive Data

If your application transmits sensitive data to and from a serviced component across a network, to address the network eavesdropping threat, the data should be encrypted to ensure it remains private and unaltered. You can use transport level protection with IPSec or you can use application level protection by configuring your Enterprise Services application to use the RPC packet privacy authentication level. This encrypts each packet of data sent to and from the serviced component to provide privacy and integrity.

You can configure packet privacy authentication using the Component Services tool or by adding the following attribute to your serviced component assembly:

[assembly: ApplicationAccessControl(
                   Authentication = AuthenticationOption.Privacy)]

For more information about using IPSec to encrypt all of the data transmitted between two computers, see "How To: Use IPSec to Provide Secure Communication Between Two Servers" in the "How To" section of "Microsoft patterns & practices Volume I, Building Secure ASP.NET Applications: Authentication, Authorization, and Secure Communication" at

Auditing and Logging

Auditing and logging should be performed across the tiers of your application to avoid potential repudiation threats where users deny performing certain transactions or key operations.

Audit User Transactions

If your Web application or Web service is configured for impersonation, the identity of the original caller automatically flows to an Enterprise Services application and is available using SecurityCallContext.OriginalCaller. This is useful for auditing in the middle tier. The following code shows how to access this information:

public class YourServicedComponent : ServicedComponent
  public void ShowCallers()
    SecurityCallers callers = SecurityCallContext.CurrentCall.Callers;
    foreach(SecurityIdentity id in callers)
  private void LogEvent(string message)
      EventLog.WriteEntry(appName, message, EventLogEntryType.Information );
    catch (SecurityException secex)
      throw new SecurityException(
            "Event source does not exist.", secex);

To successfully write to the event log, an event source must exist that associates the Enterprise Services application with a specific event log. If you want application specific event sources, you should create them at application installation time when administrative privileges are available. If you are unable to create event sources at installation time, and you are in deployment, the administrator can manually create new event source entry beneath the following registry key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\<LogName>.

Note   You should not grant write permission to the serviced component process account (or any impersonated account if your service component uses impersonation) on the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\ registry key. If you allow write access to this key and the account is compromised, the attacker can modify any log-related setting, including access control to the log, for any log on the system.

For more information about this approach, see "Auditing and Logging" in Chapter 10 "Building Secure ASP.NET Pages and Controls."

Building a Secure Serviced Component

Having covered the threats and countermeasures applicable to serviced components and Enterprise Services applications, the following code fragments illustrate the key characteristics of a secure serviced component for a simple Customer class implementation. Method implementation details have been omitted for the sake of clarity.

Assembly Implementation

The following code fragment from assemblyinfo.cs shows the assembly level metadata used to configure the COM+ catalog when the serviced component assembly is registered with Enterprise Services using regsvcs.exe.

// (1) Assembly has a strong name.
[assembly: AssemblyKeyFile(@"..\..\Customer.snk")]

// Enterprise Services configuration
[assembly: ApplicationName("CustomerService")]
[assembly: Description("Customer Services Application")]
// (2) Server application - runs in dllhost.exe process instance.
[assembly: ApplicationActivation(ActivationOption.Server)]
// (3) Enable component level access checks.
// (4) Specify call level authentication.
// (5) Specify Identify impersonation level for downstream calls.
[assembly: ApplicationAccessControl(

The code shown above exhibits the following security characteristics (identified by the numbers in the comment lines).

  1. The assembly is strong named. This is a mandatory requirement for serviced components. The added benefit from a security perspective is that the assembly is digitally signed. This means that any modification by an attacker will be detected and the assembly will fail to load.
  2. The application is configured to run as a server application in a dedicated instance of dllhost.exe. This allows you to specify the least privileged run-as identity at deployment time.
  3. The application is configured to support component level access checks. This allows you to authorize callers based on role membership at the class, interface, and method levels.
  4. Call level authentication is specified. This means that each method call from a client is authenticated.
  5. The impersonation level for outgoing calls from this serviced component to other components on remote servers is set to Identify. This means that the downstream component can identify the caller but cannot perform impersonation.
    Note   The impersonation level for a calling ASP.NET Web application or Web service client is specified on the <processModel> element in Machine.config on the client Web server.

Serviced Component Class Implementation

The following code fragment highlights the security configuration of a partially implemented Customer class.

namespace busCustomer
  // (1) Explicit interface definition to support method level authorization
  public interface ICustomerAdmin
    void CreditAccountBalance(string customerID, double amount);
  // (2) Enforce component level access checks.
  public sealed class Customer : ServicedComponent, ICustomerAdmin
    private string appName = "Customer";
    private string eventLog = "Application";
    // ICustomer implementation
    // (3) Access to CreditAccountBalance is limited to members of the
    //     Manager and Senior Manager role.
    [SecurityRole("Senior Manager")]
    public void CreditAccountBalance(string customerID, double amount)
      // (4) Structured exception handling to protect implementation.
        // (5) Check that security is enabled.
        if (ContextUtil.IsSecurityEnabled)
          // Only managers can credit accounts with sums of money
          // in excess of $1,000.
          if (amount > 1000) {
            // (6) Programmatic role check to authorize credit operation
            if (ContextUtil.IsCallerInRole("Senior Manager")) {
              // Call data access component to update database.
              . . .
              // (7) Audit the transaction.
              AuditTransaction(customerID, amount);
            else {
              throw new SecurityException("Caller not authorized");
        else {
          throw new SecurityException("Security is not enabled");

      catch( Exception ex)
        // Log exception details.
        throw new Exception("Failed to credit account balance for customer: " +
                             customerID, ex);
    private void AuditTransaction(string customerID, double amount)
      // (8) Original caller identity is obtained from call context for
      //     logging purposes.
      SecurityIdentity caller = SecurityCallContext.CurrentCall.OriginalCaller;
        if (!EventLog.SourceExists(appName))
        StringBuilder logmessage = new StringBuilder();
        logmessage.AppendFormat("{0}User {1} performed the following transaction"
                               + "{2} Account balance for customer {3} "
                               + "credited by {4}",
                                Environment.NewLine, caller.AccountName,
                                Environment.NewLine, customerID, amount);
        EventLog.WriteEntry(appName, logmessage.ToString(),
      catch(SecurityException secex)
        throw new SecurityException(
                   "Event source does not exist and cannot be created", secex);

The code shown above exhibits the following security characteristics (identified by the numbers in the comment lines):

  1. An interface is defined and implemented explicitly to support interface and method level authorization with COM+ roles.
  2. Component level access checks are enabled for the class by using the [ComponentAccessControl] attribute at the class level.
  3. The [SecurityRole] attribute is used on the CreditAccountBalance method to restrict access to members of the Manager or Senior Managers role.
  4. Structured exception handling is used to protect implementation. Exceptions are caught, logged, and an appropriate exception is propagated to the caller.
  5. The code checks whether or not security is enabled prior to the explicit role check. This is a risk mitigation strategy to ensure that transactions cannot be performed if the application security configuration is inadvertently or deliberately disabled by an administrator.
    Note   The IsCallerInRole method always returns "true" if security is disabled.
  6. Callers must be members of either the Manager or Senior Manager role because of the declarative security used on the method. For fine-grained authorization, the role membership of the caller is explicitly checked in code.
  7. The transaction is audited.
  8. The audit implementation obtains the identity of the original caller by using the SecurityCallContext object.

Code Access Security Considerations

Applications that use serviced components are usually fully trusted and, as a result, code access security has limited use to authorize calling code. The calling code should consider the following points:

  • Unmanaged code permission is required to activate and perform cross context calls on serviced components.
  • If the client of a serviced component is an ASP.NET Web application, then its trust level must be set to "Full" as shown below.
    <trust level="Full" />

    If your Web application is configured with a trust level other than "Full," it does not have the unmanaged code permission. In this instance, you must create a sandboxed wrapper assembly to encapsulate the communication with the serviced component. You must also configure code access security policy to grant the wrapper assembly the unmanaged code permission. For more information about the sandboxing technique used to encapsulate high privileged code, see Chapter 9, "Using Code Access Security with ASP.NET."

  • If a reference to a serviced component is passed to untrusted code, methods defined on the serviced component cannot be called from the untrusted code. The exception to this rule is with methods than do not require context switching or interception services and do not call members of System.EnterpriseServices. Such methods can be called by untrusted code.

Deployment Considerations

Enterprise Services applications are typically installed on the Web server or on a remote application server. Figure 11.3 shows the two typical deployment scenarios for Enterprise Services. From a security perspective, the notable difference with the remote deployment scenario is that data passed to and from the serviced component is passed over the network, often through an internal firewall used to separate the internal and perimeter networks.


Figure 11.3

Enterprise Services typical deployment configurations

Developers and administrators need to be aware of the following deployment-related issues:

  • Firewall restrictions, including port requirements for DCOM and DTC
  • Run-as account configuration
  • Storing secrets in object constructor strings

For more information about applying secure configuration at deployment time, see Chapter 17, "Securing Your Application Server."

Firewall Restrictions

If the client and Enterprise Services application are separated by an internal firewall, the relevant ports that support DCOM and possibly the DTC (if your application uses distributed transactions) must be open.

DCOM uses RPC dynamic port allocation that by default randomly selects port numbers above 1024. In addition, port 135 is used by the RPC endpoint mapper. You can restrict the ports required to support DCOM on the internal firewall in two ways:

  • Define port ranges.

    This allows you to control the ports dynamically allocated by RPC.

  • Use static endpoint mapping.

    Windows 2000 SP3 (or Quick Fix Engineering [QFE] 18.1 and greater) or Windows Server 2003 allow you to configure Enterprise Services applications to use a static endpoint. Static endpoint mapping means that you only need to open two ports in the firewall. Specifically, you must open port 135 for RPC and a nominated port for your Enterprise Services application.

For more information about defining port ranges and static endpoint mapping, see "Firewall Considerations in Chapter 17, "Securing Your Application Server."

Using Web Services

If opening ports on the internal firewall is not an option, then you can introduce a Web services façade layer in front of the serviced components on the application server. This means that you only need to open port 80 for HTTP traffic and specifically for Simple Object Access Protocol (SOAP) messages to flow in both directions as shown in Figure 11.4.


Figure 11.4

Using a Web services fa&#231ade; layer to communicate with Enterprise Services using HTTP

This approach does not allow you to flow transaction context from client to server, although in many cases where your deployment architecture includes a middle-tier application server, it is appropriate to initiate transactions in the remote serviced component on the application server.

For information about physical deployment requirements for service agents and service interfaces such as the Web services façade layer, see "Physical Deployment and Operational Requirements" in the Reference section of the MSDN article, "Application Architecture for .NET: Designing Applications and Services."

DTC Requirements

If your application uses COM+ distributed transactions and these are used across remote servers separated by an internal firewall, then the firewall must open the necessary ports to support DTC traffic.

If your deployment architecture includes a remote application tier, transactions are usually initiated within the Enterprise Services application and propagated to the database server. In the absence of an application server, the Enterprise Services application on the Web server initiates the transaction and propagates it to the SQL Server resource manager.

For information about configuring firewalls to support DTC traffic, see Chapter 18, "Securing Your Database Server."


Enterprise Services (COM+) security relies on Windows security to authenticate and authorize callers. Authorization is configured and controlled with COM+ roles that contain Windows group or user accounts. The majority of threats that relate to Enterprise Services applications and serviced components can be addressed with solid coding techniques, and appropriate catalog configuration.

The developer should use declarative attributes to set the serviced component security configuration. These attributes determine how the application is configured when it is initially registered with Enterprise Services (typically using Regsvcs.exe).

Not every security configuration setting can be set with attributes. An administrator must specify the run-as identity for a server application. The administrator must also populate roles with Windows group or user accounts at deployment time.

When you are developing serviced components or are evaluating the security of your Enterprise Security solution, use "Checklist: Securing Enterprise Services" in the "Checklists" section of this guide.

Additional Resources

For more information, see the following resources:

  • For a printable checklist, see Checklist: Securing Enterprise Services in the Checklists section of this guide.
  • For information on authentication, authorization and secure communication for Enterprise Services see "Enterprise Services Security" in "Microsoft patterns & practices Volume I, Building Secure ASP.NET Applications: Authentication, Authorization, and Secure Communication" at
  • For frequently asked questions regarding Enterprise Services, see "Enterprise Services FAQ" at [Content link no longer available, original URL:""] .
  • For background on Enterprise Services, see MSDN article, "Understanding Enterprise Services (COM+) in .NET," at

patterns & practices Developer Center

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

© 2016 Microsoft