Продолжаем тематику «Причины и виды уязвимости приложений».
Уязвимость целочисленного переполнения возникает как результат некорректных операций над данными целого типа. Последствия целочисленного переполнения могут быть самыми разными — от некорректного результата до краха приложения. Данная уязвимость может быть использована для изменения значения критически важных данных — изменения размера буфера, значения индекса массива. При этом возникает возможность переполнения буфера. К возникновению данной уязвимости могут привести следующие операции:
-
совместное оперирование знаковыми и беззнаковыми целыми (например, сравнение знакового целого и беззнакового);
-
усечение целых (например, усечение32-битовогоцелого до16-битового);
-
потеря значимости и переполнение (например, в результате суммирования двух целых может быть получено число большее, чем максимально возможное для целого типа данных).
Следующие особенности кода приложения свидетельствуют о потенциальной возможности уязвимости:
-
смешивание знаковых и беззнаковых целых в операциях вычисления и сравнения;
-
смешивание данных различных типов в операциях вычисления и сравнения;
-
сравнение переменных и литералов;
-
отсутствие проверки входных данных;
-
использование результата вычисления без его проверки.
Основным методом обнаружения данной уязвимости является ревизия исходных текстов программного обеспечения. Важно, чтобы все случаи динамически выделяемой памяти и индексных массивов, использующих целочисленную арифметику, были проанализированы на предмет корректности. В процессе такой проверки необходимо тестировать следующие ситуации:
-
ввод отрицательных значений при запросе на ввод целых чисел;
-
ввод целых, соответствующих граничным значениям хранения данных в одном байте, двух байтах и т.д. — т.е. чисел 0, 7, 8, 254, 255, 16353, 16354;
-
ввод очень длинных строк (более 64 К);
-
ввод строк, длина которых равна типичным граничным значениям (32К, 32К-1, 64К-1, 64К);
-
ввод случайных, непредусмотренных или неверных данных — так называемый Fuzz testing. Fuzz testing — это техника тестирования, состоящая в подаче на вход приложения случайных и направленно сформированных наборов данных с целью генерации ошибок в приложении или его аварийного завершения. Процентный показатель сбоев и крахов приложения является показателем уязвимости.
Чтобы минимизировать вероятность возникновения данной уязвимости, следует придерживаться следующих правил:
-
для проверки текстов программ использовать инструментальные средства анализа, обладающие низкой вероятностью ошибок2-города для уязвимостей данного типа;
-
везде, где возможно, использовать беззнаковые целые;
-
при выделении памяти использовать только беззнаковые целые;
-
при построении индексированных массивов использовать только беззнаковые целые;
-
проверять введенные пользователем числовые данные, разрешая только заведомо корректные данные;
-
при компиляции приложения устанавливать максимально подробный уровень сообщений компилятора.