Tainted NULL or non-null-terminated string

Аргумент получен из небезопасного источника и может иметь значение NULL или не быть завершен NULL

Описание

Этот дефект возникает, когда строки из небезопасных источников используются в стандартных программах манипуляции строками, которые неявно передают буфер строк, например strcpy или sprintf. Чтобы считать все входы за пределами периметра анализа тока небезопасными, используйте -consider-analysis-perimeter-as-trust-boundary.

Испорченная строка NULL или строка без обрыв NULL не вызывает дефекта для строки, возвращенной из вызова в scanf-семейные вариадные функции. Точно так же никакой дефект не поднимается, когда вы передаете строку с %s спецификатор для printf-семейные вариадные функции.

Риск

Если строка из небезопасного источника, возможно, что атакующий манипулировал строкой или указывал строковый указатель на другое место памяти.

Если строка имеет значение NULL, строковая стандартная программа не может разлучить строку, что приводит к аварийному завершению работы программы. Если строка не оконечна null, строковая стандартная программа может не знать, когда строка закончится. Эта ошибка может привести к тому, что вы записываете вне границ, вызывая переполнение буфера.

Зафиксировать

Проверьте строку перед использованием. Проверьте, что:

  • Строка не имеет значение NULL.

  • Строка завершена со значением null

  • Размер строки соответствует ожидаемому размеру.

Примеры

расширить все

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define SIZE128 128
#define MAX 40
extern void print_str(const char*);
void warningMsg(void)
{
	char userstr[MAX];
	read(0,userstr,MAX);
	char str[SIZE128] = "Warning: ";
	strncat(str, userstr, SIZE128-(strlen(str)+1));
	print_str(str);
}


В этом примере строка str конкатенируется с аргументом userstr. Значение userstr неизвестно. Если размер userstr больше, чем доступное пространство, переполнение конкатенации.

Коррекция - валидация данных

Одной из возможных коррекций является проверка размера userstr и убедитесь, что строка имеет нулевое значение, прежде чем использовать ее в strncat. Этот пример использует вспомогательную функцию, sansitize_str, для проверки строки. Дефекты сконцентрированы в этой функции.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define SIZE128 128
#define MAX 40
extern void print_str(const char*);
int sanitize_str(char* s) {
	int res = 0; 
	if (s && (strlen(s) > 0)) { // TAINTED_STRING only flagged here
		// - string is not null
		// - string has a positive and limited size
		// - TAINTED_STRING on strlen used as a firewall
		res = 1;
	}
	return res; 
}
void warningMsg(void)
{
	char userstr[MAX];
	read(0,userstr,MAX);
	char str[SIZE128] = "Warning: ";
	if (sanitize_str(userstr))	
		strncat(str, userstr, SIZE128-(strlen(str)+1));
	print_str(str);
}
Коррекция - валидация данных

Другой возможной коррекцией является вызов функции errorMsg и warningMsg с определенными строками.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define SIZE128 128

extern void print_str(const char*);

void warningMsg(char* userstr)
{
    char str[SIZE128] = "Warning: ";
    strncat(str, userstr, SIZE128-(strlen(str)+1));
    print_str(str);
}

void errorMsg(char* userstr)
{
  char str[SIZE128] = "Error: ";
  strncat(str, userstr, SIZE128-(strlen(str)+1));
  print_str(str);
}

int manageSensorValue(int sensorValue) {
  int ret = sensorValue;
  if ( sensorValue < 0 ) {
    errorMsg("sensor value should be positive");
    exit(1);
  } else if ( sensorValue > 50 ) {
    warningMsg("sensor value greater than 50 (applying threshold)...");
    sensorValue = 50;
  }
  
  return sensorValue;
}

Информация о результатах

Группа: испорченные данные
Язык: C | C++
По умолчанию: Off
Синтаксис командной строки: TAINTED_STRING
Влияние: Низкое
ИДЕНТИФИКАТОР CWE: 120, 170, 476, 690, 822
Введенный в R2015b