Process Control

ID

csharp.process_control

Severity

critical

Resource

Injection

Language

CSharp

Tags

CWE:114, NIST.SP.800-53, OWASP:2021:A1, OWASP:2021:A8, PCI-DSS:6.5.8

Description

Executing commands or loading libraries from an untrusted source or in an untrusted environment can cause an application to execute malicious commands (and payloads) on behalf of an attacker.

This happens when the software use external input to choose which program or library to execute.

Rationale

Some .NET methods load dynamically native libraries or executing external processes. When these methods can be affected by untrusted input, an attacker can control the execution of unintended code.

Examples include AppDomain.Load() or AppDomain.ExecuteAssembly() for loading or executing .NET assemblies, AppDomain.CreateInstance to create an wrapped instance of a .NET type.

If these method are influenced by untrusted input, including system environment or configuration properties, a security violation may be triggered.

Please note that other detectors check for control of OS executable names by untrusted input, as with Process.Start(), which is a different vulnerability (OS Command Injection).

For example, consider:

  public void RunAssembly() {
    // if an attacker manages to alter configuration, this is catastrophic
    string libpath = ConfigurationManager.AppSettings["MY_LIBRARY"];
    Environment.ExitCode = AppDomain.CurrentDomain.ExecuteAssembly(libpath); // FLAW
  }

Here, an attacker controlling the MY_LIBRARY property can redirect the library loading process, potentially executing a malicious library.

Remediation

To mitigate risks associated with loading libraries dynamically, the best practice is to whitelist allowed libraries to load: Never allow untrusted sources to dictate the name or path of the library being loaded. Ensure that all inputs are validated and sanitized before use. A whitelist of allowed libraries can be configured in the application, so that only approved libraries can be loaded.

In the previous example, a whitelist of allowed libraries could be checked against the MY_LIBRARY configuration property:

  public void RunAssembly() {
    string libpath = ConfigurationManager.AppSettings["MY_LIBRARY"];

    if (string.IsNullOrEmpty(libpath)) return;

    // FIX: Whitelist of allowed assemblies, possibly taken from a trusted source
    var allowedAssemblies = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
    {
        "TrustedLib1.dll", "TrustedLib2.dll"
    };

    if (allowedAssemblies.Contains(libpath))
    {
        Environment.ExitCode = AppDomain.CurrentDomain.ExecuteAssembly(libpath);
    }
    else
    {
        throw new InvalidOperationException("Unauthorized assembly path.");
    }
  }

Configuration

The detector has the following configurable parameters:

  • alwaysReportLoadLibrary, that indicates if using loadLibrary() should be considered always insecure.

  • sources, that indicates the source kinds to check.

  • neutralizations, that indicates the neutralization kinds to check.

References