Programming .Net Security
The Code Access Security Policy tool (Caspol.exe) is a utility provided with the .NET Framework that allows you to administer .NET's code-access security system from the command line and from batch files. You can run Caspol.exe from the following location, where version is the version of the .NET framework, such as "v1.0.3705" for Version 1.0: %Systemroot%\Microsoft.NET\Framework\version\Caspol.exe When performing some administrative tasks Caspol.exe commands can become long and confusing, but for many tasks, Caspol.exe provides a much quicker way of configuring and inspecting security policy, as long as you are happy to work from the command line. Before we look at how to configure security policy using Caspol.exe, there is one Caspol.exe configuration setting that you will want to change if you use Caspol.exe frequently. Whenever you run a Caspol.exe command that changes the security policy configuration, before Capsol.exe commits the change to disk, it will prompt you to confirm the change with the following message: The operation you are performing will alter security policy. Are you sure you want to perform this operation? (yes/no) You must enter "y" or "yes" for the change to proceed. Although it serves a valuable purpose, you will find this level of protection frustrating if you use Caspol.exe frequently. To turn this prompt on and off use the following statements, but remember that if you turn it off, any changes you make will be committed automatically: caspol -polchgprompt on caspol -polchgprompt off
9.4.1 Controlling the Security System
Not only does Caspol.exe allow you to manage security policy, but it also allows you to manage some higher-level configuration settings of the security system. These features map directly to methods of the System.Security.SecurityManager class, which we discussed in Chapter 8. 9.4.1.1 Switching code-access security on and off
To switch code-access security on and off, use the -security flag, as shown here: caspol -security on caspol -security off Turning off code-access security bypasses the security system, meaning that all code has full permission to perform any action. You should consider this only after ensuring that other security mechanisms, such as operating system security, are in place and properly configured to protect your system and resources.
Use of the -security flag maps directly to the static SecurityManager.SecurityEnabled property we discussed in Chapter 8; it is protected by the SecurityPermission.ControlPolicy permission. 9.4.1.2 Switching execution permission checks on and off
Normally, the .NET Framework runtime checks to see if an assembly has the SecurityPermission.Execution permission before it will load and run the assembly. You can switch execution permission checking on and off using the -execution flag shown here: caspol -execution on caspol -execution off There are performance benefits from turning off execution checking; your assembly will load and start more quickly, but you must weigh those savings against the decreased security. Once an assembly is running, there are many undesirable things that malicious code can do that do not require permissions, such as making heavy use of your CPU. Also' once loaded, malicious code is free to probe the security you have in place to try to identify any weaknesses that exist. Use of the -execution flag maps directly to the static SecurityManager.CheckExecutionRights property we discussed in Chapter 8; it is protected by the SecurityPermission.ControlPolicy permission. 9.4.2 Administering Policy Levels
With respect to the administration of security policy, the functionality of Caspol.exe is much the same as what we described for Mscorfg.msc in Section 9.3. In the following sections, we describe how to manage each of the key elements of security policy, but first we must describe how to target your Caspol.exe commands to affect the appropriate policy level and code group. 9.4.2.1 Specifying the target policy level
You must target each policy-administration command at the policy levels you want it to affect using one of the following flags:
Not every target value is valid for every Caspol.exe command. In addition, if you do not specify a target policy level, the result will depend on the command you execute; some commands assume a default -machine setting, others use -all. We describe the default behavior when we discuss the individual commands. 9.4.2.2 Specifying the target code group
Some Caspol.exe commands require you to specify an existing code group as the target of the command. For example, you must identify the code group you want to delete, or the code group under which you want to add a new child code group. Caspol.exe provides two ways in which you can uniquely reference a code group. First, because code group names must be unique within their policy levels, you can use the name of the code group. For example, when manipulating code groups from the default machine policy that we described in Section 9.1 earlier, you could use names like All_Code, Trusted_Zone, or Microsoft_Strong_Name to identify the target of your command. Second, you can use a numeric label that uniquely represents the position of the target code group within the code group hierarchy of a policy group. The root code group has a label of "1.", and every code group below it has a label that identifies its position among its peers for example, "1.1.", "1.2.", "1.3.", and so on. The labels extend to accommodate all the levels in the code group hierarchy for example, "1.1.", "1.1.1.", "1.1.1.1.", and so on. You must always include the final decimal point when specifying the label of a code group. 9.4.2.3 Managing fully trusted assemblies
To list the fully trusted assemblies in a policy level use the -listfulltrust flag. The default target for -listfulltrust is -machine, but you can specify any of the target values; we show some examples here: caspol -listfulltrust caspol -all -listfulltrust caspol -customuser "c:\someuser\security.config" -listfulltrust The start of the output from these commands will look similar to the following. The output shows some general Caspol.exe settings, identifies the target policy level, and then lists the fully trusted assemblies, along with strong-name information. Microsoft (R) .NET Framework CasPol 1.0.3705.288 Copyright (C) Microsoft Corporation 1998-2001. All rights reserved. Security is ON Execution checking is ON Policy change prompt is ON Level = Machine Full Trust Assemblies: 1. mscorlib.resources 1.0.3300.0 = StrongName - 00000000000000000400000000000000 name = mscorlib.resources version = 1.0.3300.0 2. System 1.0.3300.0 = StrongName - 00000000000000000400000000000000 name = System version = 1.0.3300.0 To add an assembly to the fully trusted list of a policy level, use the -addfulltrust flag. You cannot specify -all or -customall as the target, and if you do not specify any target, -machine is used. You must specify the name and path of the assembly that you want to add to the fully trusted list, as shown in the following examples: caspol -addfulltrust SomeAssembly.dll caspol -user -addfulltrust C:\Development\SomeOtherAssembly.dll
To remove an assembly from the fully trusted assembly list, use the -remfulltrust flag and specify the name of the assembly to remove, as shown here; note that you do not need to include any path information. Again, the default target is -machine, and you cannot specify -all or -customall as the target of the command: caspol -remfulltrust SomeAssembly.dll caspol -user -remfulltrust SomeOtherAssembly.dll
9.4.2.4 Managing named permission sets
To list the named permission sets currently defined in a policy level, use the -listpset flag. The default target for -listpset is -machine, but you can specify any target, as shown in these examples: caspol -listpset caspol -user -listpset caspol -customall "c:\someuser\security.config" -listpset The start of the output from these commands will look something like this, showing the XML representation of every code group defined in the policy level. This information is long and difficult to read in this format, but you cannot get Caspol.exe to list the definition of a specific permission set: Microsoft (R) .NET Framework CasPol 1.0.3705.288 Copyright (C) Microsoft Corporation 1998-2001. All rights reserved. Security is ON Execution checking is ON Policy change prompt is ON Level = Machine Named Permission Sets: 1. FullTrust (Allows full access to all resources) = <PermissionSet version="1" Unrestricted="true" Name="FullTrust" Description="Allows full access to all resources"/> 2. SkipVerification (Grants right to bypass the verification) = <PermissionSet version="1" Name="SkipVerification" Description="Grants right to bypass the verification"> <IPermission version="1" Flags="SkipVerification"/> </PermissionSet> To add a new named permission set to a policy level, use the -addpset flag. You must specify the name of the file that contains the XML description of the permission set to add. This is equivalent to importing the permission set using Mscorcfg.msc, which we discussed earlier in Section 9.3.2.1, and the XML format is the same. The following statements demonstrate how to create permission sets from an XML description contained in the file pset.xml. You cannot use -all or -customall as the target of the command, and the default is -machine: caspol -addpset pset.xml caspol -enterprise -addpset pset.xml If the XML description of the permission set does not include a Name attribute, Capsol.exe will throw an error and refuse to create the permission set. In this case, you must specify the name of the permission set as an argument to the -addpset command, as shown here where we name the permission set "TestSet": caspol -addpset pset.xml TestSet caspol -enterprise -addpset pset.xml TestSet You can change an existing permission set using the -chgpset flag and specifying the name of the existing permission set to change and the name of the file containing the new XML description for the permission set. The -chgpset command simply overwrites the existing permission set definition with the new one. For example, to change the TestSet permission set that we just created using the contents of a file named newpset.xml, we use these commands: caspol -chgpset newpset.xml TestSet caspol -enterprise -chgpset newpset.xml TestSet To remove a named permission set, use the -rempset flag and specify the name of the permission set to remove. Here we show how to remove the TestSet permission set that we just created. Again, the default target is -machine, and you cannot specify -all or -customall as the target of the command: caspol -rempset TestSet caspol -enterprise TestSet
9.4.2.5 Managing code groups
To list the code groups in a policy level, use the -listgroups flag. The default target for -listgroups is -machine, but you can specify any of the target settings, as demonstrated in the following examples: caspol -listgroups caspol -user -listgroups caspol -customuser "c:\someuser\security.config" -listgroups When executed against the default machine policy, which we described in Section 9.1, the output of the -listgroups command looks like this; the numeric label we discussed in Section 9.4.2.2 precedes the membership condition, and the name of the permission set each code group grants: Microsoft (R) .NET Framework CasPol 1.0.3705.288 Copyright (C) Microsoft Corporation 1998-2001. All rights reserved. Security is ON Execution checking is ON Policy change prompt is ON Level = Machine Code Groups: 1. All code: Nothing 1.1. Zone - MyComputer: FullTrust 1.1.1. StrongName - 00240000048000009400000006020000002400005253413100040 0000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE 79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E82 1C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8 A12436518206DC093344D5AD293: FullTrust 1.1.2. StrongName - 00000000000000000400000000000000: FullTrust 1.2. Zone - Intranet: LocalIntranet 1.2.1. All code: Same site Web. 1.2.2. All code: Same directory FileIO - Read, PathDiscovery 1.3. Zone - Internet: Nothing 1.4. Zone - Untrusted: Nothing 1.5. Zone - Trusted: Internet 1.5.1. All code: Same site Web. Success To add a new code group to a policy level, use the -addgroup flag. Because of the complexity of code group configuration, the -addgroup command is the most complex Caspol.exe statement, and takes multiple arguments with many optional values. The general form of the -addgroup command is shown here: caspol -target -addgroup {label|name} membership pset [flags] The target argument specified the target policy level, which defaults to -machine, and cannot be -all or -customall. The label and name arguments allow you to specify the parent of the new code group using either its numeric label or name, as we discusses earlier in Section 9.4.2.2. The membership, pset, and flags arguments specify the membership condition, permission set, and properties of the code group respectively. We summarize the possible values of the membership argument in Table 9-4, and those of the flags argument in Table 9-5. The types of evidence listed in Table 9-4 are discussed in Chapter 6, and we provide a more complete discussion of membership conditions in Chapter 8.
The following is an example of the -addgroup command that we used in Chapter 8 to create a code group using the custom AuthorMembershipCondition class: caspol -user -addgroup All_Code -custom Peter.xml FullTrust -name "Peter's code" -description "Code group grants all code written by Peter full trust" The command to change an existing code group is also complex but uses the same arguments as the -addgroup command, with which you are now familiar. The general structure of a -chggroup command is as follows: caspol -target -chggroup {label|name} {membership|pset|flags} In the following example, we change the name of the machine-level code group with label "1.5." to "SomeTestGroup": caspol -enterprise -chggroup 1.5. -name SomeTestGroup Here, we target a machine-level code group named "MyCode" to change its membership condition and its permission set, and make the code group Exclusive; notice that we do not specify the target level because -machine is the default: caspol -chggroup MyCode -url "file://c:\dev\*" FullTrust -exclusive on To remove a code group, use the -remgroup flag and specify the code group to remove. The examples here show how to remove a code group in the enterprise level using both its name and numeric label. Again, the default target is -machine, and you cannot specify -all or -customall as the target of the command: caspol -enterprise -remgroup 1.5. caspol -enterprise -remgroup SomeTestGroup 9.4.3 Evaluating Security Policy
Caspol.exe also allows you to test an assembly to determine which code groups it is a member of and, consequentially, the runtime would grant to it when loaded. To determine which groups an assembly is a member of, use the -resolvegroup flag and specify the assembly name as follows: caspol -resolvegroup HelloWorld.exe Depending on the evidence of the assembly and the configuration of security policy, the output will look similar to this: Microsoft (R) .NET Framework CasPol 1.0.3705.288 Copyright (C) Microsoft Corporation 1998-2001. All rights reserved. Level = Enterprise Code Groups: 1. All code: FullTrust 1.1. Url - file://C:/development/*: FullTrust (Exclusive) 1.2. All code: FullTrust 1.2.1. All code: Internet Level = Machine Code Groups: 1. All code: Nothing 1.1. Zone - MyComputer: FullTrust Level = User Code Groups: 1. All code: Nothing 1.1. Zone - MyComputer: FullTrust Success To view the permission granted to an assembly, use the -resolveperm flag, as shown here: caspol -resolveperm HelloWorld.exe The -resolveperm command will display the XML description of the permission set granted to the assembly, similar to that shown here. Notice that the permission set also lists the identity permissions granted to the assembly based on the evidence it presented, as well as the permissions granted by the security policy: Microsoft (R) .NET Framework CasPol 1.0.3705.288 Copyright (C) Microsoft Corporation 1998-2001. All rights reserved. Resolving permissions for level = Enterprise Resolving permissions for level = Machine Resolving permissions for level = User Grant = <PermissionSet version="1" Unrestricted="true"> <IPermission version="1" Url="file://C:/Development/HelloWorld.exe"/> <IPermission version="1" Zone="MyComputer"/> </PermissionSet> Success Both the -resolvegroup and -resolveperm commands allow you to specify a target policy level, in which case the assembly is only evaluated against that policy level. If you do not specify a policy level, the default target -all is used. 9.4.4 Forcing Security Changes
Caspol.exe is a managed application that relies on obtaining a high level of trust from the runtime in order to perform management of the security system. When you execute any of the commands we discussed in the previous sections, Caspol.exe will test to see if the changes will result in Caspol.exe being unable to run correctly in the future; Caspol.exe will refuse to make such changes and display the following message: Microsoft (R) .NET Framework CasPol 1.0.3705.288 Copyright (C) Microsoft Corporation 1998-2001. All rights reserved. This operation will make some or all caspol functionality cease to work. If you are sure you want to do this operation, use the '-force' option before the opti on you just executed. For example: caspol -force -machine -remgroup 1.6 Policy save aborted. If you want to force the change despite this warning, you must use the -force flag. The following command makes the All_Code code group of the machine policy exclusive. In the default security policy, this will stop all code from running: caspol -force -machine -chggroup All_Code -exclusive on 9.4.5 Resetting Security Policy
A feature of Caspol.exe you will find useful during development is the ability to reset the security policy to its default value. When developing software that manipulates security policy directly, it is not difficult to break security policy to a point where your code will not run. To reset policy levels, use the -reset flag and specify the levels you want to reset: caspol -user -reset caspol -all -reset You can also undo the last change you made with Caspol.exe using the -recover flag, as shown here: caspol -machine -recover caspol -all -recover
|