C & C++

C & C++

Made by DeepSource

Audit required: calling command processor based system() is exploitable CXX-A1001

Security
Major
cwe-78

The system() function in C programming executes a specified command by invoking an implementation-defined command processor, such as a UNIX shell or CMD.EXE in Microsoft Windows.

The problem with using system() function is that it can result in exploitable vulnerabilities, allowing for the execution of arbitrary system commands. The risks associated with using the system() function include passing an unsanitized or improperly sanitized command string originating from a tainted source, specifying a command without a path name and the command processor path name resolution mechanism is accessible to an attacker, specifying a relative path to an executable and control over the current working directory is accessible to an attacker, and if the specified executable program can be spoofed by an attacker.

To prevent these security risks, it is recommended not to invoke a command processor via system(). Consider using the alternative options available in the platform, for example, exec family function calls in POSIX compliant systems or CreateProcess on Windows.

Bad practice

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

enum { BUFSIZE = 512 };

int run_command(const char *cmd) {
  char cmdbuf[BUFSIZE];
  int len = snprintf(cmdbuf, BUFSIZE, "any_cmd '%s'", cmd);

  if (len >= BUFSIZE) {
    return 1;
  }
  if (len < 0) {
    return 2;
  }
  if (system(cmdbuf) == -1) {
    return -1;
  }
  // command finished successfully
  return 0;
}

Recommended

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>

int run_command(const char* cmd, const char* arg, char** env) {
  pid_t pid;
  int status;
  pid_t retval;

  /* ... Sanitize arguments ... */

  pid = fork();
  if (pid == -1) {
    return -1;
  } else if (pid != 0) {
    while ((retval = waitpid(pid, &status, 0)) == -1) {
      if (errno != EINTR) {
        break;
      }
    }
    if ((retval == 0) || !(WIFEXITED(status) && !WEXITSTATUS(status))) {
      /* Report unexpected child status */
      return -2;
    }
  } else {
    if (execve("/usr/bin/any_cmd", args, env) == -1) {
      _Exit(127);
    }
  }
  return 0;
}

References