Code Access Security (hereafter referred to as CAS) is a feature of the CLR that protects resources from unauthorized access. Not too long ago, there was a lot of concern about ActiveX controls because when you trusted such a control, you trusted it completely and implicitly. That meant that if you downloaded and trusted an ActiveX control, that control could then access your hard drive, delete important files, or otherwise wreak havoc with your computer. Even worse, innocent ActiveX controls could be used as security holes through which malicious code could be injected onto your computer.
CAS provides a stock set of permissions and permission groups that can be used to restrict access to protected resources, giving the end user peace of mind knowing that no .NET code can ever access anything on his machine without his explicit permission. In addition, CAS includes the underlying plumbing that makes all of this possible. CAS is built directly into the .NET Framework so that it is impossible to write managed code that exists outside the boundaries defined by CAS. As you will see later in this chapter, end users and IT administrators alike can create and manage security policy for their computers or for an entire enterprise, choosing exactly which resources specific applications can access.
Permissions are enforced in such a way that code with limited security cannot make use of code with unrestricted security to gain access to protected resources. When the code demands a permission (illustrated in the Imperative and Declarative Security sections), the CLR walks backward along the call stack, examining the permission levels of each assembly in the stack. If the CLR finds an assembly that does not have the permission being requested by the code, the CLR will deny permission to everything on the call stack. This is illustrated in Figure 14.1.
Figure 14.1. Using the call stack to ensure secure access to resources.
In this hypothetical scenario, untrusted code makes a call to an assembly that is partially trusted, which then in turn makes a call into a fully trusted assembly. In other scenarios, this could turn into a huge security hole and allow the untrusted code to do things like delete files in the system directory or make damaging changes to the registry. However, when the fully trusted assembly indicates that it needs a specific permission in order to continue, the CLR then walks backward along the call stack and examines the permission levels of all calling assemblies. If any of them have been denied the permission in question, so too will the fully trusted assembly, even though that assembly has the permission. This prevents exploiting fully trusted code for malicious purposes.