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(               AccessChecksLevel=AccessChecksLevelOption.ApplicationComponent,               Authentication=AuthenticationOption.Call,               ImpersonationLevel=ImpersonationLevelOption.Identify)] 

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.   [ComponentAccessControl]   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("Manager")]     [SecurityRole("Senior Manager")]     public void CreditAccountBalance(string customerID, double amount)     {       // (4) Structured exception handling to protect implementation.       try       {         // (5) Check that security is enabled.         if (ContextUtil.IsSecurityEnabled)         {           // Only managers can credit accounts with sums of money           // in excess of ,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;       try       {         if (!EventLog.SourceExists(appName))         {           EventLog.CreateEventSource(appName,eventLog);         }         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(),                             EventLogEntryType.Information);       }       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.




Improving Web Application Security. Threats and Countermeasures
Improving Web Application Security: Threats and Countermeasures
ISBN: 0735618429
EAN: 2147483647
Year: 2003
Pages: 613

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net