File format and metadata validation The Common Language Runtime verifies that the PE file format is valid and that addresses do not point outside of the PE file. This helps provide assembly isolation. The Common Language Runtime also validates the integrity of the metadata that is contained in the assembly.
Code verification The MSIL code is verified for type safety at JIT compile time. This is a major plus from a security perspective because the verification process can prevent bad pointer manipulation, validate type conversions, check array bounds, and so on. This virtually eliminates buffer overflow vulnerabilities in managed code, although developers still need to carefully inspect any code that calls unmanaged application programming interfaces (APIs) for the possibility of buffer overflow.
Integrity checking The integrity of strongly named assemblies is verified using a digital signature to ensure that the assembly has not been altered in any way since it was built and signed. This means that attackers cannot alter source code in any way by directly manipulating the MSIL instructions. Also, code runs only against the specific version of a library it was designed for. This prevents version-compatibility surprises as libraries are updated.
Code access security The virtual execution environment provided by the Common Language Runtime allows additional security checks to be performed at runtime. Specifically, code access security can make various run-time security decisions based on the identity of the calling code.