Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Securable resources such as access tokens, events, files, threads, and others are represented via HANDLE objects on Windows . [MSDN]  . Handle inheritance is a two-step process.  When obtaining a HANDLE, an option is given to specify whether the object is inheritable or not.   This option is usually in the form of a BOOL parameter (as in the case of OpenMutex()), or a SECURITY_DESCRIPTOR parameter (as in the case of CreateFile()).   When creating a process via the CreateProcess() family of APIs, a parameter is given specifying whether the spawned process will inherit handles previously flagged as being inheritable.   Any handles that were opened as being inheritable will be opened in the child process using the same handle value and access privileges as in the parent process.   The parent process can then alert the child process of the handle values via an inter-process communication mechanism, and the child process can use those values as though it had opened the handle . [MSDN].

When opening handles to securable resources or spawning child processes, prohibit handle inheritance by default to prevent accidental information leakage.   If obtaining an inherited handle from a parent process, prevent leakage to subsequent child processes by duplicating the handle without inheritance.

Noncompliant Code Example (Mutex)

The following This noncompliant code example attempts to open an existing mutex handle that can be inherited by a child process.:

Code Block
bgColor#ffcccc
langc
#include <Windows.h>
 
void func(void) {
  HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, TRUE, TEXT("Global\\CommonMutex"));
  if (!hMutex) {
    /* Handle error */
  }
}

Even if the process does not currently spawn child processes, this code example is non-compliant noncompliant because future changes involving child processes could leak this handle accidentally.

...

This compliant solution opens the same mutex without specifying the handle can be inherited by a child process.:

Code Block
bgColor#ccccff
langc
#include <Windows.h>
 
void func(void) {
  HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, TEXT("Global\\CommonMutex"));
  if (!hMutex) {
    /* Handle error */
  }
}

...

In this noncompliant example, the child process is spawned and inherits a single file handle from its parent process.   The first argument to the main function is the handle's integer value as a hexadecimal string.   However, the child process is not validating that the handle is a valid file handle, and it is not restricting further inheritance of the handle.   Additionally, there is a portability concern arises if the parent process and the child process are the same architecture (egfor example, if one is 32-bit and the other is 64-bit).

...

Compliant Solution (Further Inheritance)

The This compliant solution receives the inherited handle via the command line , but prevents further inheritance by duplicating the handle.   This It also ensures that the value passed is a valid HANDLE value.   Then it validates the handle as a proper file handle by calling GetFileInformationByHandle().   It This solution also properly handles cross-architecture situations between the processes.

...

By default, all files on Windows that are opened using fopen() will allow handle inheritance, and processes spawned via the system() API automatically inherit handles.   In this noncompliant code example, SomeProcess.exe inherits the file handle for SomeFile.txt.:

Code Block
bgColor#ffcccc
langc
#include <stdio.h>
#include <stdlib.h>
 
int main(void) {
  FILE *fp = fopen("SomeFile.txt", "rw");
  if (!fp) {
    return -1;
  }
  
  system("SomeProcess.exe");
 
  fclose(fp);
  return 0;
}

...

In this compliant solution, the Windows-specific 'N' mode parameter is passed  to the call to fopen(), which ensures the file is opened without allowing handle inheritance.:

Code Block
bgColor#ccccff
langc
#include <stdio.h>
#include <stdlib.h>
 
int main(void) {
  FILE *fp = fopen("SomeFile.txt", "rwN");
  if (!fp) {
    return -1;
  }
  
  system("SomeProcess.exe");
 
  fclose(fp);
  return 0;
}

...

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

WIN03-C

highHigh

unlikelyUnlikely

lowLow

P9

L2

Related Guidelines

  

Bibliography

...