Chapter
14
.NET Security
As sophisticated hackers continue to spawn new generations of
malicious computer viruses, security has become an increasingly important issue
for both software developers and end users. Microsoft has taken security to new
levels in the .NET Framework. Not only does it help you avoid running
potentially destructive code, it also gives you the ability to implement user
security for denying and granting user access.
Just about every software application needs some type
of security. In Visual FoxPro applications, security usually takes the form of
preventing users from accessing secure areas of the application or from viewing
and editing sensitive data. In VFP, you have to design and write your own
security code or purchase a third-party application framework that provides
this functionality for you. In contrast, there are two main types of security
built right into the .NET Framework—role-based security and code
access security.
Role-based security allows you to control what end users can
do in your .NET applications. This is similar to the security you are probably
already using in your Visual FoxPro applications. There may be functionality in
your application you don’t want certain groups of users to access. You may have
other areas of your application where you allow some users to have read-write
privileges and others to have read-only privileges. The .NET Framework contains
classes that provide this ability.
Code access security is not available in Visual FoxPro
applications. It is enforced by the .NET runtime and helps you avoid running
“evil” code that can do bad things to your computer. Code access security has
become particularly important with the advent of .NET’s new deployment model
allowing you to easily install .NET assemblies downloaded from the Internet on
your computer. The downside of this model is assemblies may contain code that
intentionally (or unintentionally) wreaks havoc on your computer. Because
Microsoft is moving to this sort of Internet-downloadable software distribution
model, they spent resources incorporating security into the .NET Framework.
The first part of this chapter focuses on code access
security introducing the tools and classes provided by the .NET Framework and
the Windows operating system you can use to define and enforce security for
your desktop and Internet applications. The second part of the chapter shows
you how to define and enforce role-based security. Fortunately, Microsoft has
created a consistent model so once you learn one type of security you can
easily learn the other.
Code Access Permissions
I’m not a big fan of running code from unknown sources
on my computer. Although I’m religious about backing up my laptop—which is my
main development machine—it would be a real pain to get it back in working
order after being demolished by malicious code.
.NET helps you breathe a little easier in this regard if
you’re careful and follow the rules. .NET allows you to grant or deny code the
permission to perform a particular type of operation or access a specific
resource. For example, you may want to deny an assembly the permission to
perform read or write operations to files and directories on your local
computer or network drives. You may also want to deny permission to access
resources such as your local hard drive, your database, or your Windows
Registry. This is where .NET permissions come in.
The .NET Framework has a variety of permission classes that
enforce restrictions on managed code. Table 1 lists the different
permission classes found in the framework. I’ll take a closer look at these
classes later in this chapter and show you how to implement them in your .NET
applications.
Table 1. .NET code access permissions
|
Permission
|
Description
|
Namespace
|
|
DirectoryServicesPermission
|
Access to the System.DirectoryServices
classes.
|
System.DirectoryServices
|
|
DNSPermission
|
Access to the Domain Name System
(DNS).
|
System.Net
|
|
EnvironmentPermission
|
Read or write environment variables.
|
System.Security.Permissions
|
|
EventLogPermission
|
Read or write access to event log services.
|
System.Diagnostics
|
|
FileDialogPermission
|
Access files selected by the user in an Open dialog box.
|
System.Security.Permissions
|
|
FileIOPermission
|
Read, append, or write files or directories.
|
System.Security.Permissions
|
|
IsolatedStorageFilePermission
|
Access private virtual file systems.
|
System.Security.Permissions
|
|
IsolatedStoragePermission
|
Access isolated storage, which is storage associated with
a specific user and some aspect of the code’s identity, such as its Web site,
publisher, or signature (abstract base class).
|
System.Security.Permissions
|
|
MessageQueuePermission
|
Access message queues through the managed Microsoft
Message Queue (MSMQ) interfaces.
|
System.Messaging
|
|
OleDbPermission
|
Access to databases using OLE DB.
|
System.Data.OleDb
|
|
PerformanceCounterPermission
|
Access performance counters.
|
System.Diagnostics
|
|
PrintingPermission
|
Access printers.
|
System.Drawing.Printing
|
|
ReflectionPermission
|
Discover information about a type at run time.
|
System.Security.Permissions
|
|
RegistryPermission
|
Read, write, create, or delete registry keys and values.
|
System.Security.Permissions
|
|
SecurityPermission
|
Execute, assert permissions, call into unmanaged code,
skip verification, and other rights.
|
System.Security.Permissions
|
|
ServiceControllerPermission
|
Access running or stopped services.
|
System.ServiceProcess
|
|
SocketPermission
|
Make or accept connections on a transport address.
|
System.ServiceProcess
|
|
SqlClientPermission
|
Access to SQL Databases.
|
System.Data.SqlClient
|
|
UIPermission
|
Access user interface functionality.
|
System.Security.Permissions
|
|
WebPermission
|
Make or accept connections on a Web address.
|
System.Net
|
As you peruse Table 1, you will see some permission classes
that make a lot of sense, such as FileIOPermission, OleDbPermission, and
SqlClientPermission. However, other classes such as UIPermission may seem
unnecessary—why would you prevent code from displaying a message to the user?
Here’s a good example—a few times a year I get e-mails from
well-meaning friends and relatives warning me of a virus that’s sweeping the
globe. I’m told I can easily fix the problem by deleting a particular
virus-laden file from my hard drive. In reality, the file I am told to delete
has nothing to do with a virus, but is actually a file necessary to the
Windows operating system. The moral of this story is that I may not want code
from unknown sources popping up dialogs telling users to perform actions that
can debilitate their computers.
Figure 1 displays all of the classes from Table 1 in a
UML class diagram, to give you a clearer picture of the code access permission
class hierarchy.

Figure 1. The code access permission class
hierarchy.
Creating custom code access permissions
Although the built-in permission classes cover many of
the permissions you need to administer in your application, there are times
when you need to create your own custom permission classes. For examples of
when and how you should create your own custom permissions, see the .NET Help
topic “Creating Your Own Code Access Permissions”.
It’s a matter of trust
How much do you trust the code you’re getting ready to
run? If you’ve written it yourself, and it resides on your local machine, the
level of trust should be pretty high! However, if you’ve just downloaded an
assembly from the Internet and a company you are not familiar with publishes
it, your level of trust should be very low. So how do you specify which
permissions apply to a particular assembly? This is done by means of a security
policy.
Security policy
A security policy is a set of rules telling the .NET
runtime what permissions to grant to assemblies from different sources. When
the runtime gets ready to run an assembly, it determines the identity of the
assembly (such as where the code came from and who published it) and then
checks the security policy to determine the rights it should be given.
Security policy levels
There are four different security policy levels as
shown in Table 2.
Table 2. Security policy levels
|
Policy level
|
Description
|
Specified by
|
|
Enterprise
|
Applies to all managed code for
every computer and user on the network.
|
Administrator
|
|
Machine
|
Applies to all managed code on a computer.
|
Administrator
|
|
User
|
Applies to code in all the processes associated with the
current operating system user.
|
Administrator or user
|
|
Application domain
|
Applies to managed code in the host’s application domain.
|
Set programmatically
|
These four security policies form a hierarchy, with the
enterprise policy at the top of the food chain (Figure 2), and each
subsequent policy beneath the previous.

Figure 2. Security policy hierarchy.
You set permissions at the enterprise level that apply to all
computers and users on the network. Permissions set at the machine level apply
to all users on a given machine and the user policy specifies permissions for
the current operating system user. The application domain security policy level
lets you specify security for a particular application domain.

.NET’s application “domain” replaces the “process” as the
smallest unit of application isolation on a Windows system. You can have
multiple domains within a single process that isolate applications from each
other. For more information, see the .NET Help topic “Application Domains
Overview”.
At run time, when determining the permissions for an
assembly, all security policy levels are evaluated, and the code is granted the
minimum permissions granted by any of the levels.
In this chapter, I discuss security policies at the machine
level. For information on setting security policy for all other levels, see the
.NET Help topic “Security Policy Best Practices”.
Viewing and configuring code access security policies
There are two .NET tools you can use to configure code
access security policies. The first is the Code Access Security Policy Tool
(Caspol.exe) command-line utility. The other tool is the .NET Framework
Configuration tool (Mscorcfg.msc) that provides a graphical user interface for
configuring security policies. Although Caspol provides more capabilities, I
will show you the .NET Framework Configuration tool in the sections that follow
because its graphical interface helps you better understand the .NET
Framework’s security concepts. For more information on Caspol, see the .NET
Help topic “Code Access Security Policy Tool (Caspol.exe)”.
The
enterprise, machine, and user-level security policies can be configured using
one of these .NET configuration tools, but the application domain policy can
only be set programmatically.
To launch the .NET Framework Configuration tool in Windows
2000, click the Windows Start
button and select Programs |
Administrative Tools | Microsoft .NET Framework Configuration. In
Windows XP go to the Control Panel,
select Administrative Tools,
and then select Microsoft
.NET Framework Configuration. When the tool appears, select the Runtime Security Policy
node in the left pane (Figure 3).

Figure 3. The .NET Framework Configuration tool
can be used to configure code access security policies.
The .NET
Framework Configuration tool allows you to configure settings by
using either wizards or configuration dialogs. The right pane contains a list
of tasks with wizards. You will run one of these wizards later in the chapter,
but first look at the tree view in the left pane.
If you expand the Runtime
Security Policy node, you see the three configurable policy
levels—Enterprise,
Machine, and User (Figure 4).

Figure 4. Security policy can be configured at
the Enterprise,
Machine, and
User levels.
If you expand the Machine
node, you see three additional nodes—Code
Groups, Permission
Sets, and Policy Assemblies
(Figure 5).

Figure 5. Each policy level contains Code Groups,
Permission Sets, and Policy Assemblies nodes.
The Enterprise
and User policy levels
also contain these nodes, but again, I am concentrating on the machine-level
security policy in this chapter. The following sections describe what each of
these nodes represents.
Code groups
Each security policy contains a hierarchy of code
groups. A code group is a logical grouping of code with similar
characteristics, such as where the code came from (for example, Local machine,
Internet, Intranet).
For code to be included in a particular group, it must meet a
specific membership condition. Each code group has only one code membership
condition. The .NET Framework has eight default membership conditions
represented by the classes listed in Table 3.
Table 3. Code group membership conditions
|
Membership condition
|
.NET class
|
Membership requirement
|
|
All code
|
AllMembershipCondition
|
A membership condition for all
code.
|
|
Application Directory
|
ApplicationDirectoryMembership
Condition
|
Assemblies located in the same directory or in a child
directory of the running application.
|
|
Hash
|
HashMembershipCondition
|
The hash value of the assembly.
|
|
Publisher
|
PublisherMembershipCondition
|
Assemblies digitally signed with a specified certificate.
|
|
Site
|
SiteMembershipCondition
|
The HTTP, HTTPS, or FTP Web site where the code originated
|
|
Strong Name
|
StrongNameMembershipCondition
|
Assemblies that have the specified strong name public key
(and optionally name and version)
|
|
URL
|
UrlMembershipCondition
|
The URL where the code originated. An asterisk can be used
as a wildcard character at the end of the URL.
Examples:
http://www.MySite.com/MyAssembly.dll
ftp://ftp.MySite.com/pub/*
|
|
Zone
|
ZoneMembershipCondition
|
The zone, or region, where the code originated.
|
The .NET runtime uses the criteria listed in Table 3 (also
known as evidence) to determine the placement of code into a code group.
Expand the Code
Group node in the .NET
Framework Configuration tool (Figure 6) and you see the All_Code node. This node
forms the root of the code group tree and the top of the code group hierarchy.
This is the first code group listed in Table 3. All .NET assemblies belong to
this code group—no membership condition is necessary!

Figure 6. All .NET assemblies belong to the All
Code group by default—no membership condition is necessary.
If you expand the All_Code
node, you see a list of child code group nodes (Figure 7).

Figure 7. The All_Code node sits at the top of a
hierarchy of code group nodes that define membership conditions for assemblies.
“Zone” is also one of the code groups listed in Table 3.
Because zones are one of the most commonly used code group membership
conditions, the following section details each type of zone used by .NET
security policies.
Zones
The Zone code groups provide a way to specify
membership conditions based on an assembly’s origin. If you have toyed with
Internet Explorer’s security settings, you may be familiar with the concept of
zones. Table 4 lists the different zones used by .NET security policies.
Table 4. Security policy zones
|
Zone
|
Description
|
|
My Computer
|
Applies to code that exists on the local computer.
|
|
Local Intranet
|
Used for code located on a company’s intranet.
|
|
Internet
|
This is a “catch all” zone used for
code located on Web sites not specified as belonging to any other zone.
|
|
Trusted Sites
|
Used for code located on Web sites you trust. The URL of
one or more Web sites can be added to the Trusted zone.
|
|
Untrusted Sites
|
Used for code located on Web sites you do NOT trust. The
URL of one or more Web sites can be added to the Untrusted zone
|
Now, I’ll show you how to use the .NET Framework
Configuration tool’s Security Adjustment Wizard to view the security policy
zone settings on your local computer. Afterwards, I’ll come back to the tree
view and look at the settings in greater detail. To launch the wizard, select
the Runtime Security Policy node
in the left pane and click the Adjust
Zone Security link in the right pane. This displays the Security Adjustment Wizard
(Figure 8).

Figure 8. The Security Adjustment Wizard allows
you to modify security policy for the local computer or for the current user.
The wizard allows you to modify the security policy for the
local computer or the current user. Accept the default setting Make changes to this computer,
click the Next button, and
the Security Adjustment Wizard
displays (Figure 9).

Figure 9. The Security Adjustment Wizard allows
you to configure security settings for assemblies coming from a particular
zone.
The top of the dialog displays a pane containing the
different .NET security zones. Each of these corresponds to a zone code group
node shown in Figure 7. To change the security level for a particular zone,
select the zone at the top of the dialog and use the track bar at the bottom of
the dialog to select the desired level of trust. To set the default level for a
particular zone, click the Default
Level button. Here are the different “level of trust” choices as
described by their associated text:
·
Full Trust – Security checks are not
performed and programs can access and use all resources on your machine. Avoid
this setting unless you are certain no potentially harmful or error-prone
programs can execute from the selected zone. This is the default setting for the
My Computer zone.
·
Medium Trust – Programs might not be able
to access most protected resources
such as the registry or security policy settings, or access your local file
system without user interaction. Programs can connect back to their site of
origin, resolve domain names, and use all windowing resources. This is the
default setting for the Local
Intranet zone.
·
Low Trust – Programs might not be able to
access protected resources such as the registry, environment variables, domain
names, or security policy settings. Programs have limited ability to use
windowing resources and your local file system. This is the default setting for
the Trusted Sites
zone.
·
No Trust – Programs might not be allowed
to execute. This is the default setting for the Internet
zone and the Untrusted Sites
zone.
If you click the wizard’s Next
button, it displays a list of zones and their associated security levels (Figure
10). If you click Finish,
it saves any changes you have made.

Figure 10. The last page of the Security Adjustment
Wizard shows a list of all zones and their associated security level.
Specifying zone web sites
You can use Internet Explorer to specify the Web sites
that belong to the Local intranet, Trusted sites, and Restricted sites zones.
From within Internet Explorer, select Tools | Internet Options
from the main menu to launch the Internet
Options dialog (Figure 11).

Figure 11. You can use the Internet Options
dialog in Internet Explorer to specify the Web sites that belong to the Local
intranet, Trusted sites, and Restricted sites zones.
Local Intranet zone
If you select the Local
Intranet zone at the top of the Internet
Options dialog, and then click the Sites
button, it displays a Local
intranet dialog (Figure 12) for specifying the Web sites
included in the Local Intranet zone. All Web sites included in the Local
Intranet zone use the security settings specified for this zone.

Figure 12. The Local intranet dialog allows you
to specify the Web sites included in the Local Intranet zone.
If you click the Advanced…
button, a second dialog is launched allowing you to add or remove Web sites
from the Local intranet zone. You can also use this dialog to add Web sites
that are not in your local intranet. You might do this if you want to give an
external Web site the same permissions as sites on your local intranet—I
recommend doing this judiciously!
Trusted sites
If you select the Trusted
sites zone at the top of the Internet
Options dialog and click the Sites button, it displays a Trusted
sites dialog (Figure 13) that allows you to specify the Web sites
included in the Trusted sites zone.

Figure 13. The Trusted sites dialog allows you to
add and remove Web sites from the Trusted sites zone.
As you can see in Figure 13, I’ve added three Web sites to my
Trusted sites zone, which grants additional “trusted” permissions to these Web
sites.
Restricted sites
If you select the Restricted
sites zone at the top of the Internet
Options dialog and click the Sites…
button, it displays the Restricted sites dialog (which is similar to the dialog
shown in Figure 13) that allows you to add and remove Web sites from the
Restricted sites zone.
Why would you want to restrict all software from a particular
site? At times, you may determine that a site is known to contain unstable or
malicious code. You can use this dialog to add that site to the list of
restricted sites causing them to run in an extremely restricted environment or
not allowing them to run at all!
Viewing code group detail
Now that you’ve seen a higher-level view of zone code
groups, it’s time to take a more detailed look at them. To do this, launch the .NET Framework Configuration
tool again, and in the left pane, expand the Runtime
Security Policy | Machine | Code Groups | All_Code node as shown
in Figure 7.
If you select the My_Computer_Zone,
a description of the code group is shown in the right pane. This description
informs you this code group allows full access to all resources and the current
policy level is “FullTrust”.
At the bottom of the right pane is a list of Tasks that can be
performed on the My_Computer_Zone
code group—in this case, “Edit Code Group Properties” and “Add a Child Code
Group”. You can also choose to perform these tasks (and more) by clicking the Action menu pad or
right-clicking the node and selecting New
or Properties from
the menu (Figure 14).

Figure 14. The .NET Framework Configuration tool
allows you to add, duplicate, copy, delete, rename, and edit security code
groups.
If you select New
from the menu, it launches the code group Properties dialog, allowing you to
create a new code group. If you select Properties
from the menu, it also launches the code group Properties dialog (Figure 15).

This section describes the basics of the code group Properties
dialog. For more information on creating your own custom code groups, see the
.NET
Help topic “Configuring Code Groups Using the .NET Framework
Configuration tool”.
The General
tab of the dialog allows you to specify the name and description of the code
group. At the bottom of the tab are two check boxes in the If the membership condition is met
group box. As described by their associated text, these check boxes let you
change how the .NET runtime evaluates permissions for the code group.

Figure 15. The code group Properties dialog lets
you specify a code group’s name, description, membership conditions, and
permission set.
If you click the Membership
Condition tab, you see two combo boxes. The first combo box
allows you to select the condition type for the code group (Figure 16).

Figure 16.The Membership Condition tab allows you
to select a membership condition type for the code group.
The options listed in this combo box are the same code group
membership conditions listed in Table 3 earlier in this chapter. You can also
select a custom code group you define yourself (see the next section for
details). Based on the option you select in the upper combo box, additional
input controls are displayed beneath it or, in the case of the “All Code” and
“Application Directory” selection, no additional input controls are displayed
at all. If “Zone” is selected in the condition type combo box, a second combo
box is displayed allowing you to select the desired zone (Figure 17).

Figure 17. When configuring a zone membership
condition, a second combo box is displayed allowing you to select the desired
zone.
Permission sets
The third tab of the code group Properties dialog
introduces a new concept—named permission sets. A named permission set is a
grouping of one or more permissions given a friendly name and description. Table
5 lists the built-in named permission sets found in the .NET Framework.
Table 5. Built-in permission sets
|
Permission set
|
Description
|
|
Full Trust
|
Full access to all resources.
|
|
Skip Verification
|
Skip verification of code in the assembly. This is a
powerful permission that should only be applied to highly trusted code.
|
|
Execution
|
Permission to run, but no
permission to use protected resources.
|
|
Nothing
|
No permissions. Code cannot run.
|
|
Local Intranet
|
The default policy permission set within an enterprise.
|
|