Потенциальная уязвимость (критическая ошибка, security weakness) — это дефект программного кода, который при определённом стечении обстоятельств может быть использован злоумышленником для влияния на процесс работы программы. Если найден способ использования такого дефекта, он становится уязвимостью (vulnerability).
Программная ошибка. Ошибка в коде может как явно проявлять себя в виде некорректной работы программы, так и оставаться незаметной. Часто именно обыкновенные программные ошибки, а не высокоуровневые просчёты в системах безопасности, могут приводить к появлению уязвимостей.
The National Institute of Standards and Technology (NIST) reports that 64% of software vulnerabilities stem from programming errors and not a lack of security features.
Потенциальная уязвимость. Дефект кода, который теоретически можно использовать и создать эксплойт. Другие названия: дефект безопасности, security weakness, критическая ошибка. Существует система классификации ошибок, приводящих к уязвимостям: Common Weakness Enumeration (CWE). Таким образом, если найденная ошибка в коде может быть классифицирована согласно CWE, то перед нами потенциальная уязвимость.
Критическая ошибка. Термин, вводимый в ГОСТ Р 71207–2024 и фактически обозначающий то же самое, что и потенциальная уязвимость: ошибка, которая может привести к нарушению безопасности обрабатываемой информации.
Компилируемые языки:
Дополнительно для C и C++:
Интерпретируемые языки:
С примерами многих перечисленных здесь ошибок можно познакомиться в презентации Андрея Карпова "Использование статического анализатора в разработке безопасного программного обеспечения (ГОСТ Р 71207-2024) на примере PVS-Studio".
Уязвимость. Дефект, про который известно, что его можно использовать во вредоносных целях. Такие ошибки собираются в базу данных общеизвестных уязвимостей информационной безопасности: Common Vulnerabilities and Exposures (CVE).
Уязвимость нулевого дня (zero day). Термин, обозначающий бреши и уязвимости, которые были допущены разработчиками, но при этом ещё не были ими обнаружены. До тех пор, пока уязвимость не будет устранена, она может использоваться для доступа к сетям, удалённому управлению компьютером, манипуляций с данными и т. п. Такое название термина устоялось по причине того, что у разработчиков нет ни дня на исправление уязвимости: атака становится возможной до момента выпуска патча.
SAST (Static Application Security Testing). Набор технологий, предназначенных для анализа исходного кода ПО в области безопасности. Анализ заключается в поиске участков кода, содержащих потенциальные уязвимости.
Часто понятия "потенциальная уязвимость" и "уязвимость" смешиваются. Делается это или по причине недостаточной компетентности авторов публикаций, или для того, чтобы сделать описание проблем более пугающим.
Например, можно встретить текст такого типа:
Статический анализатор нашёл уязвимость, так как здесь может произойти переполнение буфера...
Но это ещё не уязвимость. Высока вероятность того, что ошибка действительно приводит к некорректной работе программы, но ей никак нельзя воспользоваться. Например, ошибка может приводить лишь к тому, что на экране что-то будет отрисовано не тем цветом.
Только если будет создан эксплойт, который позволяет использовать ошибку с какой-то целью, можно говорить о том, что перед нами уязвимость. До того момента, пока мы точно не знаем, является ошибка безобидной, или это явная уязвимость, мы имеем дело с потенциальной уязвимостью.
Наша команда считает неправильным сгущать краски и писать, что анализатор PVS-Studio нашёл сотни уязвимостей в каком-то приложении. Инструмент находит именно потенциальные уязвимости (критические ошибки). Вероятность, что их можно хоть как-то использовать, весьма низка.
Примечание. Если вы используете PVS-Studio как плагин для SonarQube, то часть предупреждений будет попадать в раздел "Уязвимости". На самом деле это потенциальные уязвимости. Просто разработчики SonarQube решили назвать серьёзные дефекты сразу уязвимостями.
Мы разобрали, почему не стоит каждую ошибку считать уязвимостью. Однако это не значит, что наличие таких ошибок в приложении допустимо. Нет смысла думать, исправлять ли ту или иную потенциальную уязвимость. Любую проблему в коде лучше сразу исправить. Это снизит риски и вероятность создания эксплойта.
В ГОСТ Р 71207–2024 ("Статический анализ программного обеспечения") также указано, что в задачи статического анализа не входит разграничение ошибок в части последствий. Необходимо найти потенциальные места ошибок. Подход безопасной разработки основан на том, что должны исправляться все найденные критические ошибки.
Ошибка "недостижимый код" описана в базе CWE как CWE-561, а значит, является потенциальной уязвимостью. Давайте посмотрим, каким образом такая потенциальная уязвимость может оказаться как безобидной с точки зрения безопасности ошибкой, так и серьёзной уязвимостью.
Вначале рассмотрим фрагмент кода из игры Vangers: One For The Road (подробности).
void uvsVanger::break_harvest(void){
....
pg = Pworld -> escT[0] -> Pbunch
-> cycleTable[Pworld -> escT[0] -> Pbunch -> currentStage].Pgame;
if (!pg) {
return;
ErrH.Abort("uvsVanger::break_harvest : don't know where to go ");
}
....
}
Предупреждение PVS-Studio: V779 CWE-561 Unreachable code detected. It is possible that an error is present.
В случае некоего ошибочного состояния программы функция break_harvest должна записать сообщение в лог и завершить свою работу. Случайно операция записи в лог расположена в коде уже после оператора return. То, что в лог не попадёт отладочное предупреждение, неприятно и однозначно является ошибкой, которую следует исправить. Однако никак нельзя сказать, что эта ошибка является уязвимостью.
Теперь рассмотрим ошибку, которая стала причиной появления уязвимости в операционной системе iOS.
Описание уязвимости CVE-2014-1266: The SSLVerifySignedServerKeyExchange function in libsecurity_ssl/lib/sslKeyExchange.c in the Secure Transport feature in the Data Security component in Apple iOS 6.x before 6.1.6 and 7.x before 7.0.6, Apple TV 6.x before 6.0.2, and Apple OS X 10.9.x before 10.9.2 does not check the signature in a TLS Server Key Exchange message, which allows man-in-the-middle attackers to spoof SSL servers by using an arbitrary private key for the signing step or omitting the signing step.
static OSStatus
SSLVerifySignedServerKeyExchange(SSLContext *ctx,
bool isRsa,
SSLBuffer signedParams,
uint8_t *signature,
UInt16 signatureLen)
{
OSStatus err;
....
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
goto fail;
....
fail:
SSLFreeBuffer(&signedHashes);
SSLFreeBuffer(&hashCtx);
return err;
}
Обратите внимание, что если проверить этот фрагмент кода с помощью PVS-Studio, то он выдаст то же самое предупреждение: V779 CWE-561 Unreachable code detected. It is possible that an error is present.
Из-за двойного goto так же, как и в предыдущем примере, часть кода является недостижимой. Даже если переменная err равна нулю, происходит переход к метке fail. Это приводит к тому, что проверка подписи не производится. Функция возвращает 0, который обозначает, что с подписью всё хорошо. Далее программа получает ключ с сервера, даже если с подписью есть проблемы. Этот ключ нужен для шифрования данных при передаче.
Как видите, здесь точно такая же потенциальная уязвимость на самом деле уже оказалась настоящей серьёзной уязвимостью.
Для поиска потенциальных уязвимостей используют SAST-решения (Static Application Security Testing). Они выполняют статический анализ кода с целью поиска дефектов безопасности. Подобные инструменты ищут дефекты безопасности, описанные, например, CWE и OWASP Top 10.
Примером SAST-решения для поиска потенциальных уязвимостей является PVS-Studio.
0