One of my most read blog posts (and one of the reasons I created this blog in the first place -- to answer what was one of the most asked questions on the old .NET Security newsgroup), is my post about granting managed controls hosted in IE extra permissions. If you need to have a managed control run above its default grant set, the process getting this working in .NET versions through .NET 2.0 was relatively painful.
You needed to create an extra code group that granted your control the permissions required, and then get that policy deployed to all client machines. One of the more common ways of doing this is to use the .NET MMC snap-in to create a policy MSI file. However, those policy files are snapshots of policy and overwrite any other custom policy settings on each client machine. This means if a user has two controls they use that require an MSI prerequisite, they end up fighting for control over policy -- only the last one installed wins. There's also no guarantee that client machines have run my MSI file, so unless the control does runtime permission checking it will sometimes fail on misconfigured machines.
Versioning provides another challenge here. Since every CLR has independent security policy and IE will always load the latest runtime version when hosting a control, as soon as a new version of the CLR ships all changes in policy will no longer apply to hosted controls, and new MSIs will need to be created.
On top of all of these challenges, is the problem mentioned in the original blog post -- namely that the AppDomain hosting the control will only have Url and Zone evidence. If your code group uses a stronger membership condition (and it probably should) such as StrongName or Publisher, any demands will fail when they hit the AppDomain boundary because the domain will not match your code group and will have lower trust than your assembly. This required adding an assert at each of the control's entry points, which is not really a great coding practice.
With all of these problems, it's pretty obvious that we need a better solution for controls which need to run with higher permission than default. A lot of these problems apply to applications as well as controls, and we solved them in .NET 2.0 by having those applications use ClickOnce. Since ClickOnce applications can specify their required permissions in a manifest and allow the user to decide if this is a safe set of permissions to grant, there was no policy modification.
Orcas introduces a very similar system for IE hosted controls. They can now include a set of manifests, which are very similar to the ClickOnce manifests, that state the required set of permissions for the control to run. Again, this decouples the control from policy which solves the MSI-fight problem as well as the CLR versioning problem. Just like ClickOnce applications, these controls are hosted in simple sandbox domains -- this means that the domain and the control both have the same permission set, removing the need to assert at the entry points.
One of the first questions that comes to mind when thinking about this feature is if a control is allowed to declaratively state what permissions it wants to run with, what's to prevent malicious controls from elevating to FullTrust and doing whatever it wants to my machine? We've decided not to do any prompting of the user for this feature, instead we use a simple algorithm to determine if the control should be allowed to run with its requested permissions. Specifically, if any of these requirements are met, then we allow the control to run:
- The control is requesting a subset of the permissions it would have gotten anyway. So if a control is coming from the Internet zone and it is requesting the Internet permission set, we'll allow it to run.
- The control is signed by a trusted publisher. The control's deployment manifest must be signed (more on the requirements for manifests later) by a X.509 certificate. If the signer is in the client's trusted publisher list and the certificate is valid and chains to a trusted root, then we allow the control to run with whatever permissions it requests. This is likely the easiest way for IT organizations to make use of the feature, as trusted publishers can be controlled via group policy.
- If the zone the manifest is running from explicitly allows controls loaded from it to elevate their permissions
If all three of those checks fail, then the control is not allowed to run. (Note that we don't run the control with the permissions it would be granted from policy if these checks fail -- we assume that the control was authored to run with the specified set of permissions, and should not be run with less than the requested set).
The third check may need a little more explanation. When you install Orcas, you'll see that a new option has been added to the Internet Explorer Security Settings dialog box called "Permissions for components with manifests":
As you can see, there are three possible values for this setting:
- Disable - controls with manifests will not be allowed to run at all. Even if the control is requesting only Execution permission and is signed by a trusted publisher, if the zone it's loaded from is set to disabled the CLR will not allow the control to run.
- High Safety - controls are not allowed to elevate their permissions via this setting alone. If the control is not requesting elevation or is signed by a trusted publisher than it will be allowed to run, however this setting will cause check #3 above to fail.
- Low Safety (Unrestricted) - controls are allowed to elevate. Even if the first two elevation checks fail, if the zone is set to low safety, then the control will be allowed to run with whatever permissions it asks for. The reason that "Unrestricted" appears in the setting is that by setting this value, you're effectively giving all controls loaded from this zone the ability to run fully trusted. Obviously that's not something that should be done lightly if at all. [Updated 1/24/2008 - Low Safety was removed after the Orcas betas.]
Essentially, if the setting for the deployment manifest's zone is High Safety then elevation check #3 fails, if it is Low Safety then elevation check #3 succeeds. The default values for this setting are:
|Local Intranet||High Safety|
|Trusted Sites||High Safety|
So no zone will elevate by default, and manifested controls are disabled entirely on the local machine and restricted sites.
Next time: More information about the manifests