SV.BRM.HKEY_LOCAL_MACHINE

Use of HKEY_LOCAL_MACHINE macro to defeat least privileges principle

The HKEY_LOCAL_MACHINE macro shouldn't be used as the hkey parameter in the following Microsoft Windows functions:

  • RegConnectRegistry
  • RegCreateKey
  • RegCreateKeyEx
  • RegLoadKey
  • RegOpenKey
  • RegOpenKeyEx
  • SHRegCreateUSKey
  • SHRegOpenUSKey

Similarly, these functions shouldn't manipulate a key that has previously been opened using HKEY_LOCAL_MACHINE as a parameter.

The SV.BRM.HKEY_LOCAL_MACHINE checker flags Windows system calls that use HKEY_LOCAL_MACHINE as the hkey parameter in any of these functions. Registry manipulation using HKEY_LOCAL_MACHINE requires administrator privileges, so if it's used in any of these function calls, the code is defeating the principle of using the least privileges necessary for any particular application.

If it's necessary to use the HKEY_LOCAL_MACHINE parameter in your code, you can switch this checker off.

Vulnerability and risk

If an application continues to operate with excessive privileges, an attacker may be able to use the program to gain unauthorized access to other resources. A successful attack against the application through another flaw, such as a buffer overflow, could result in a privilege escalation attack.

Mitigation and prevention

It's better to use the HKEY_LOCAL_USER macro when the application is writing user-specific data or performing registry operations that can be controlled by the user.

Tracing back the calls to registry functions is important, because it is a common practice to create a handle to the hive and use that for further calls, as shown in the code example.

Vulnerable code example

Copy
    HKEY hKeyHive; 
    HKEY hRealKey; 
    DWORD dwDisposition; 
    if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software", 0, NULL, 
                       REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
                      &hKeyHive, &dwDisposition) != ERROR_SUCCESS) { 
      printf("failed to open hive HKLM. Error %d\n", GetLastError()); 
      return; 
    } 
   printf("Opened hive HKLM\n"); 
   if (RegCreateKeyEx(hKeyHive, "K7_Test", 0, NULL, REG_OPTION_NON_VOLATILE, 
                      KEY_ALL_ACCESS, NULL, &hRealKey, &dwDisposition) != 13   ERROR_SUCCESS) { 
     return; 
   } 
   printf("Created key under HKLM:HKEY_LOCAL_MACHINE\\K9_Test\n");

Klocwork produces an issue report at line 4 indicating that function RegCreateKeyEx is using macro HKEY_LOCAL_MACHINE as its hkey parameter. The use of HKEY_LOCAL_MACHINE makes it impossible to run an application from a regular user account. Instead, the macro requires administrator privileges, which defeats the least privileges rule, and opens up the possibility of a privilege escalation attack.

Fixed code example

Copy
    HKEY hKeyHive; 
    HKEY hRealKey; 
    DWORD dwDisposition; 
    if (RegCreateKeyEx(HKEY_LOCAL_USER, "Software", 0, NULL, 
                       REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
                      &hKeyHive, &dwDisposition) != ERROR_SUCCESS) { 
      printf("failed to open hive HKLM. Error %d\n", GetLastError()); 
      return; 
    } 
   printf("Opened hive HKLM\n"); 
   if (RegCreateKeyEx(hKeyHive, "K7_Test", 0, NULL, REG_OPTION_NON_VOLATILE, 
                      KEY_ALL_ACCESS, NULL, &hRealKey, &dwDisposition) != 13   ERROR_SUCCESS) { 
     return; 
   } 
   printf("Created key under HKLM:HKEY_LOCAL_USER\\K9_Test\n");

In the fixed code example, the HKEY_LOCAL_MACHINE parameter has been replaced with HKEY_LOCAL_USER. In this case, the principle of least privileges is followed, eliminating the possibility for malicious attack.

Related checkers

Security training

Application security training materials provided by Secure Code Warrior.