.NET Security1

.NET Security

Overview

Objectives

This module will introduce you to security in .NET. We will show you the basic concepts of protection against malicious code and operations and we will present an overview on cryptographic support in .NET.

It is important to make clear what we are not talking about:

  • Security in the Microsoft Windows (or any other) operating system
  • COM+ security
  • ASP.NET security
What you will learn
  • Overview of security in .NET
  • Design and use your own security solutions
  • Cryptography in .NET
Related Topics Covered In This Lesson
  • Security and the Common Language Runtime
  • How to encrypt and decrypt data

Overview

Section 1: Overview

We start with a short look on object-based security. We summarize its benefits and shortly discuss some issues.

Subsequently we give an overview of the components that all together form security in .NET, for example the Common Language Runtime, Permissions, and Roles.

Overview

Object based security models
Securing distributed applications

Distributed applications introduce a number of security issues. The basic requirements for distributed application security are:

  • Identification and authentication: Who wants to access a certain object or resource? What is the origin of the code that wants to run on my machine? You cannot grant the same level of trust to all callers. Therefore the caller’s identity must be established depending on some information, like username/password combination or a digital signature.
  • Data integrity and privacy: The messages that are exchanged between the caller and the callee may be confidential and therefore must be secured. It must be ensured that these data is protected from being altered and intercepted. For example, if you’re asking your boss for a pay rise via email, you don’t want a malicious co-worker changing the content into a termination.
  • User authorization: Which operations is the user, respectively an object allowed to perform? For example, different groups of users have different access rights to different areas or virtual directories of an application residing on a Web Server.

All together, security must be administrable. An administrator must have the ability to easily move a user to another user group, specify the level of trust that is admitted to a software component or simply manage secure access to objects or resources.

Objects act on behalf of the caller

The principle of object-based security is that a caller/user wants to gain access to a secured object, which can be, for example, a file, a process, or the Windows Registry.

  • Access token: When a user successfully logs into the system, the identity and the privileges of the user’s account are determined and an access token is created. An access token is an object describing the security context of each process executed on behalf of the user. When a certain process (or thread) tries to access a secured object, the access token is used to identify the associated user.
  • Security descriptors: The security information about a secured object is held by a security descriptor.

Now, in the case that a thread touches a secured object the security information of both the access token and the security descriptors are compared by the system before any further proceeding.

Overview

Looking back …
Security mechanisms

If we are looking at security there are different solutions for different issues. Some samples:

  • To identify and authenticate a user or a software component you can make use of solutions provided by the operating system. In case of Windows NT/Windows 2000 a user must use a combination of username and password to log into the system, and a software component can use signatures. Sent together with the associated message, a signature is a piece of information that uniquely identifies the origin of the signed message. To create a signature either the complete message or just a part of it is encrypted using algorithms like the RSA digital signature process. Both the sender and the receiver of a message need keys to encrypt and decrypt the data.
  • When receiving the message and the corresponding security information the callee may look up a database, for example, Active Directory to verify the identity of the caller.
  • Another way of protecting transmitted data is to use a security (transport) protocol like Secure Sockets Layer (SSL), which is very popular on the Internet through HTTPS.
DCOM, CORBA, and TPMs

For distributed applications it’s necessary to transport data safely from a client to a server while simultaneously data must be protected once it’s arrived. To target this security issue databases, for example, ask the user for some identification.

If there are many users identification, authentication and authorization of each single caller consumes time and resources. Therefore it would be better if a single authorized user could act on behalf of all users.

A Transaction Processing Monitor (TPM) is the middleware that moves the security from the middle tier/backend tier boundary to the frontend tier/middle tier boundary. The TPM communicates with the server as a single user and all other clients have to deal with the TPM to verify that they are authorized to perform the request. So, with TPMs authorization takes place upon making a request to the middle-tier. There is no security check for read, write, or update. A client either is allowed to make a request - which may be composed of a number of reads and writes - or not.

Now components come into the play.

The basic security requirements are already discussed and they are the same with components. To support security different component models provide different rudiments.

For example DCOM relies more or less on security mechanisms provided by the underlying operating system, while CORBA manages security within a security-enabled ORB.

Overview

What’s wrong with that?
Trust all or nothing at all

Imagine a piece of code, let’s say a component, that is allowed to run on a certain machine. This component is conceded a specific level of trust. Once the component has the permission to execute there is no distinction made between more or less trusted methods. This means, all operations that are implemented by the component can be called and performed on the same security level.

“Luring attacks”

Now, you might say that all code that is not built on your local machine is less trusted code. But it is possible that some less trusted code calls highly trusted code and perform malicious actions.

TPMs are difficult to administer

Transaction Procession Monitors are hard to program. At least you must understand the architecture of the TPM. But more important is the fact that for some administrators it may be easier to give a user access to a middle-tier process that has nearly the requested security settings than to create and configure a new exactly matching role.

Core Concepts

Section 2: Core Concepts

This part introduces the core concepts of security in .NET, which are:

  • Kinds of Security
  • Permissions, Policies, and Roles
  • Common Language Runtime
  • Code Groups and Stack Walking

Core Concepts

Kinds of Security

If your computer is connected to the “world outside”, how often did you search the Internet for a new required utility or game, downloaded it, installed and ran it without scanning for viruses? Never? O.K., then, how often was code downloaded to your computer, installed and ran without your personal activity or control - for example, when your browser asked you to install a new plug-in and you just clicked on “OK”? This never happened? You lucky fellow!

If you connect your computer to the Internet it is a potential target for malicious code and unauthorized access. To help protecting your computer two main security solutions are offered by the .NET Framework: Code access security and role-based security.

Code access security

Code access security is provided to protect against malicious mobile code that - without protection - may to damage or modify private data.

Role-based security

Once a caller is identified and authenticated role-based security provides support for authorization.

In this context a principal is an object that acts on behalf of the caller. It carries all information that is necessary to specify what the principal, respectively the caller is allowed to do.

Security model is based on permissions

With the .NET Framework code needs permissions to perform operations. This code might have different permissions for different operations.

Permissions are objects that can be requested, granted, and demanded.

Heavily based on the Common Language Runtime

Security is an integral part of the Common Language Runtime. The runtime is involved in security tasks like code identification or versioning.

Core Concepts

Common Language Runtime

The Common Language Runtime is a runtime environment provided by the .NET Framework.

The CLR resides on top of the system services and manages .NET code. Managing code means that it loads and executes code that targets the .NET platform.

The CLR consists of a number of elements – or components – that represent different functionalities. For example, the Common Type System describes all types that at least must be supported by a language compiler targeting .NET. Two elements of the CLR that are mainly involved in the security subject are the class loader and the JIT compiler.

The class loader provides information about each type implementation after the CLR has loaded the type. This includes security information that can be used to perform a minimal verification process.

The Just-In-Time (JIT) compiler converts Microsoft Intermediate Language (MSIL) into native executable code. To support security the JIT compiler has a built-in verification algorithm to verify that the MSIL code is type-safe.

Core Concepts

Application Domain Host

An application domain is an isolated execution space created by the runtime that ensures that code running in one application cannot affect other unrelated applications.

Application domains are something similar to Win32 processes. But this model is independent of the operating system concept of threads or processes. A single operating system process can host multiple "AppDomains".

Application domains are important for .NET security in that they enforce security policy.

Host sets up Application Domain and loads assembly

Each .NET application runs within an application domain under the control of a host. A host sets up the application domain and loads the assembly. The host has access to security information about assemblies and specifies the security policy for the application domain.

If the runtime allows the host to hand over this security information (evidence) it is called a trusted host.

Different hosts

There are different kinds of hosts:

  • Shell: runs an executable program
  • Browser: launches applications within the context of a Web Page
  • Server: runs server-side request-handlers
  • Custom-designed: self-explanatory

Core Concepts

Evidence
Information about the code

Evidence is security related information about an assembly. This information is provided directly by the loader or by a trusted application domain host.

Types of evidence

Evidence helps answering questions like:

  • Who published the code?
  • Where did the code come from?

To achieve this there are different types of evidence. For example:

  • Signature: The signature should uniquely identify the publisher of the code. A strong name guarantees the uniqueness of the assembly’s name. They are simple text names that consist of a combination of a key and a digital signature. Strong names are created using a public/private key pair.
  • URL and Site of origin: self-explanatory

Core Concepts

Permissions, Policies, and Roles
Permissions

To handle the issue what code is allowed to do and what is not the CLR uses permissions.

Permissions are the access code to restricted areas. They do not directly represent the rights to perform intended actions. Permissions are objects that help to control the restrictions on managed code.

Code can request permissions to determine whether it is allowed to perform operations on or gain access to secured resources and objects. The CLR grants permissions to callers that are trusted or that might request permissions. If code doesn’t request any permission the runtime grants a default set of permissions. And code can demand permissions from its caller, which means that a caller must have the legal permissions to proceed.

Security Policy

To decide on what code is allowed to do the CLR performs some certain operations. These operations are configured through the security policy, which is a configurable set of rules that the runtime must follow to check permissions.

A security policy assorts code into a hierarchical tree of code groups. Each code group has a set of permissions associated with it. Due to this an administrator can easily configure the restrictions on code running on the respective machine.

Roles and the principal

After a caller is identified and authenticated the system verifies the authorization of the caller to perform the requested operations. For this purpose the .NET Framework provides role-based security.

Users are logically grouped together using named sets. One set of users that have the same security permissions is called a role.

Depending on the role a user is associated with the .NET Framework can decide on the authorization level it concedes to the user.

The role or identity is determined through the principal, which acts on the user’s behalf. Each new thread is furnished this principal object that contains a reference to an identity object.

Core Concepts

Code Group Hierarchy

In .NET code is logically grouped into code groups. A piece of code must have some certain qualities and has to fulfill specific preconditions to be a member of such a code group. Think of it like user groups where users must meet certain membership conditions to become a member of a group.

As mentioned above the membership is close-knit to security. Each code group has a permission set and/or some code group attributes associated with it.

The runtime uses the information provided by the assembly’s evidence to decide on the membership. Due to this there are membership conditions like publisher, site of origin, or application directory.

Code groups are arranged hierarchically. This means code groups may have one or more subordinated code groups.

For example, a code group CG1 with the membership condition Publisher:Microsoft has two subordinated code groups with the conditions Site:LocalWeb (CG2) and Name:Ms Money (CG3). Each of these code groups holds a certain permission set. A piece of code that is published by Microsoft will be a member of the code group CG1 and will have the permissions based on CG1’s permission set. If this specific piece of code also comes from the site LocalWeb it will be granted the permissions associated with code group CG2.

The groups are numbered due to their hierarchical order. The base code group has the number “1”. Code groups of the first sublevel have numbers like “1.1”, “1.2”, “1.3”, etc. The next level is numbered “1.1.1”, 1.1.2”, and so on. All leading digits up to the last one signify the common superior code group (except level 1), and the last digit is a counter that indicates the amount of code groups subordinated to the superior code group.

Use these numbers to refer to certain code groups.

Core Concepts

Code inspection and Stack Walking

Security check

Security not only in .NET aims at protecting resources and operations.

For example, an assembly A1 wants to use some functionality provided by assembly A2. A2 itself needs to call another assembly A3 to serve the purpose. A3 needs to call A4 to gain access to the file system and perform some operations, like reading from or writing to a file.

Now in this scenario we have a call chain of four assemblies. Each assembly has been granted a set of permissions. Let’s further assume that the called method in the last assembly of the chain (A4) demands a certain permission P. At run-time the runtime walks the call stack and checks whether each granted permission set of all assemblies in the call chain inclose the demanded permission P. This is called a security check.

Security checks are, of course, a feature of code access security and can be overridden by calling Assert, Deny, or PermitOnly.

Varying levels of trust

The .NET security solutions let you specify different levels of trust. You are not restricted on trusting an assembly (a component) in its entirety, rather you can specify which single operation is allowed and which is not.

Some evil-minded code producer may try to call highly trusted code from less trusted code to perform malicious operations. But security checks helps preventing such “luring attacks”.

Core Concepts

Security Namespace