Return to
HomePage
Protect Data in the Registry Using Key Permissions (VB.NET)
Applies To
* .NET Framework 2.0
* VB.NET
Summary
The purpose of this code snippet is to illustrate how to secure data stored in the Windows registry through the use of registry access control list (ACL) permissions. By using these permissions, a user
can programmatically control who can and cannot access data stored in the registry.
Objectives
* Creating an applying a registry kep security context to control which users can access data from the registry
Solution Example
Sub [ControlledRegistryStore(ByVal] keyName As String, [ByVal] valueName As String, [ByVal] data As String)
' Create a security context for a new key that we will use to store our data.
' The security context will restrict access to only our user.
Dim user As String = [Environment.UserDomainName] + "\" + [Environment.UserName]
Dim security As New [RegistrySecurity()]
Dim rule As New [RegistryAccessRule(user,] [RegistryRights.FullControl,] [InheritanceFlags.ContainerInherit,] [PropagationFlags.None,] [AccessControlType.Allow)]
[security.AddAccessRule(rule)]
' Actually create the new registry key and apply the security context we just came up with.
Dim key As [RegistryKey] = [Registry.CurrentUser.CreateSubKey(keyName,] [RegistryKeyPermissionCheck.ReadWriteSubTree,] security)
' Write the data into the registry
[key.SetValue(valueName,] data)
End Sub
Problem Example
' Write an unprotected key and value into the registry. Default
' permissions allow all other users to access this key
Dim key As
RegistryKey =
Registry.CurrentUser.CreateSubKey(keyName) key.SetValue(valueName, data)* Any other user on the system can access this key because no security
context has been applied
Test Case
The following classes must be included in any project making use of the sample code provided above:
Imports System.Security
Imports
System.Security.AccessControl Imports Microsoft.Win32
Furthermore, two distinct users must be defined on the test system. These users will be referred to in the following example as User A and User B.
This test cases illustrates how a registry key secured using access control permissions by one user cannot be access by another user in the following 3 steps:
1) Store a key as "User A" (in this example, "User A" = Administrator) using the following code:
'Entry point which delegates to C-style main Private Function
Sub Main(args() As String)
Dim keyName As String = "AdminSecuredKey"
Dim valueName As String = "AdminSecuredValue"
[ControlledRegistryStore(keyName,] valueName, "sensitive data")
End Sub
Sub
ControlledRegistryStore(keyName As String, valueName As String, data As String)
' Create a security context for a new key that we will use to store our data.
' The security context will restrict access to only our user.
Dim user As String = [Environment.UserDomainName] + "\" + [Environment.UserName]
Dim security As New [RegistrySecurity()]
Dim rule As New [RegistryAccessRule(user,] [RegistryRights.FullControl,] [InheritanceFlags.ContainerInherit,] [PropagationFlags.None,] [AccessControlType.Allow)]
[security.AddAccessRule(rule)]
' Actually create the new registry key and apply the security context we just came up with.
Dim key As [RegistryKey] = [Registry.CurrentUser.CreateSubKey(keyName,] [RegistryKeyPermissionCheck.ReadWriteSubTree,] security)
' Write the data into the registry
[key.SetValue(valueName,] data)
End Sub
2) Attempt to retrieve the previously stored key as User A using the following code:
Sub Main(args() As String)
Dim keyName As String = "AdminSecuredKey"
Dim valueName As String = "AdminSecuredValue"
Dim data As String = [RegistryRetrieve(Registry.Users,] "\" + keyName, valueName)
If Not (data Is Nothing) Then
[Console.WriteLine(data)]
Else
Console.WriteLine("*** Inaccessible key ***")
End If
End Sub
Function
RegistryRetrieve(parent As
RegistryKey, keyName As String, valueName As String) As String
' Recursively search through each subkey of a parent key
' checking to see if a match for the keyname exist and if
' the data can be obtained from that key. Returns data upon
' match and an error message otherwise.
Dim childName As String
For Each childName In [parent.GetSubKeyNames()]
Try
Dim child As [RegistryKey] = [parent.OpenSubKey(childName)]
Dim data As String = Nothing
If [child.Name.EndsWith(keyName)] Then
' We found the name, try to pull out key data
data = [child.GetValue(valueName)]
Else
' No luck finding the name, try a depth-first recursive search
data = [RegistryRetrieve(child,] keyName, valueName)
End If
If Not (data Is Nothing) Then
Return data
End If
Catch ex As Exception
' Print out a message whenever we come across a
' key we don't have permissions to open
[Console.WriteLine((childName] + ": " + ex.Message))
End Try
Next childName
Return Nothing
End Function
3) Repeat Step 2 while logged in as User B. Compare results.
Expected Result
--------------------------------
"User A" (Administrator) output:
--------------------------------
C:\temp>whoami
vm-win2003\administrator
C:\temp>RegistrySnippet.exe S-1-5-21-2537879503-2075122368-204042655-1006: Requested registry access is not
allowed.
sensitive data
---------------------------
"User B" (Joe User) output:
---------------------------
C:\temp>whoami
vm-win2003\joeuser
C:\temp>RegistrySnippet.exe NetDDE: Requested registry access is not allowed.
S-1-5-19: Requested registry access is not allowed.
S-1-5-19_Classes: Requested registry access is not allowed.
S-1-5-20: Requested registry access is not allowed.
S-1-5-20_Classes: Requested registry access is not allowed.
S-1-5-21-2537879503-2075122368-204042655-1006: Requested registry access is not
allowed.
S-1-5-21-2537879503-2075122368-204042655-500: Requested registry access is not a
llowed.
S-1-5-21-2537879503-2075122368-204042655-500_Classes: Requested registry access
is not allowed.
NetDDE: Requested registry access is not allowed.
*** Inaccessible key ***
Scenarios
* Application comprised of multiple components that to access the same key material for secret encryption keys
* Application needs to store data configuration data to be retrieved on startup, such as database connection strings
* Application consists of a client tier that needs to store runtime credentials to connect to other application tiers
More Information
* Developers should not rely alone or registry permissions to control access to highly sensitive data. Consider encrypting certain data using the Data Protection API (DPAPI) in conjunction with registry access controls to add additional safeguards to more sensitive data stored in the registry. See Additional Resources section for links to encrypting data with the
Additional Resources
* Registry Security Guidelines (.NET): http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGGuidelines0003.asp?frame=true#pagguidelines0003_registry
* Working with Permissions (.NET): http://blogs.msdn.com/asanto/archive/2006/01/22/516009.aspx
Attributes
* Applies To: .NET Framework 2.0, VB
* Category: Registry
* Author: Jonathan Bailey
Return to
HomePage