Type-Safety in .NET Security
After taking a close look at Microsoft's embarrassingly lightweight Strategic Technology Protection Program, which, however, provides a welcome shift of emphasis for the company, it's time to return to the security features in Microsoft's upcoming .NET framework. This week, I'll take a brief look at the framework's type safety. Don't confuse this type safety with data type-verification in most programming languages. In a .NET security context, type safe means preventing programs from accessing memory outside the bounds of an object's public properties
Type-safe code accesses only the memory locations it is authorized to access. For example, type-safe code cannot directly read values from another object's private fields or code areas. It accesses types only in well-defined, allowable ways, thereby circumventing certain popular overrun security breaches.
During just-in-time compilation, an optional verification process examines the metadata and intermediate language of a method to verify that they are type-safe. If the code has permission to bypass verification, then this process is skipped. Although verification of type-safety is not mandatory for managed code, type-safety is important for assembly isolation and security enforcement. When code is type- safe, the common language runtime can completely isolate assemblies from each other. This isolation helps ensure that assemblies cannot adversely affect each other and it increases application reliability. Type-safe components can execute safely in the same process even if they are trusted at different levels.
JIT compilation performs a process called verification that examines code and attempts to determine whether the code is type-safe. Code that is proven during verification to be type-safe is called verifiably type- safe code. Code can be type-safe, yet not be verifiably type-safe, due to the limitations of the verification process or of the compiler. Not all languages are type-safe, and some language compilers cannot generate verifiably type-safe managed code. If you use a language compiler that generates verifiably type-safe code only when you avoid certain language constructs, then use the .NET Framework SDK PEVerify tool to determine whether your code is verifiably type-safe. Code that is not verifiably type-safe can attempt to execute if security policy allows the code to bypass verification. But because type-safety is an essential part of the runtime's mechanism for isolating assemblies, security cannot be reliably enforced if code violates the rules of type- safety. By default, code that is not type-safe is only allowed to run if it originates from the local machine.
When code is not type-safe, unwanted side effects can occur. For example, the runtime cannot prevent unsafe code from calling into native (unmanaged) code and performing malicious operations. When code is type-safe, the runtime's security enforcement mechanism ensures that it does not access native code unless it has permission to do so. All code that is not type-safe must have been granted SecurityPermission with the passed enum member SkipVerification to run.