Main Content

CERT C: Rec. WIN02-C

Restrict privileges when spawning child processes

Since R2026a

Description

Restrict privileges when spawning child processes1

Polyspace Implementation

The rule checker checks for the issue Child process creation without privilege restriction.

Examples

expand all

Issue

This issue occurs if you create a process or thread using the CreateProcess() or CreateThread() functions. The rule checker flags the issue only if you use the version of these functions declared in Windows.h, which comes as part of the Windows® Software Development Kit (SDK).

Risk

The functions CreateProcess() and CreateThread() do not support restriction of privileges when creating a child process. If you use one of these functions, the child process has the same privileges as the parent process. As a result, you cannot operate on the principle that any newly created process must have the least set of privileges necessary to complete a task.

Fix

Use alternative functions that allow restriction of privileges when creating a process.

For instance, instead of the CreateProcess() function, use the CreateRestrictedToken() function to create a restricted token and then use the CreateProcessAsUser() function to start a process with the restricted token.

Example — Child Process With Same Privileges as Parent Process

In this example, the CreateProcess() function is used to create a child process with the same privileges as the parent process.


          
          #include <Windows.h>

int main() {
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    // Initialize the STARTUPINFO structure
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    // Specify the command line for the child process
    TCHAR szCmdline[] = TEXT("C:\\Windows\\System32\\notepad.exe");

    // Create the child process
    BOOL success = CreateProcess(  //Noncompliant
        NULL,           // Application name
        szCmdline,      // Command line
        NULL,           // Process security attributes
        NULL,           // Primary thread security attributes
        FALSE,          // Handles are not inherited
        0,              // Creation flags
        NULL,           // Use parent's environment block
        NULL,           // Use parent's starting directory 
        &si,            // Pointer to STARTUPINFO structure
        &pi             // Pointer to PROCESS_INFORMATION structure
    );

    if (success) {
        // Process created successfully
        // Wait until child process exits
        WaitForSingleObject(pi.hProcess, INFINITE);

        // Close process and thread handles
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    } else {
        // Failed to create process
    }

    return 0;
}
Correction – Restrict Privileges When Creating Child Process

Instead of using the CreateProcess() function to create a child process, use the CreateRestrictedToken() function to create a restricted token and then use the CreateProcessAsUser() function with this restricted token to spawn a child process with restricted privileges.


          
          #include <windows.h>

int main() {
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    HANDLE hToken, hRestrictedToken;

    // Initialize the STARTUPINFO structure
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    // Open the current process token
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, &hToken)) {
        // Failure to open process token
        return 1;
    }

    // Create a restricted token
    if (!CreateRestrictedToken(hToken, DISABLE_MAX_PRIVILEGE, 0, NULL, 0, NULL, 0, NULL, &hRestrictedToken)) {
        // Failed to create restricted token
        CloseHandle(hToken);
        return 1;
    }

    // Specify the command line for the child process
    TCHAR szCmdline[] = TEXT("C:\\Windows\\System32\\notepad.exe");

    // Create the child process with restricted token
    BOOL success = CreateProcessAsUser(
        hRestrictedToken,  // Restricted token
        NULL,              // Application name
        szCmdline,         // Command line
        NULL,              // Process security attributes
        NULL,              // Primary thread security attributes
        FALSE,             // Handles are not inherited
        0,                 // Creation flags
        NULL,              // Use parent's environment block
        NULL,              // Use parent's starting directory 
        &si,               // Pointer to STARTUPINFO structure
        &pi                // Pointer to PROCESS_INFORMATION structure
    );

    if (success) {
        // Process created with restricted privileges successfully
        // Wait until child process exits
        WaitForSingleObject(pi.hProcess, INFINITE);

        // Close process and thread handles
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    } else {
        // Failed to create process with restricted privileges
    }

    // Clean up
    CloseHandle(hToken);
    CloseHandle(hRestrictedToken);

    return 0;
}

Check Information

Group: Rec. 51. Microsoft Windows (WIN)
PQL Name: std.cert.WIN02_C

Version History

Introduced in R2026a


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.