Main Content

Sources of Tainting in a Polyspace Analysis

Generally, any code element that can be modified from outside of the code is considered tainted data. An attacker might pass values to tainted variables to cause program failure, inject malicious code, or leak resources. The results of operations that use tainted data are also considered tainted.. For instance, if you calculate a path to a file by using tainted variable, the file also becomes tainted. To mitigate risks associated with tainted data, validate the content of the data before you use it.

Enhance the security of your code by using the Polyspace® tainted data defect checkers to identify sources of tainted data and then validating data from those sources.

Sources of Tainted Data

Polyspace considers data from these sources as tainted data:

  • Volatile objects: Objects declared by using the keyword volatile can be modified by the hardware during program execution. Using volatile objects without checking their content might lead to segmentation errors, memory leak or security threat. Polyspace flags operations that use volatile objects without validating them.

  • Functions that obtains a user input: Library functions such as getenv, gets, read, scanf, or fopen return user inputs such as an environment variable, a string, a data stream, formatted data or a file. The main() might also take input arguments directly from the user. User dependent inputs are unpredictable. Before using these input, validate them by checking their format, length, or content.

  • Functions that interacts with hardware: Library functions such as RegQueryValueEx interacts with hardware like registers and peripherals. These functions return hardware dependent data that might be unpredictable. Before using data obtained from hardware, validate them by checking their format, length, or content.

  • Functions that returns the current time: Library functions such as ctime returns the current time of the system as a formatted string. The format of the string depends on the environment. Before using such strings, validate them by checking their format.

  • Functions that return a random number: Before using random numbers, validate them by checking their format and range.

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. See Modify Default Behavior of Bug Finder Checkers

Impact of Tainted Data Defects

An attacker might exploit tainted data defects by deliberately feeding unexpected input to the program to expose the stack or execute commands that access or delete sensitive data. Consider this code which uses input from the user to modify the system.

#include <stdio.h>
#include <stdlib.h>
#define MAX 128
void Echo(char* string, int n) {
	printf("Argument %d is; ",n);
	printf(string); //Tainted operation
}
void SystemCaller(char* string){
	printf("Calling System...");
	char cmd[MAX] = "/usr/bin/cat ";
	strcat(cmd, string);
	system(cmd);//Tainted operation
}

int main(int argc, char** argv) {
	int i = 0;
	for(i = 0;i<argc;++i){
		Echo(argv[i],i);
		SystemCaller(argv[i]);
	}
	return (0);
}
The input from the user is tainted. Polyspace flags two tainted data defects in this code.

  • In the function Echo, the line printf(string) print a user input string without validating the string. This defect enables an attacker to expose the stack by manipulating the input string. For instance, if the user input is "%d", function prints the integer in the stack after n is printed.

  • In the function SystemCaller, a user input string is used to call an operating system command. Malicious users can execute commands to access or delete sensitive data, and even crash the system by exploiting this defect.

To prevent such attacks, validate the tainted data by checking their format, length, or content. For instance, in this code, the tainted inputs are validated before they are used.

#include <stdio.h>
#include <stdlib.h>
#define MAX 128
extern char** LIST_OF_COMMANDS;
int isAllowd(char*);
void Echo(char* string, int n) {
	printf("Argument %d is; ",n);
	printf("%s",string); //Validated
}
void SystemCaller(char* string){
	printf("Calling System...");
	char cmd[MAX] = "/usr/bin/cat ";
	if(isallowed(string)==1){
	strcat(cmd, string);
	system(cmd);//Validated
	}
}

int main(int argc, char** argv) {
	int i = 0;
	for(i = 0;i<argc|| i<10;++i){
		Echo(argv[i],i);
		SystemCaller(argv[i]);
	}
	return (0);
}
By specifying the format as %s in printf, the tainted input string is validated. Now, the program prints the content of the string and the stack is no longer exposed. In SystemCaller, the program executes an operating system command only if the input matches an allowed command.

For details about the tainted data defects in Polyspace, see Tainted Data Defects.

Polyspace Tainted Data Checkers

Check Tainted Data by using these Bug Finder defects and coding rules:

See Also

|

Related Topics