.NET for Visual FoxPro Developers

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.

Text Box: ¥

.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)”.

 

Text Box: ¥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). 

Text Box: ¥

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.