SV.TAINTED.PATH_TRAVERSAL

Unvalidated input in path construction

If a program uses external input to construct a pathname without special character neutralization, it can be left open to a path traversal attack. This checker reports defects when external strings that are used as parts of file paths are not checked properly.

Vulnerability and risk

A path traversal attack aims to get access to arbitrary files and directories including critical system or application data. A path traversal attack can also be used to provide malicious configuration for a program. It has been ranked as #13 in the Top 25 Most Dangerous Programming Errors.

Mitigation and prevention

To avoid this issue, it's best to add validation code before raw input is used as a pathname. The validation code must contain checks for the following cases:

  • dot-dot-slash ( ../ ): Using this sequence and its variations, an attacker could navigate your file system and obtain access to any file.
 Note that ( ../ ) can be presented in various encodings, for example, " ../../../etc/shadow " .
  • absolute paths: Using absolute paths in a situation when relative paths are expected could also provide access to arbitrary files in your system, for example, " /etc/shadow ".
  • null symbol : Using the null symbol may allow an attacker to truncate a generated filename to widen the scope of attack in a situation when an application restricts possible file extensions by checking or appending specific extension, for example, " application.cfg%00.pdf ".

Vulnerable code example

Copy
  main.c
  #include <stdio.h>
  int main(int argc, char **argv) {
    char *name = argv[1];
    FILE *user_config = fopen(name, "r");
    if (user_config == NULL) {
      return 1;
    }
    fclose(user_config);
    return 0;
  }

Klocwork reports a defect in this example because the "name" string is received through the "argv" argument and is used as a pathname without being validated.

Fixed code example

Copy
  check.h
  char* neutralize(char *);
  main.c
  #include <stdio.h>
  #include "check.h"
  int main(int argc, char **argv) {
     char *name = argv[1];
     name = neutralize(name);
     FILE *user_config = fopen(name, "r");
    if (user_config == NULL) {
       return 1;
    }
    fclose(user_config);
    return 0;
    }

      check.kb
      neutralize - TSCheckPT 1 : $1 : 1

Klocwork will not report a defect in this example because the external input is passed to the "neutralize" function and is validated, making the path safe.

Extension

This checker can be extended through the Klocwork knowledge base. See Tuning C/C++ analysis for more information.