Анализатор обнаружил, что в буфер копируются данные из небезопасного источника.
Примерами таких источников являются:
Пример небезопасной работы с аргументами командной строки:
int main(int argc, char *argv[]) { .... const size_t buf_size = 1024; char *tmp = (char *) malloc(buf_size); .... strcpy(tmp, argv[0]); .... }
В случае, когда размер копируемых данных превысит размер буфера, произойдёт его переполнение. Для того чтобы избежать этого, лучше вычислить требуемый объём памяти заранее:
int main(int argc, char *argv[]) { .... char buffer[1024]; errno_t err = strncpy_s(buffer, sizeof(buffer), argv[0], 1024); .... }
Также можно выделять память по мере необходимости, используя функцию 'realloc'. В C++ для работы со строками можно использовать классы, такие как 'std::string'.
До стандарта С++20 была доступна возможность использовать C-строку в качестве буфера-приёмника для стандартных потоков ввода ('std::cin', 'std::ifstream'):
void BadRead(char *receiver) { std::cin >> receiver; }
К счастью, в С++ 20 такую возможность убрали, и теперь потоки ввода стандартной библиотеки можно использовать только с массивами известного размера. При этом происходит неявное ограничение максимально считываемого количества символов.
void Exception2Cpp20() { char *buffer1 = new char[10]; std::cin >> buffer1; // Won't compile since C++20 char buffer2[10]; std::cin >> buffer2; // no overflow // max 9 chars will be read }
Более подробно это изменение (с примерами и применением) освещено в предложении P0487R1 к стандарту С++ 20.
Злоумышленники могут манипулировать значением, возвращаемым некоторыми функциями, поэтому следует быть предельно аккуратными при работе с ними:
void InsecureDataProcessing() { char oldLocale[50]; strcpy(oldLocale, setlocale(LC_ALL, nullptr)); .... }
В данном примере создаётся буфер фиксированного размера, в который происходит чтение из переменной окружения 'LC_ALL'. Если у злоумышленника имеется возможность повлиять на неё, то чтение может привести к переполнению буфера.
Предупреждение не выдаётся в случаях, если источник данных неизвестен:
void Exception1(int argc, char *argv[]) { char *src = GetData(); char *tmp = (char *)malloc(1024); strcpy(tmp, src); .... }
Данная диагностика классифицируется как:
|