Main Content

CWE Rule 22

Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

Since R2024a

Description

Rule Description

The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.

Polyspace Implementation

The rule checker checks for Vulnerable path manipulation.

Examples

expand all

Issue

This issue 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.

Example — Relative Path Traversal
# 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+");  //Noncompliant
    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();
}

Check Information

Category: File Handling Issues

Version History

Introduced in R2024a