Main Content

Vulnerable path manipulation

Path argument with /../, /abs/path/, or other unsecure elements

Description

This defect occurs when you create a relative or absolute path from a tainted source and you then use the path to open/create files.

Risk

Relative path elements, such as ".." can resolve to locations outside the intended folder. Absolute path elements, such as "/abs/path" can also resolve to locations outside the intended folder.

An attacker can use these types of path traversal elements to traverse to the rest of the file system and access other files or folders.

Fix

Avoid vulnerable path traversal elements such as /../ and /abs/path/. Use fixed file names and locations wherever possible.

Examples

expand all

# include <stdio.h>
# include <string.h>
# include <wchar.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <unistd.h>
# include <stdlib.h>
# define BASEPATH "/tmp/"
# define FILENAME_MAX 512

static void Relative_Path_Traversal(void)
{
    char * data;
    char data_buf[FILENAME_MAX] = BASEPATH;
    char sub_buf[FILENAME_MAX];

    if (fgets(sub_buf, FILENAME_MAX, stdin) == NULL) exit (1);
    data = data_buf;
    strcat(data, sub_buf);

    FILE *file = NULL;
    file = fopen(data, "wb+"); 
    if (file != NULL) fclose(file);
}

int path_call(void){
    Relative_Path_Traversal();
}

This example opens a file from "/tmp/", but uses a relative path to the file. An external user can manipulate this relative path when fopen opens the file.

Correction — Use Fixed File Name

One possible correction is to use a fixed file name instead of a relative path. This example uses file.txt.

# include <stdio.h>
# include <string.h>
# include <wchar.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <unistd.h>
# include <stdlib.h>
# define BASEPATH "/tmp/"
# define FILENAME_MAX 512

static void Relative_Path_Traversal(void)
{
    char * data;
    char data_buf[FILENAME_MAX] = BASEPATH;
    data = data_buf;

    /* FIX: Use a fixed file name */
    strcat(data, "file.txt");
    FILE *file = NULL;
    file = fopen(data, "wb+");  
    if (file != NULL) fclose(file);
}

int path_call(void){
    Relative_Path_Traversal();
}

Result Information

Group: Security
Language: C | C++
Default: Off
Command-Line Syntax: PATH_TRAVERSAL
Impact: Low

Version History

Introduced in R2015b