.NET Framework 2.0 Security Guidelines - Threading

From Guidance Share

Jump to: navigation, search

- J.D. Meier, Alex Mackman, Blaine Wastell, Prashant Bansode, Chaitanya Bijwe


Contents

Do not cache the results of security checks

If your multithreaded code caches the results of a security check, perhaps in a static variable, the code is potentially vulnerable, as shown in the following example.

public void AccessSecureResource()
{
 callerOK = PerformSecurityDemand();
 OpenAndWorkWithResource();
 callerOK = false;
}
private void OpenAndWorkWithResource()
{
 if (callerOK)
   PerformTrustedOperation();
 else
 {
   PerformSecurityDemand();
   PerformTrustedOperation();
 }
}

If your code has other paths to OpenAndWorkWithResource, and a separate thread calls the method on the same object, it is possible for the second thread to omit the security demand because it encounters callerOK=true, set by another thread.


Avoid losing impersonation tokens

In .NET Framework 1.1, impersonation tokens did not automatically flow to newly created threads. This situation could lead to security vulnerabilities because new threads assume the security context of the process. In .NET Framework 2.0, by default the impersonation token still does not flow across threads, but for ASP.NET applications you can change this default behavior by configuring the ASPNET.config file in the %Windir%Microsoft.NET\Framework\{Version} directory.


If you need to flow the impersonation token to new threads, set the enabled attribute to true on the alwaysFlowImpersonationPolicy element in the ASPNET.config file, as shown in the following example.

<configuration>
 <runtime>
   <alwaysFlowImpersonationPolicy enabled="true"/>
    </runtime>
</configuration>

If you need to prevent impersonation tokens from being passed to new threads programmatically, you can use the ExecutionContext.SuppressFlow method.


Synchronize static class constructors

If you use static class constructors, make sure that they are not vulnerable to race conditions. If, for example, they manipulate static state, add thread synchronization to avoid potential vulnerabilities.


Synchronize Dispose methods

If you develop non-synchronized Dispose implementations, the Dispose code could be called more than once on separate threads. The following code shows an example of this.

void Dispose()
{
 if (null != theObject)
 {
   ReleaseResources(theObject);
   theObject = null;
 }
}

In this example, it is possible for two threads to execute the code before the first thread has set theObject reference to null. Depending on the functionality provided by the ReleaseResources method, security vulnerabilities could occur.

Personal tools