Main Content

CWE Rule 15

External Control of System or Configuration Setting

Since R2024a

Description

Rule Description

One or more system settings or configuration elements can be externally controlled by a user.

Polyspace Implementation

The rule checker checks for these issues:

  • Host change using externally controlled elements

  • Use of externally controlled environment variable

Examples

expand all

Issue

This issue occurs when routines that change the host ID, such as sethostid (Linux®) or SetComputerName (Windows®), use arguments that are externally controlled.

Risk

The tainted host ID value can allow external control of system settings. This control can disrupt services, cause unexpected application behavior, or cause other malicious intrusions.

Fix

Use caution when changing or editing the host ID. Do not allow user-provided values to control sensitive data.

Extend Checker

By default, Polyspace® assumes that data from external sources are tainted. See Sources of Tainting in a Polyspace Analysis. To consider any data that does not originate in the current scope of Polyspace analysis as tainted, use the command line option -consider-analysis-perimeter-as-trust-boundary.

Example — Change Host ID from Function Argument
#include <unistd.h>
#include <stdlib.h>

void bug_taintedhostid(void) {
    long userhid = strtol(getenv("HID"),NULL,10);
    sethostid(userhid);//Noncompliant //Noncompliant
}

This example sets a new host ID using the argument passed to the function. Before using the host ID, check the value passed in.

Correction — Predefined Host ID

One possible correction is to change the host ID to a predefined ID. This example uses the host argument as a switch variable to choose between the different, predefined host IDs.

#include <unistd.h>
#include <stdlib.h>

extern long called_taintedhostid_sanitize(long);
enum { HI0 = 1, HI1, HI2, HI3 };

void taintedhostid(void) {
    long host = strtol(getenv("HID"),NULL,10);
    long hid = 0;
    switch(host) {
        case HI0:
            hid = 0x7f0100;
            break;
        case HI1:
            hid = 0x7f0101;
            break;
        case HI2:
            hid = 0x7f0102;
            break;
        case HI3:
            hid = 0x7f0103;
            break;
        default:
            /* do nothing */
	    break;
    }
    if (hid > 0) {
        sethostid(hid);
    }
}
Issue

This issue occurs when functions that add or change environment variables, such as putenv and setenv, obtain new environment variable values from unsecure sources.

Risk

If the environment variable is tainted, an attacker can control your system settings. This control can disrupt an application or service in potentially malicious ways.

Fix

Before using the new environment variable, check its value to avoid giving control to external users.

Extend Checker

By default, Polyspace assumes that data from external sources are tainted. See Sources of Tainting in a Polyspace Analysis. To consider any data that does not originate in the current scope of Polyspace analysis as tainted, use the command line option -consider-analysis-perimeter-as-trust-boundary.

Example — Set Path in Environment
#define _XOPEN_SOURCE
#define _GNU_SOURCE
#include "stdlib.h"

void taintedenvvariable(void)
{
    char* path = getenv("APP_PATH");
    putenv(path); //Noncompliant
}

In this example, putenv changes an environment variable. The path path has not been checked to make sure that it is the intended path.

Correction — Sanitize Path

One possible correction is to sanitize the path, checking that it matches what you expect.

#define _POSIX_C_SOURCE
#include <stdlib.h>
#include <string.h>

/* Function to sanitize a path */
const char * sanitize_path(const char* str) {
	/* secure allowlist of paths */
	static const char *const authorized_paths[] = {
		"/bin",
		"/usr/bin"
	};
	if (str != NULL) {
		for (int i = 0; i < sizeof(authorized_paths) / sizeof(authorized_paths[0]); i++)
		if (strcmp(authorized_paths[i], str) == 0) {
			return authorized_paths[i];
		}
	}
	return NULL;
}

void taintedenvvariable(void)
{
	const char* path = getenv("APP_PATH");
	path = sanitize_path(path);
	if (path != NULL) {
		if (setenv("PATH", path, /* overwrite = */1) != 0) {
			/* fatal error */
			exit(1);
		}
	}
} 

Check Information

Category: State Issues

Version History

Introduced in R2024a