.NET Framework security features
Role-based security is based on the identity of the user executing the application. Code-based security is based on the origin and identity of the code being executed. Both forms of security should be used in tandem to effectively secure your applications.
Type safety and verification
Type-safe code is code that's guaranteed to respect the calling mechanisms and access modifiers for declared types, avoid using unsafe mechanisms like pointer arithmetic, and to use memory resources, like the stack, in a predictable and provably correct manner. Type-safe code is also guaranteed not to interfere with other applications, or even other code within the same process, and to respect the other .NET security mechanisms that check security permissions.
The Common Language Runtime (CLR) can automatically verify the type safety of managed code at runtime when it's loaded and compiled. CLR-compatible compilers producing Microsoft Intermediate Language (MSIL) code generally only produce verifiably safe code. The verification algorithm used by the CLR cannot verify all type-safe code. Some code, though actually type safe, may use illegal mechanisms such as pointer arithmetic. Also, languages such as C++ are inherently unsafe and are not suitable for constructing verifiably type-safe code. Microsoft Visual Basic .NET and C# both automatically produce verifiably safe MSIL code, though C# allows you to override this default behavior with the unsafe keyword.
Code signing
Code signing marks an assembly with a publisher's private key, and ensures that an assembly is not tampered with after publication. Hashes are constructed for each file in the assembly, and these are then stored in the manifest. At runtime, these hashes can be recalculated and checked against the values in the manifest, ensuring that any tampering is detected. Assemblies can also be signed with Microsoft Authenticode certificates. You can generate strong names for assemblies, which consist of a simple name, a version number, an optional culture identifier, and a public-key. Data and code can also be encrypted, hashed, or digitally signed using built-in .NET Framework security classes.
Application domains
Windows applications are generally run in separate processes. These processes provide boundaries, keeping the applications isolated so that they can't interfere with each other.
Code access security
Prevents unauthorized execution of unauthorized code. Permissions are assigned by on evidence of origin, identity and permissions you create. Evidence can include (origin/identity) strong names, cryptographic hashes, and location from which the evidence comes. Permissiones are rights granted to access resources. Permissions are granted when the evidence is combined with the security policy.
Permissions
Built-in .NET Framework permissions in the system.security.permissions namespace
Permission classes Permissions granted
DirectoryServicesPermission Controls access to directory services
DnsPermission Allows the assembly to use DNS services
EnvironmentPermission Allows the assembly to change environment variables
EventLogPermission Grants access to the event logs
FileDialogPermission Allows the assembly to open dialog boxes in the user interface
FileIOPermission Lets the assembly read and write to files and folders
IsolatedStorageFilePermission Allows the assembly to use isolated storage
MessageQueuePermission Grants access to message queues
OleDbPermission Allows the assembly to use the data provider to access OleDb databases
PerformanceCounterPermission Grants access to the performance counters
PrintingPermission Grants access to printers
ReflectionPermission Controls the assembly's access to metadata
RegistryPermission Grants access to the system registry
SecurityPermission A basic permission that allows the assembly to execute, assert other permissions, call unmanaged code, and skip verification, among other rights
ServiceControllerPermission Allows the assembly to run or stop services
SocketPermission Controls access to other computers using sockets
SqlClientPermission Allows the assembly to use the data provider to access SQL Server databases
UIPermission Gives the assembly access to Windows and other user interface elements
WebPermission Allows the assembly to create HTTP connections to other computers
Permission set levels (topmost has the fewest)
Nothing - no permission including execution
Execution - permitted to execute but without resources
Internet - execute, windows, file dialogs and limited isolated storage
LocalIntranet - DNS services, environment variable access, unlimited use of isolated storage
Everything - all permissions except skipping type-safety verification
FullTrust - all permissions and access to resources
There are 4 different levels of security policy:
application doman (ASP.NET)
enterprise (Network administrator)
machine (Machine administrator)
user (Single user under OS)
Code groups and security policy
Membership conditions
Condition Corresponding evidence
Application directory The address of the assembly, particularly the assembly's installation directory
Cryptographic hash The hash of the assembly code, which indicates it hasn't been tampered with
Software publisher The Microsoft Authenticode signature and public key, which identifies the software publisher
Strong name The strong name identifies the publisher and proves that the assembly hasn't changed since publication
URL The particular web address where the assembly was published
Web page This condition applies to applications that are presented on web pages, and not as individual assemblies
Web site The site on which the assembly was published
Zone The security zone � local computer, local network, or Internet � from which the assembly originates
Exclusive attribute means that member assemblies only receive permissions of that group
LevelFinal attribute means that member assemblies are not tested for membership of lower level code groups
Role based security
All users in a business or application can be assigned roles, which are logical groupings related to the application or system. Role based security can be combined with Code base security to provide a more effective security model. User identity holds login information and principal contains role membership information.
WindowsIdentity object (Windows OS authentication)
GenericIdentity object (Not using Windows OS authentication
IIdentity has three properties: Name, Is Authenticated, Authentication
WindowsPrincipal and GenericPrincipal classes and an IPrincipal interface
Call stack walks
Whenever a call is made requiring permission, the system automatically checks access rights to the resource. Call-stack walks are inefficient. By asserting a permission you can forestall a call stack walk. You can write your own code to manually enforce permissions, which is called issueing a security demand. All standard predefined permission classes are stored in system.security.permissions namespace.
EnvironmentPermission class - controls access to system and user variables
SecurityPermission class - set of security permissions in code
UIPermission class - clipboard and user interface permissions
Permission objects
FileDialogPermission - open, opensave, save (file and folder access)
FileIOPermission - read, write, pathdiscovery, append
IsolatedStorageIOPermission - usage of private virual file system: none or unrestricted
IsolatedStoragePermission - usage of generate isolated file storage: none or unrestricted
ReflectionPermission - access to metadata through system.security.permissions.reflectionpermission
RegistryPermission - controls access to registry variables
Imperative security
You can imperatively issue security demands and asserts methods. Demand triggers a call stack walk. Circumvent the call stack walk by using Assert. The .NET Framework completes these demands automatically and there is no need to make a demand for a call stack walk, however, the demand can be completed by an assembly. Special permission is required to use assert but not demand method.
Permission object methods:
Deny
PermitOnly
RevertPermitOnly, RevertAssert, RevertDeny
IsSubsetOf, Union, Intersect
Declarative security
Declarative security uses attributes to modify security settings for assemblies, classes and methods.
VB.NET Example:
< FileIOPermission(SecurityAction.Demand, Read:="C:\Perms") >
Public sub LookAtFile(ByVal filename as string)
Imperative security is visible at run time, declarative security demands are checked upon loading.
Permview tool
The Permview tool allows user of an assembly to scan for declarative security demands. User can anticipate the kinds of security permission their code will need when the assembly is being used. All permission objects have corresponding permission attributes. Imperative security actions are hidden to users of an assembly. Declarative security is stored within the manifest, imperative security is not a part of an assembly.
VB.NET Example:
< FileIOPermission(SecurityAction.Demand, Read:="C:\Perms") >
Public sub LookAtFile(byval filename as string)
Securityaction value:
demand
assert
deny
permitonly
linkdemand
inheritancedemand
requestminimum
requestoptional
requestrefuse
Declarative security
Can be implemented only at assembly, class, or method level
Parameterized during build time
Exceptions thrown only in callers
Visible to assembly users
Inherently simpler than imperative security
Best suited to using permission requests with link demands
Uses attributes to modify security for assemblies, classes and methods
Imperative security
Can be implemented at assembly, class, or method level, or within a method
Parameterized during runtime
Exceptions thrown and handled in methods
Hidden to assembly users
Inherently more complex than declarative security
Doesn't support using permission requests with link demands
Using permissions in VB.NET
Imports System.Security.Permissions
Module Perms
Sub main()
LookAtFile("C:\Perms\myFile.txt")
End Sub
'Callers must have access to C:\Perms
< FileIOPermissionAttribute(SecurityAction.Demand, _
Read:="C:\Perms" > > _
Public Sub LookAtFile(ByVal filename As String)
Dim unmanagedPerm As SecurityPermission
Dim fileIOPerm As FileIOPermission
Try
'Define the File access permission object
fileIOPerm = New FileIOPermission( _
FileIOPermissionAccess.Read, filename)
'Make sure callers have the correct permission
fileIOPerm.Demand()
'Allow access to unmanaged code
unmanagedPerm = New SecurityPermission _
(SecurityPermissionFlag.UnmanagedCode)
unmanagedPerm.Assert()
' call unmanaged code
' code not included***
Console.WriteLine("File read")
unmanagedPerm.RevertAssert()
Catch ex As Security.SecurityException
Console.WriteLine("Security exception: ")
Console.WriteLine("Security message : " & ex.Message)
Console.WriteLine("Security type : " & _
ex.PermissionType.ToString)
End Try
End Sub
End Module
Link Demands
Link demand is a special form of declarative security check that determines whether permission exists to a caller. A security exception may be thrown at an undetermined time and in such a case try/catch is not reliable unless used with another method, each caller passes the security check.
< FileIOPermission(SecurityAction.LinkDemand, read:="C:\Perms") >
Public function the LinkedMethod() as string
' Access a resource
End function
Inheritance demands
Inheritance demands can be used at the class or method levels.
Class inheritance example:
< FileIOPermission(SecurityAction.InheritanceDemand, read:="C:\Perms") >
Public Class newclass
' Class implementation
End Class
Method inheritance demand example:
< FileIOPermission(SecurityAction.InheritanceDemand, read:="C:\Perm") >
Public Overridable Function newMethod() as integer
' Access a resource
End Function
Identity permissions
Identity permissions are granted using evidence which does include strong name, download url, authenticode signature, originating zone. Used in a declarative syntax form to demand caller belongs to a particular zone or that the caller is published by a particular publisher.
< ZoneIdentityPermission(SecurityAction.Demand, Zone:=SecurityZone.MyComputer) >
Public Function newMethod() as Integer
' Access a resource
End Function
Suppose you need your assembly to be called only from assemblies installed on your local computer - demand the callers zone is SecurityZone.MyComputer.
< ZoneIdentityPermission(SecurityAction.Demand, Zone:=SecurityZone.MyComputer >
Public Function newMethod() as integer
' Access a resource
End Function
Additional identity permission classes included in the .NET Framework:
* PublisherIdentityPermission - authenticode signature of assembly
* StrongNameIdentityPermission - assembly strong name
* SiteIdentityPermission - website originated
* URLIdentityPermission - originating url
* ZoneIdentityPermission (shown in above example) - my computer, internet, intranet
Ideally an assembly should not load unless the minimum set of permissions is available to it. You could code around not having local storage access and instead use isolated storage or memory.
There are three types of permission requests:
* RequestMinimum - specifies minimum set of permissions required to execute
* RequestOptional - request additional permissions not included in minimum set
* RequestRefused - specifies permissions that should be denied to your code
VB.NET Identity Permission example:
' Request minimum
< Assembly: SecurityPermission(SecurityAction.RequestMinimum, Flags:=SecurityPermissionFlag.UnmanagedCode) >
' Request optional
< Assembly: SecurityPermission(SecurityAction.RequestOptional, Flags:=SecurityPermissionFlag.ControlPrincipal) >
' Request refused
< Assembly: SecurityPermission(SecurityAction.RequestRefuse, Flags:=SecurityPermissionFlag.ControlPolicy) >
< Assembly: SecurityPermission(SecurityAction.RequestRefuse, Flags:=SecurityPermissionFlag.ControlThread) >
Custom Permissions
.NET Framework predefined permissions should suit your purposes. There are situations where custom permissions are appropriate to protect resources:
* When no permission class protects a resource
* Inadequately controlled access right to a resource that is protected
* Permission protects the resource but not in a way that meets your needs
Custom permissions should be defined in a way they do not overlap which could cause unnecessary processing overhead. To implement a custom code access permission:
* Implementing IPermission and IUnrestrictedPermission, and/or possibly ISerializable
* Handling XML encoding and decoding
* Optionally adding support for declarative security by implementing an Attribute class
Configuring security policy using the MFC tool
.NET Framework comes with the MFC (Microsoft Framework Configuration) and Caspool (Code Access Security Policy tool) utilities. Both are used to configure security policy on a machine.
MFC
Common reasons you might need to change security policy:
* External assemblies deployed locally will have local access rights
* Legitimate assemblies may not be able to run correctly if denied access rights to some resources
* Default security gives full access to local assemblies, security is not enforced during development
* A security policy you create in a zone may be quite restrictive; either redeploy the assembly or change security for specific assemblies rather than changing zone policy
Development must be tested using expected zone security policies. Restricting access rights might be required in such a case.
The Trust Assembly Wizard, allows you to increase level of trust applied to a particular assembly or publisher.
The Adjust Security Wizard, allows you to change security settings for an entire zone.
These wizards are found in administrative tools - Microsoft .NET Framework Wizards in the control panel.
There is a sliding bar to change level of trust for zones; my computer, local intranet, internet, trusted sites and untrusted sites. By default untrusted sites are denied even the ability to execute.
Example adjustment of security policy:
* Open .NET Framework configuration tool
* Open runtime security policy
* Click enterprise, machine or user
* Click code groups to display current set of groups
* Add a child code group, starts the create code group wizard
* Select a condition type: All code, Application Directory, Hash, Publisher, Site, Strong Name, URL, Zone - using strong name public key from the assembly's manifest by using the ildasm tool or you can click the import button and browse to the assembly
*Enter the assembly name, version is optional
* Assign a permission set; fulltrust, skipverification, execution, nothing, localintranet, internet, everything
* Click the finish button
* Repeat for enterprise, machine or user level (if needed)
Example change of zone security policy:
* Select adjust zone security
* Select current computer or current user
* Highlight the zone and slide the bar up for additional trust level
* A summary appears, click finish
Example of deploying a custom security policy on local machine:
* Select create deployment package
* Select machine option
* Choose a folder and file name for the new package
* Click finish
Example to view permission sets:
* Click enterprise, machine or user
* Click the permission set you want to review
* Click view permissions
* A list of all permissions appears at the level selected
Note: It may be difficult to keep track of permissions each assembly requires, the Permview command allows you to view the permissions an assembly requires; here is a sample permview commandline C:\system\microsoft .net\1.1\permview /decl codefile.exe (/decl indicates declarative security demands)
Caspool - Code Access Security Policy tool
This tool is installed with the .NET Framework SDK. If the user has administrator rights Caspool policies are applied to machine level, if the user does not have administrator rights Caspool policies are applied to the user level. Administrator defaults can be changed to -en -m or -u to change the default. Caspool has built in warnings, backups and a reset.
Sample caspool commands:
-lg or -listgroups
-lp or -listpset
-all, -machine, -user or -enterprise
-lf or -listfulltrust
-u -recover (replace existing user level security policy with previous policy backup)
-m -lp (list permission sets associated with machine policy level)
-en -af test.exe (adds enterprise fulltrust to assembly text.exe)
-en -remfulltrust test.exe (remove full trust abbreviation is -rf)
-m -addpset newPset newPermissions (adds new permission set called newPermissions to machine policy, defined within newPset.xml file)
-user -addgroup 1. - zone Intranet Execution (adds a child group to the root of the user policy code group, member of intranet zone receiving execution permission set)
-resolvegroup test.exe
-resolveperm test.exe
-user -chggroup 1.1 -site www.test.com (edits membership condition of second child group so test.com is a member
-m -recover (recover changes from last backup of machine policy)
.NET role based security
All principal and identity objects must implement IPrincipal IIdentity objects.
IIdentity public properties include AuthenticationType (passport, windows, kerberos), Name (current user), IsAuthenticated (boolean). IIdentity classes include WindowsIdentity (IsAnonymous, IsGuest, IsSystem) and GenericIdentity. Two methods of WindowsIdentity are GetCurrent and GetAnonymous.
VB.NET example:
Dim myID as WindowsIdentity
myID = WindowsIdentity.GetCurrent()
Dim myPrin as new WindowsPrincipal(myID)
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal)
To call SetPrincipalPolicy you'll need permission from system.security.permissions.security.
dim myPrin2 as WindowsPrincipal = CType(System.Threading.Thread.CurrentPrincipal, WindowsPrincipal)
Create a GenericIdentity object passing a string representing the user's name
Dim myId as new GenericIdentity("Toby")
Dim myPrin as New GenericPrincipal(myId, new String() {"Administrator", "Debugger"))
After principal and identity objects are established, you can check user identity information and role membership using String.Compare, WindowsPrinipal.IsInRole or GenericPrincipal.IsInRole and PrincipalPermission.Demand.
'Compare two strings, ignoring their case
Console.WriteLine(String.Compare(myId.Name(), myId2.Name(), True))
Dim myId as WindowsIdentity = WindowsIdentity.GetCurrent()
Dim myPrin as new WindowsPrincipal(myId)
Console.Writeline(myPrin.IsInRole(WindowsBuiltInRole.Administrator))
Values include Administrator, Guest, PowerUser, User
Check membership of multiple roles
Dim myPerm as New PrincipalPermission("Toby", "Administrator")
To check current user is an administrator use the IsInRole method with the WindowsBuiltInRole and the Administrator value.
Cases my arise where your application needs to impersonate a user to perform some operations. Avoid storing passwords in your applications.
< DllImport("C:\\WINNT\\System32\\advapi32.dll") >
Public Shared Function LogonUser( _
byval lpszUsrename as string, _
byval lpszdomain as string, _
byval lpszpassword as string, _
byval dwlonontype as integer, _
byval dwlononprovider as integer, _
byref phToken as integer) as boolean
End Function
< DllImport("C\\WINNT\\System32\\Kernel32.dll") & gt
Public Shared Function GetLastError() as integer
End function
Dim token as integer
' Call unmanaged LogonUser with new account details
If LogonUser("Toby", "ARK1", "password", 3, 0, token) then
' Create the new WindowsIdentity
Dim myNewID as WindowsIdentity = New WindowsIdentity(New IntPtr(token))
' Start impersonation here
Dim WinImper as WindowsImpersonationContext = myNewID.Impersonate()
' do restricted actions here...
' Then remember to undo the impersonation
' WinImper.Undo()
Authentication technologies
* User names and passwords
* Digital certificates
* Biometrics
* Encryption
* IPSec
ASP.NET security
There are several types of authentication under ASP: Forms (user must complete before access, set a cookie of credentials), passport (register and install passport SDK) and windows.
< authorization > < element attribute = "option, option"/ < /authorization >
This configuraion denies access to anonymous users but grants access to everyone else
< authorization > < deny users = "?"/ > < allow users = "*"/ > < /authorization >
Rights specified in subdirectory configuration files take precedence over those located in parent directories. The system applies the first relevant rule it finds.
User Lisa will be allowed to access a URL because the rule granting her permission comes before the rule denying access to all users.
< authorization > < allow users = "Lisa"/ > < deny users = "*"/ > < /authorization >
The default configuration file disables impersonation.
< impersonation enable = "false" / >
Hard coding identity that an application will impersonate:
< impersonation enable = "true" userName = "Last\First" password = "password" / >
The default anonymous ASP.NET user account is IUSER_machinename. To manage ananymous accounts the Windows Computer Management admin tool can be used.
Viewing authorized users on your computer:
Start the Computer Management tool under control panel - performance/maintenance - administrative tools
Click local users and groups
Select users folder - contains authorized users of your computer
Click name to view properties
ASP.NET uses the ASPNET account to run web applications. ASPNET displays account name in the security event log of the event viewer. NTFS must be used to secure file servers from anonymous users.
Windows authentication is the default mode enabled using XML code in your web.config file. To identify network users with permission to access an application, ASP.NET checks the projects web.config authorization list.
< authentication mode="Windows" / >
< authorization >
< allow users="*" / > < !-- Allow all users -- >
< /authorization >
< authorization >
< allow users="Nick, Dean, Trish" / >
< deny users="*" / >
< /authorization >
The * character indicates al users and ? character indicates unauthorized users
VB.NET code obtains current username and authenticatino type:
Dim myName as string
Dim authenType as string
Dim isOK as boolean
myName = User.Identity.Name
authenType = User.Identity.AuthenticationType
isOK = User.Identity.IsAuthenticated
When an app is run remotely, ASP.NET displays a dialog box in which you enter your username and password. An authorization certificate (cookie) persists for the user's entire session.
Using forms authentication
Forms authentication has several advantages over Windows integrated authentication:
* The app controls authentication and authorization tasks
* Users can access your app without being members of a domain based network
* Commercial web sites like to have access to user information
To create forms authentication, specify the authentication mode in web.config as Forms. Create a web form to collect logon information. Create a database to collect user names and passwords. Write code that adds new users to the database and authentication against the database.
How it works:
ASP.NET automatically displays the logon web form specified in web.config for the user to fill in
Upon receiving completed form, ASP will either accept or reject the request base on user information
ASP issues (if authenticated) an authorization certificate in the form of a cookie
XML code sets default settins and includes a user list with web.config:
< authentication mode="Forms" > < !-Set authentication mode - >
< forms loginUrl="myLogin.aspx" > < -- Specify a log on form -- >
< credentials passwordFormat="Clear" > < !-Create user list - >
< user name="Nikolai" password="MondayMorning"/ & gt
< user name="Jennifer" password="TBD0101"/ >
< /credentials >
< /forms >
< authentication >
< authorization >
< deny users="?" / > < !-Deny all unauthenticated users- >
< /authorization >
The credentials element allows you to store users in the web.config file. To encrypt user password Passwordformat is used.
VB.NET sample login:
Private sub cmdlogin_click(byval sender as system.object, byval e as system.eventargs) handles cmdLogin.Click
' Authenticates the username and password
If formsauthtication.authenticate(txtusername.txt, txtpassword.txt) then
' redirects authenticated user to original URL
FormsAuthentication.RedirectFromLoginPage(txtUserName.text, True)
else
' did not pass
txtPassword.text = ""
end if
End Sub
Of course the above example is manual, to allow users to enter and store username and password information you'll need a user database. You can encrypt database information using the HashPasswordForStoringInConfigFile method of FormsAuthentication class.
password = FormsAuthentication.HashPasswordForStoringInConfigFile(password, "sha1")
Example above uses the SHA1 encryption algorithm.
Passport authentication
To use Microsoft's passport authentication the Passport SDK must be downloaded and installed.
< authentication mode="Passport" / >
< authorization >
< deny users="?" / > < !-deny unauthenticated users- >
< /authorization >
Return to top of this page
To contact me (Author of this website and software), please E-mail me at:
jep1965@gmail.com
This page last updated Aug 01 04 5pm