We recommend using Visual Studio 2017

Checklist: Security Review for Managed Code


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

Applies to:

  • .NET Framework version 1.1

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

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


How to Use This Checklist General Code Review Guidelines Managed Code Review Guidelines Resource Access Considerations Code Access Security Considerations

How to Use This Checklist

This checklist is a companion to Chapter 7, "Building Secure Assemblies", and Chapter 8, "Code Access Security in Practice." Use it to help you implement a security review for managed code in your Web application, or as a quick evaluation snapshot of the corresponding chapters.

This checklist should evolve so that you can repeat a successful security review of managed code.

General Code Review Guidelines

Ff648189.z02bthcm01(en-us,PandP.10).gifPotential threats are clearly documented. (Threats are dependent upon the specific scenario and assembly type.)
Ff648189.z02bthcm01(en-us,PandP.10).gifCode is developed based on .NET framework coding guidelines and secure coding guidelines at http://msdn.microsoft.com/en-us/library/czefa0ke(VS.71).aspx.
Ff648189.z02bthcm01(en-us,PandP.10).gifThe FXCop analysis tool is run on assemblies and security warnings are addressed.

Managed Code Review Guidelines

Assembly-Level Checks

Ff648189.z02bthcm01(en-us,PandP.10).gifAssemblies have a strong name. (Dynamically generated ASP.NET Web page assemblies cannot currently have a strong name.)
Ff648189.z02bthcm01(en-us,PandP.10).gifYou have considered delay signing as a way to protect and restrict the private key that is used in the strong name and signing process.
Ff648189.z02bthcm01(en-us,PandP.10).gifAssemblies include declarative security attributes (with SecurityAction.RequestMinimum) to specify minimum permission requirements.
Ff648189.z02bthcm01(en-us,PandP.10).gifHighly privileged assemblies are separated from lower privileged assemblies.

If the assembly is to be used in a partial-trust environment (for example, it is called from a partial-trust Web application), then privileged code is sandboxed in a separate assembly.

Class-Level Checks

Ff648189.z02bthcm01(en-us,PandP.10).gifClass and member visibility is restricted. The most restrictive access modifier is used (private where possible).
Ff648189.z02bthcm01(en-us,PandP.10).gifNon-base classes are sealed if they contain security secrets (like passwords) accessible through protected APIs or if they contain many virtual members that cannot be sealed and the type is not really designed for third-party extensibility.
Ff648189.z02bthcm01(en-us,PandP.10).gifInput from outside the current trust boundary is validated. Input data is constrained and validated for type, length, format, and range.
Ff648189.z02bthcm01(en-us,PandP.10).gifCode implements declarative checks where virtual internal methods are used.
Ff648189.z02bthcm01(en-us,PandP.10).gifAccess to public classes and methods are restricted with principal permission demands (where appropriate).
Ff648189.z02bthcm01(en-us,PandP.10).gifFields are private. When necessary, field values are exposed by using read/write or read-only public properties.
Ff648189.z02bthcm01(en-us,PandP.10).gifRead-only properties are used where possible.
Ff648189.z02bthcm01(en-us,PandP.10).gifTypes returned from methods that are not designed to be created independently contain private default constructors.
Ff648189.z02bthcm01(en-us,PandP.10).gifUnsealed public types do not have internal virtual members.
Ff648189.z02bthcm01(en-us,PandP.10).gifUse of event handlers is thoroughly reviewed.
Ff648189.z02bthcm01(en-us,PandP.10).gifStatic constructors are private.


Ff648189.z02bthcm01(en-us,PandP.10).gifCode uses platform-provided cryptography and does not use custom implementations.
Ff648189.z02bthcm01(en-us,PandP.10).gifRandom keys are generated by using RNGCryptoServiceProvider (and not the Random class).
Ff648189.z02bthcm01(en-us,PandP.10).gifPasswordDeriveBytes is used for password-based encryption.
Ff648189.z02bthcm01(en-us,PandP.10).gifDPAPI is used to encrypt configuration secrets to avoid the key management issue.
Ff648189.z02bthcm01(en-us,PandP.10).gifThe appropriate key sizes are used for the chosen algorithm, or if they are not, the reasons are identified and understood.
Ff648189.z02bthcm01(en-us,PandP.10).gifKeys are not held in code.
Ff648189.z02bthcm01(en-us,PandP.10).gifAccess to persisted keys is restricted.
Ff648189.z02bthcm01(en-us,PandP.10).gifKeys are cycled periodically.
Ff648189.z02bthcm01(en-us,PandP.10).gifExported private keys are protected.


Ff648189.z02bthcm01(en-us,PandP.10).gifSecrets are not hard coded.
Ff648189.z02bthcm01(en-us,PandP.10).gifPlain text secrets are not stored in configuration files.
Ff648189.z02bthcm01(en-us,PandP.10).gifPlain text secrets are not stored in memory for extended periods of time.

Exception Management

Ff648189.z02bthcm01(en-us,PandP.10).gifCode uses exception handling. You catch only the exceptions that you know about.
Ff648189.z02bthcm01(en-us,PandP.10).gifException details are logged on the server to assist in diagnosing problems.
Ff648189.z02bthcm01(en-us,PandP.10).gifThe information that is returned to the end user is limited and safe.
Ff648189.z02bthcm01(en-us,PandP.10).gifCode that uses exception filters is not sensitive to filter execution sequence (filter runs before finally block).
Ff648189.z02bthcm01(en-us,PandP.10).gifCode fails early to avoid unnecessary processing that consumes resources.
Ff648189.z02bthcm01(en-us,PandP.10).gifException conditions do not allow a user to bypass security checks to run privileged code.


Ff648189.z02bthcm01(en-us,PandP.10).gifDelegates are not accepted from untrusted sources.
Ff648189.z02bthcm01(en-us,PandP.10).gifIf code does accept a delegate from untrusted code, it constrains the delegate before calling it by using security permissions with SecurityAction.PermitOnly.
Ff648189.z02bthcm01(en-us,PandP.10).gifPermissions are not asserted before calling a delegate.


Ff648189.z02bthcm01(en-us,PandP.10).gifSerialization is restricted to privileged code.
Ff648189.z02bthcm01(en-us,PandP.10).gifSensitive data is not serialized.
Ff648189.z02bthcm01(en-us,PandP.10).gifField data from serialized data streams is validated.
Ff648189.z02bthcm01(en-us,PandP.10).gifISerializable.GetObjectData implementation is protected with an identity permission demand in scenarios where you want to restrict which code can serialize the object.


Ff648189.z02bthcm01(en-us,PandP.10).gifResults of security checks are not cached.
Ff648189.z02bthcm01(en-us,PandP.10).gifImpersonation tokens are considered when new threads are created (any existing thread token is not passed to the new thread).
Ff648189.z02bthcm01(en-us,PandP.10).gifThreads are synchronized in static class constructors for multithreaded application code.
Ff648189.z02bthcm01(en-us,PandP.10).gifObject implementation code is designed and built to be thread safe.
Ff648189.z02bthcm01(en-us,PandP.10).gifThreads are synchronized in static class constructors.


Ff648189.z02bthcm01(en-us,PandP.10).gifCaller cannot influence dynamically generated code (for example, by passing assembly and type names as input arguments).
Ff648189.z02bthcm01(en-us,PandP.10).gifCode demands permission for user authorization where assemblies are loaded dynamically.

Unmanaged Code Access

Ff648189.z02bthcm01(en-us,PandP.10).gifInput and output strings that are passed between managed and unmanaged code are constrained and validated.
Ff648189.z02bthcm01(en-us,PandP.10).gifArray bounds are checked.
Ff648189.z02bthcm01(en-us,PandP.10).gifFile path lengths are checked and do not exceed MAX_PATH.
Ff648189.z02bthcm01(en-us,PandP.10).gifUnmanaged code is compiled with the /GS switch.
Ff648189.z02bthcm01(en-us,PandP.10).gifUse of "dangerous" APIs by unmanaged code is closely inspected. These include LogonUser, RevertToSelf, CreateThread, Network APIs, and Sockets APIs.
Ff648189.z02bthcm01(en-us,PandP.10).gifNaming conventions (safe, native, unsafe) are applied to unmanaged APIs.
Ff648189.z02bthcm01(en-us,PandP.10).gifAssemblies that call unmanaged code specify unmanaged permission requirements using declarative security (SecurityAction.RequestMinimum).
Ff648189.z02bthcm01(en-us,PandP.10).gifUnmanaged API calls are sandboxed and isolated in a wrapper assembly.
Ff648189.z02bthcm01(en-us,PandP.10).gifUse of SuppressUnmanagedCodeSecurityAttribute is thoroughly reviewed and additional security checks are implemented.
Ff648189.z02bthcm01(en-us,PandP.10).gifTypes are not annotated with SuppressUnmanagedCodeSecurityAttribute. (This attribute is used on specific P/Invoke method declarations instead.)
Ff648189.z02bthcm01(en-us,PandP.10).gifCalling code is appropriately authorized using a full stack walk Demand (using either a .NET Framework permission or custom permission).
Ff648189.z02bthcm01(en-us,PandP.10).gifUnmanaged types or handles are never exposed to partially trusted code.
Ff648189.z02bthcm01(en-us,PandP.10).gifPointers are private fields.
Ff648189.z02bthcm01(en-us,PandP.10).gifMethods that use IntPtr fields in a type that has a finalizer call GC.KeepAlive(object).

Resource Access Considerations

File I/O

Ff648189.z02bthcm01(en-us,PandP.10).gifNo security decisions are made based on filenames.
Ff648189.z02bthcm01(en-us,PandP.10).gifInput file paths and file names are well formed.
Ff648189.z02bthcm01(en-us,PandP.10).gifEnvironment variables are not used to construct file paths.
Ff648189.z02bthcm01(en-us,PandP.10).gifFile access is constrained to the context of the application (by using a restricted FileIOPermission).
Ff648189.z02bthcm01(en-us,PandP.10).gifAssembly file I/O requirements are specified using declarative security attributes (with SecurityAction.RequestMinimum).

Event Log

Ff648189.z02bthcm01(en-us,PandP.10).gifEvent log access code is constrained using EventLogPermission.

This particularly applies if your event logging code could be called by untrusted callers.

Ff648189.z02bthcm01(en-us,PandP.10).gifEvent sources are created at installation time. If unable to create event sources at installation time, the administrator manually creates a new event source entry in the registry.

The account used to run the code that writes to the event log is not allowed to create new event sources by configuring ACL in the registry.

Ff648189.z02bthcm01(en-us,PandP.10).gifSecurity-sensitive data, such as passwords, is not written to the event log.


Ff648189.z02bthcm01(en-us,PandP.10).gifSensitive data, such as database connection strings or credentials, is encrypted prior to storage in the registry.
Ff648189.z02bthcm01(en-us,PandP.10).gifKeys are restricted. If a key beneath HKEY_CURRENT_MACHINE is used, the key is configured with a restricted ACL. Alternatively, HKEY_CURRENT_USER is used.
Ff648189.z02bthcm01(en-us,PandP.10).gifRegistry access is constrained by using RegistryPermission. This applies especially if your registry access code could be called by untrusted callers.

Environment Variables

Ff648189.z02bthcm01(en-us,PandP.10).gifCode that accesses environment variables is restricted with EnvironmentPermission. This applies especially if your code can be called by untrusted code.
Ff648189.z02bthcm01(en-us,PandP.10).gifEnvironment permission requirements are declared by using declarative security attributes with SecurityAction.RequestMinimum.

Code Access Security Considerations

If an entry is preceded by a star (*), it indicates that the checks are performed by the FXCop analysis tool. For more information about FXCop security checks, see http://code.msdn.microsoft.com/GotDotNet.aspx.

Ff648189.z02bthcm01(en-us,PandP.10).gifAssemblies marked with AllowPartiallyTrustedCallersAttribute (APTCA) do not expose objects from non-APTCA assemblies.
Ff648189.z02bthcm01(en-us,PandP.10).gifCode that only supports full-trust callers is strong named or explicitly demands the full-trust permission set.
Ff648189.z02bthcm01(en-us,PandP.10).gifAll uses of Assert are thoroughly reviewed.
Ff648189.z02bthcm01(en-us,PandP.10).gifAll calls to Assert are matched with a corresponding call to RevertAssert.
Ff648189.z02bthcm01(en-us,PandP.10).gif*The Assert window is as small as possible.
Ff648189.z02bthcm01(en-us,PandP.10).gif*Asserts are proceeded with a full permission demand.
Ff648189.z02bthcm01(en-us,PandP.10).gif*Use of Deny or PermitOnly is thoroughly reviewed.
Ff648189.z02bthcm01(en-us,PandP.10).gifAll uses of LinkDemand are thoroughly reviewed. (Why is a LinkDemand and not a full Demand used?)
Ff648189.z02bthcm01(en-us,PandP.10).gifLinkDemands within Interface declarations are matched by LinkDemands on the method implementation.
Ff648189.z02bthcm01(en-us,PandP.10).gif*Unsecured members do not call members protected by a LinkDemand.
Ff648189.z02bthcm01(en-us,PandP.10).gifPermissions are not demanded for resources accessed through the .NET Framework classes.
Ff648189.z02bthcm01(en-us,PandP.10).gifAccess to custom resources (through unmanaged code) is protected with custom code access permissions.
Ff648189.z02bthcm01(en-us,PandP.10).gifAccess to cached data is protected with appropriate permission demands.
Ff648189.z02bthcm01(en-us,PandP.10).gifIf LinkDemands are used on structures, the structures contain explicitly defined constructors.
Ff648189.z02bthcm01(en-us,PandP.10).gif*Methods that override other methods that are protected with LinkDemands also issue the same LinkDemand.
Ff648189.z02bthcm01(en-us,PandP.10).gif*LinkDemands on types are not used to protect access to fields inside those types.
Ff648189.z02bthcm01(en-us,PandP.10).gif*Partially trusted methods call only other partially trusted methods.
Ff648189.z02bthcm01(en-us,PandP.10).gif*Partially trusted types extend only other partially trusted types.
Ff648189.z02bthcm01(en-us,PandP.10).gif*Members that call late bound members have declarative security checks.
Ff648189.z02bthcm01(en-us,PandP.10).gif*Method-level declarative security does not mistakenly override class-level security checks.
Ff648189.z02bthcm01(en-us,PandP.10).gifUse of the following "potentially dangerous" permissions is thoroughly reviewed:

Unmanaged Code

Ff648189.z02bthcm01(en-us,PandP.10).gifCode identity permission demands are used to authorize calling code in scenarios where you know in advance the range of possible callers (for example, you want to limit calling code to a specific application).
Ff648189.z02bthcm01(en-us,PandP.10).gifPermission demands of the .NET Framework are not duplicated.
Ff648189.z02bthcm01(en-us,PandP.10).gifInheritance is restricted with SecurityAction.InheritanceDemand in scenarios where you want to limit which code can derive from your code.

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.