Skip to content

CWE-114: Process Control

Overview

Process control vulnerabilities occur when applications accept untrusted input to control process execution, library loading, or behavior (start, stop, kill, priority, resource limits). This includes insecure dynamic library loading (DLL hijacking, LD_PRELOAD attacks), command injection through process execution, and unauthorized process control. Attackers exploit weak validation to load malicious libraries, execute arbitrary commands, or manipulate running processes.

OWASP Classification

A05:2025 - Injection

Relationship to Other CWEs

CWE-114 and CWE-78 address different aspects of process security:

CWE-114 (Process Control) - Untrusted data controls which process/library to execute:

  • Focus: Controlling the executable path, library name, or process lifecycle (start/stop/kill)
  • Examples: System.loadLibrary(userInput), dlopen(userPath), LoadLibrary(userDll), os.kill(userPid)
  • Prevention: Absolute paths, allowlist validation, path traversal prevention, signature verification
  • No shell involved: Direct API calls to load libraries or control processes

CWE-78 (OS Command Injection) - Untrusted data interpreted by shell as commands:

  • Focus: Shell metacharacters in arguments (;, |, &, $(), backticks)
  • Examples: system("convert " + userInput), exec("grep " + userPattern)
  • Prevention: Avoid shell execution, use argument arrays, input sanitization
  • Requires shell: Vulnerability exists because shell interprets special characters

Overlap scenarios (both apply):

  • Runtime.exec(userCommand) with shell - controls which program (CWE-114) and allows command injection (CWE-78)
  • system(userInput) - controls which program and allows shell metacharacter injection

Distinct scenarios (CWE-114 only, no shell):

  • Library loading: System.load(), dlopen(), LoadLibrary() - no shell interpretation
  • Process lifecycle: os.kill(), Process.kill() - no command execution
  • Direct execution: execve(), ProcessBuilder without shell - prevents CWE-78 but still needs CWE-114 protection

Defense-in-depth: Secure patterns in this guidance prevent both vulnerabilities by:

  1. Using direct execution APIs without shell (prevents CWE-78)
  2. Validating executable paths and using allowlists (prevents CWE-114)
  3. Using argument arrays instead of string concatenation (prevents both)

Risk

High: Attackers can terminate critical processes, spawn malicious processes, exhaust system resources, or manipulate process priorities to cause denial of service or gain unauthorized control over system operations.

Remediation Steps

Core principle: Only load components from trusted, integrity-checked locations; control library/module search paths and provenance.

Identify the Process Control Vulnerability

Review the security findings to understand how untrusted data controls process operations:

  • Locate the source: Find where untrusted data enters (HTTP parameters, database, external files, network requests)
  • Trace to the sink: Identify the process control function (os.kill(), Process.kill(), taskkill, etc.)
  • Understand the operation: Determine what process control action is being performed (kill, start, stop, priority change)
  • Check the data flow: Review if there's any validation between source and sink

Implement Strict Authorization Checks

Add comprehensive access control before any process control operation:

  • Authenticate the user: Verify the user's identity before allowing process control
  • Implement RBAC: Use role-based access control - only admins/operators can control processes
  • Require elevated privileges: For sensitive operations (system processes, critical services), require additional authentication
  • Never trust untrusted data directly: Don't accept PIDs, process names, or control commands directly from untrusted sources
  • Check process ownership: Verify the user owns the process before allowing control (or has admin role)

Use Allowlists for Process Operations

Restrict which processes can be controlled:

  • Maintain allowlist of controllable processes: Define which processes/services can be managed via the application
  • Validate against known-good values: Check process names or IDs against the allowlist before any operation
  • Reject system/critical processes: Never allow control of system processes (init, systemd, kernel threads, Windows services)
  • Use indirect references: Map user input to internal process IDs (e.g., user selects "job-123" which maps to a specific PID)
  • Load allowlist from configuration: Store allowed processes in config files, not code

Validate All Process Control Parameters

Apply comprehensive validation to process identifiers and commands:

  • Validate PIDs: Ensure process IDs are positive integers, within valid range
  • Validate process names: Use allowlist, check for path traversal attempts
  • Validate control commands: Only allow specific operations (start, stop, restart), reject arbitrary commands
  • Check process existence: Verify the process exists before attempting control
  • Verify process ownership: Ensure the process belongs to the application or authorized user
  • Enforce resource limits: For process spawning, set memory, CPU, and time limits

Implement Logging and Monitoring

Detect and respond to suspicious process control activity:

  • Log all operations: Record every process control attempt with user context, timestamp, operation type, target process
  • Monitor for suspicious patterns: Alert on mass termination attempts, rapid process spawning, privilege escalation
  • Alert on unauthorized attempts: Notify security team when authorization checks fail
  • Audit process lifecycle: Track process creation, termination, and control events
  • Implement rate limiting: Prevent automated abuse of process control endpoints

Test with Malicious Process Control Attempts

Verify the fix prevents unauthorized process control:

  • Test with unauthorized user: Attempt process control as non-admin user (should be rejected)
  • Test with invalid PIDs: Try negative numbers, zero, non-existent PIDs, extremely large PIDs
  • Test with system processes: Attempt to kill system processes (should be blocked by allowlist)
  • Test with SQL injection: If PID comes from database, test for SQL injection
  • Test with mass operations: Attempt to kill multiple processes rapidly (should be rate-limited)
  • Verify authorized users can control allowed processes: Ensure legitimate functionality works

Common Vulnerable Patterns

  • Accepting user input for process kill/terminate operations
  • Using user-controlled PIDs without validation
  • Missing authorization checks on process control
  • Allowing control of arbitrary system processes
  • No rate limiting on process spawning

Language-Specific Guidance

For detailed, language-specific guidance with comprehensive code examples and security patterns:

  • C: Secure native library loading with dlopen() using absolute paths, LoadLibraryEx() on Windows, execve() for process execution, environment clearing, and LD_PRELOAD prevention
  • C#: Secure DLL loading with DllImport and SetDllDirectory(), Process.Start() without shell execution, strong name verification for assemblies, and DLL hijacking prevention
  • Java: Secure library loading with System.load() using absolute paths, ProcessBuilder for command execution, path validation, allowlist enforcement, and SHA-256 verification
  • JavaScript/Node.js: Process control security in Node.js using child_process, PM2, cluster module, and container orchestration
  • Python: Process control security using os.kill(), subprocess, signal module, and frameworks like psutil, Celery, and Docker

Additional Resources