PVS-Studio: поиск дефектов безопасности
Common Weakness Enumeration (CWE)
Для начала давайте разберемся с терминологией. Для этого я процитирую фрагмент FAQ с сайта cwe.mitre.org.
A1. Что такое CWE? Что такое «дефект безопасности ПО»?
Общий перечень дефектов безопасности ПО (Common Weakness Enumeration, CWE) предназначен для разработчиков и специалистов по обеспечению безопасности ПО. Он представляет собой официальный реестр или словарь общих дефектов безопасности, которые могут проявиться в архитектуре, проектировании, коде или реализации ПО, и могут быть использованы злоумышленниками для получения несанкционированного доступа к системе. Данный перечень был разработан в качестве универсального формального языка для описания дефектов безопасности ПО, а также в качестве стандарта для измерения эффективности инструментов, выявляющих такие дефекты, и для распознавания, устранения и предотвращения этих дефектов.
Дефекты безопасности ПО — это дефекты, сбои, ошибки, уязвимости и прочие проблемы реализации, кода, проектирования или архитектуры ПО, которые могут сделать системы и сети уязвимыми к атакам злоумышленников, если их вовремя не исправить. К таким проблемам относятся: переполнения буферов, ошибки форматной строки и т.д.; проблемы структуры и оценки валидности данных; манипуляции со специальными элементами; ошибки каналов и путей; проблемы с обработчиками; ошибки пользовательского интерфейса; обход каталога и проблемы с распознаванием эквивалентности путей; ошибки аутентификации; ошибки управления ресурсами; недостаточный уровень проверки данных; проблемы оценки входящих данных и внедрение кода; проблемы предсказуемости и недостаточная «случайность» случайных чисел.
A2. В чем разница между уязвимостью и дефектом безопасности ПО?
Дефекты безопасности — это ошибки, которые могут спровоцировать уязвимости. Уязвимости, например, описанные в перечне общих уязвимостей и подверженностей воздействиям (Common Vulnerabilities and Exposures, CVE), — это ошибки программы, которые могут быть непосредственно использованы злоумышленником для получения доступа к системе или сети.
Соответствие между предупреждениями PVS-Studio и CWE
Нам хочется, чтобы анализатор PVS-Studio начали воспринимать не только как инструмент поиска ошибок, но и как инструмент, который помогает сократить количество уязвимостей в коде. Конечно, не каждый дефект безопасности, перечисленный в CWE, является уязвимостью. Можно ли использовать тот или иной дефект для атаки, зависит от множества факторов. Поэтому в дальнейшем мы будем писать, что анализатор PVS-Studio выявляет не уязвимости, а потенциальные уязвимости. Это будет более правильно.
Итак, представляю первый вариант таблицы соответствий. Таблица будет пополняться и уточняться, но даже первый вариант уже позволяет составить общее впечатление о возможностях анализатора.
| CWE | PVS-Studio | CWE Description |
| CWE-14 | V597 | Compiler Removal of Code to Clear Buffers |
| CWE-121 | V755 | Stack-based Buffer Overflow |
| CWE-122 | V755 | Heap-based Buffer Overflow |
| CWE-123 | V575 | Write-what-where Condition |
| CWE-129 | V557, V781, V3106 | Improper Validation of Array Index |
| CWE-131 | V514, V531, V568, V620, V627, V635, V641, V651, V687, V706, V727 | Incorrect Calculation of Buffer Size |
| CWE-134 | V576, V618, V3025 | Use of Externally-Controlled Format String |
| CWE-135 | V518, V635 | Incorrect Calculation of Multi-Byte String Length |
| CWE-188 | V557, V3106 | Reliance on Data/Memory Layout |
| CWE-195 | V569 | Signed to Unsigned Conversion Error |
| CWE-197 | V642 | Numeric Truncation Error |
| CWE-36 | V631, V3039 | Absolute Path Traversal |
| CWE-369 | V609, V3064 | Divide By Zero |
| CWE-401 | V701, V773 | Improper Release of Memory Before Removing Last Reference (‘Memory Leak’) |
| CWE-404 | V611, V773 | Improper Resource Shutdown or Release |
| CWE-415 | V586 | Double Free |
| CWE-416 | V774 | Use after free |
| CWE-457 | V573, V614, V670, V3070, V3128 | Use of Uninitialized Variable |
| CWE-462 | V766, V3058 | Duplicate Key in Associative List (Alist) |
| CWE-467 | V511, V512, V568 | Use of sizeof() on a Pointer Type |
| CWE-468 | V613, V620, V643 | Incorrect Pointer Scaling |
| CWE-476 | V522, V595, V664, V757, V769, V3019, V3042, V3080, V3095, V3105, V3125 | NULL Pointer Dereference |
| CWE-478 | V577, V719, V622, V3002 | Missing Default Case in Switch Statement |
| CWE-481 | V559, V3055 | Assigning instead of comparing |
| CWE-482 | V607 | Comparing instead of Assigning |
| CWE-483 | V640, V3043 | Incorrect Block Delimitation |
| CWE-561 | V551, V695, V734, V776, V779, V3021 | Dead Code |
| CWE-562 | V558 | Return of Stack Variable Address |
| CWE-563 | V519, V603, V751, V763, V3061, V3065, V3077, V3117 | Assignment to Variable without Use (‘Unused Variable’) |
| CWE-570 | V501, V547, V560, V654, V3022, V3063 | Expression is Always False |
| CWE-571 | V501, V547, V560, V617, V654, V694, V3022, V3063 | Expression is Always True |
| CWE-587 | V566 | Assignment of a Fixed Address to a Pointer |
| CWE-588 | V641 | Attempt to Access Child of a Non-structure Pointer |
| CWE-674 | V3110 | Uncontrolled Recursion |
| CWE-690 | V522, V3080 | Unchecked Return Value to NULL Pointer Dereference |
| CWE-762 | V611 | Mismatched Memory Management Routines |
| CWE-805 | V512, V594, V3106 | Buffer Access with Incorrect Length Value |
| CWE-806 | V512 | Buffer Access Using Size of Source Buffer |
| CWE-843 | V641 | Access of Resource Using Incompatible Type (‘Type Confusion’) |
Таблица N1. Первый черновой вариант таблицы соответствий CWE и диагностик PVS-Studio.
Теперь мы сможем писать в статьях о проверке проектов, какие мы нашли потенциальные уязвимости в том или ином проекте. Раз многие хвалятся, что их анализаторы выявляют дефекты безопасности, то и мы затронем эту тему в своих статьях.
Демонстрация
Давайте посмотрим, как приведенную выше таблицу нам можно использовать при написании статей. Проанализируем проект и посмотрим на диагностические сообщения PVS-Studio с точки зрения дефектов безопасности.
Конечно, далеко не каждый проект стоит изучать с точки зрения уязвимости. Поэтому давайте возьмем такой серьезный проект, как Apache HTTP Server.
Итак, проверяем Apache HTTP Server с помощью PVS-Studio и видим, что баги лезут из всех щелей. Стоп! Теперь это не баги, а дефекты безопасности! Намного солидней говорить про потенциальные уязвимости, чем про опечатки и ошибки.
Сразу скажу, что в этот раз мы не будем анализировать проект целиком, так как перед нами стоит задача только показать использование таблицы на практике. Остановимся на трех предупреждениях.
Анализатор PVS-Studio выдаёт предупреждение: V595 The ‘c’ pointer was utilized before it was verified against nullptr. Check lines: 2340, 2348. ssl_engine_kernel.c 2340
С точки зрения дефектов безопасности это: CWE-476 (NULL Pointer Dereference)
Суть ошибки. Выделим две наиболее важные сточки кода:
Проверка (c == NULL) говорит нам, что указатель может быть нулевым. Однако, он уже разыменовывался внутри макроса myConnConfig:
Таким образом, код никак не защищён от разыменовывания нулевого указателя.
Анализатор PVS-Studio выдаёт предупреждение: V597 The compiler could delete the ‘memset’ function call, which is used to flush ‘buf’ buffer. The memset_s() function should be used to erase the private data. passwd_common.c 165
С точки зрения дефектов безопасности это: CWE-14 (Compiler Removal of Code to Clear Buffers)
Суть ошибки. При компиляции кода в режиме оптимизации, компилятор удалит вызов функции memset, так как с точки зрения компилятора этот вызов лишний. После заполнения нулями буфера, созданного на стеке, этот буфер более никак не используется. Значит, заполнять буфер нулями — это пустая трата времени и следует удалить вызов функции memset. Таким образом, приватные данные не будут затерты и останутся в памяти.
Хочу обратить внимание, что это не абстрактное теоретически возможное поведение компилятора. Компиляторы действительно так делают, чтобы ускорить наши программы. Подробности:
С точки зрения дефектов безопасности это: CWE-571 (Expression is Always True)
Мы не авторы кода и точно не знаем, как должен выглядеть код, но, скорее всего, он должен быть таким:
Заключение
Ура, анализатор PVS-Studio может использоваться для выявления потенциальных уязвимостей кода!
Предлагаем всем желающим подробнее познакомиться с анализатором кода PVS-Studio и попробовать демонстрационную версию анализатора на собственных проектах. Страница продукта: PVS-Studio.
По всем техническим вопросам и вопросам лицензирования просим писать нам на почту support [@] viva64.com или воспользоваться формой обратной связи.
Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Andrey Karpov, Phillip Khandeliants. PVS-Studio: searching software weaknesses
CWE Top 25 2021. Что такое, с чем едят и чем полезен при статическом анализе?
Впервые поддержка классификации CWE появилась в PVS-Studio с релизом 6.21, который состоялся 15 января 2018 года. С тех пор прошло уже очень много времени, и хотелось бы рассказать об улучшениях, связанных с поддержкой этой классификации в последних версиях анализатора.
Мы позиционируем анализатор PVS-Studio не только как средство для поиска опечаток и ошибок в коде, но и как инструмент статического тестирования защищённости приложений (Static Application Security Testing, SAST). Для этого необходимо уметь находить ошибки и потенциальные уязвимости, а также сопоставлять их с различными стандартами (например CWE, OWASP, SEI CERT, MISRA, AUTOSAR). Почему именно потенциальные уязвимости? Потому что они (CWE) станут реальными уязвимостями (CVE), только если кто-нибудь начнёт их эксплуатировать. А для этого нередко должно совпасть множество порой не связанных между собой факторов.
Именно с этой целью мы решили проверить, а насколько же хорошо PVS-Studio покрывает самые распространённые на данный момент дефекты. Для этого достаточно обратиться к списку CWE Top 25, который мы почему-то долго обходили стороной. Что ж, пора исправляться!
CWE. Что такое и с чем едят
Думаю, для продолжения не помешает освежить в памяти основные моменты и определения. Если вы хорошо ориентируетесь в терминологии, знаете, чем отличается CVE от CWE, зачем нужен CVSS, как ранжируется CWE Top 25, то можете пропустить этот раздел. Остальным настоятельно советую ознакомиться для удобства дальнейшего чтения. Далее довольно вольный перевод и интерпретация некоторых пунктов CWE FAQ и CVE FAQ:
Чем «дефект» (недостаток) отличается от уязвимости в ПО?
Дефекты (недостатки) – это ошибки, сбои и прочие проблемы реализации, проектирования или архитектуры программного обеспечения, которые могут привести к уязвимостям.
Уязвимости – уже найденные кем-то ошибки, которые могут быть напрямую использованы злоумышленниками для получения доступа к системе или сети, нарушения работы сервисов и так далее.
Что такое CWE, чем отличается от CVE и при чем тут CVSS?
Что такое CWE Top 25?
CWE Top 25 – это список наиболее опасных и распространённых недостатков. Эти недостатки опасны потому, что часто их легко найти и использовать. Они могут позволить злоумышленникам помешать работе приложения, украсть данные или даже полностью захватить систему. CWE Top 25 – это значимый ресурс сообщества, который может помочь разработчикам, тестировщикам, пользователям, а также руководителям проектов, исследователям безопасности и преподавателям получить представление о наиболее распространённых и опасных на данный момент недостатках безопасности.
Каков алгоритм составления и ранжирования списка CWE Top 25?
При составлении текущей редакции списка CWE Top 25 были использованы данные, полученные из национальной базы данных уязвимостей США (U.D. National Vulnerability Database (NVD)) за 2019–2020 годы. Далее команда исследователей использовала на полученных данных собственную формулу для расчёта порядка ранжирования, учитывающую частоту, с которой какой-либо недостаток (CWE) является основной причиной уязвимости, и потенциальную опасность эксплуатации. Частота и прогнозируемая серьёзность нормализованы относительно своих минимальных и максимальных значений.
Для вычисления частоты упоминания в формуле подсчитывается, сколько раз CVE ссылались на CWE в базе данных NVD. В расчёте используются только те CVE, которые имеют ссылку на CWE, поскольку использование полного набора данных привело бы к очень низким показателям частоты и незначительной разнице между различными типами дефектов.
Fr(CWE_X) = (count(CWE_X ∈ NVD) — min(Freq)) / (max(Freq) — min(Freq))
Другим важным компонентом формулы ранжирования является расчёт серьёзности недостатка, который вычисляется по формуле:
Sv(CWE_X) = (average_CVSS_for_CWE_X — min(CVSS)) / (max(CVSS) — min(CVSS))
Ну и в конце вычисляется итоговая оценка путём перемножения оценки частоты упоминания на оценку серьёзности.
Score(CWE_X) = Fr(CWE_X) * Sv(CWE_X) * 100
Хотя этот метод и вносит некоторую предвзятость за счёт анализа только обнаруженных уязвимостей и потенциально может исключить широкий пласт данных, команда CWE считает, что в результате каждый год будет составляться более точный список CWE Top 25.
CWE Top 25 действительно обновляется каждый год?
Да, CWE Top 25 обновляется ежегодно. Предыдущие выпуски CWE Top 25 можно посмотреть в архиве.
Кто занимается составлением CWE Top 25?
Сообщество CWE включает как отдельных исследователей, так и представителей многочисленных организаций, научного сообщества и государственных структур, заинтересованных в активном сокращении и устранении недостатков в программном обеспечении. Конкретный список участников команды CWE можно получить на странице «CWE Community Members».
И зачем мне это знать?
Сегодня CWE используется как основное средство при обсуждении устранения и/или смягчения недостатков безопасности в архитектуре, дизайне, коде и реализации программного обеспечения. Организации используют CWE в качестве стандартной меры для оценки инструментов проверки безопасности ПО и в качестве общего базового стандарта для идентификации, предупреждения и смягчения негативных последствий.
Пару примеров ошибок?
Классификация CWE покрывает наиболее часто встречающиеся проблемы с разработкой ПО и различного оборудования. Например:
Более подробно познакомиться с классификацией можно на сайте cwe.mitre.org.
Положение дел сегодня
С момента начала использования классификации CWE для диагностик PVS-Studio прошло более трёх лет, и хотелось бы отметить существенное увеличение их количества. Если в 2018 году мы покрывали всего 94 пункта списка CWE, то сейчас уже почти 130. Однако сегодня у нас разговор не про общее количество диагностик, а только про те, что входят в список наиболее опасных в 2021 году. Если же вас интересует полный список, то ознакомиться с ним можно в разделе «Соответствие CWE» нашей документации.
Ниже представлена таблица соответствия между списком CWE Top 25 2021 и диагностиками PVS-Studio с разделением по языкам программирования. В дальнейшем мы собираемся регулярно обновлять таблицу с покрытием CWE Top 25 на нашем сайте.
| # | CWE ID | Имя | Оценка | Диагностики PVS-Studio |
|---|---|---|---|---|
| 1 | CWE-787 | Out-of-bounds Write | 65,93 | C++: V512, V557, V582, V645 C#: V3106 Java: V6025 |
| 2 | CWE-79 | Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’) | 46,84 | C#: V5610 |
| 3 | CWE-125 | Out-of-bounds Read | 24,90 | C++: V512, V557, V582 C#: V3106 Java: V6025 |
| 4 | CWE-20 | Improper Input Validation | 20,47 | C++: V739, V781, V1010, V1024, V5009 |
| 5 | CWE-78 | Improper Neutralization of Special Elements used in an OS Command (‘OS Command Injection’) | 19,55 | C++: V1010, V5009 |
| 6 | CWE-89 | Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’) | 19,54 | C#: V5608 |
| 7 | CWE-416 | Use After Free | 16,83 | C++: V623, V723, V758, V774, V1017 |
| 8 | CWE-22 | Improper Limitation of a Pathname to a Restricted Directory (‘Path Traversal’) | 14,69 | C#: V5609 |
| 9 | CWE-352 | Cross-Site Request Forgery (CSRF) | 14,46 | Coming in the future |
| 10 | CWE-434 | Unrestricted Upload of File with Dangerous Type | 8,45 | Coming in the future |
| 11 | CWE-306 | Missing Authentication for Critical Function | 7,93 | Coming in the future |
| 12 | CWE-190 | Integer Overflow or Wraparound | 7,12 | C++: V629, V658, V673, V683, V1026, V1028, V5004, V5005, V5006, V5007, V5010, V5011 C#: V3113 Java: V6105 |
| 13 | CWE-502 | Deserialization of Untrusted Data | 6,71 | C#: V5611 |
| 14 | CWE-287 | Improper Authentication | 6,58 | Coming in the future |
| 15 | CWE-476 | NULL Pointer Dereference | 6,54 | C++: V522, V595, V664, V713, V1004 C#: V3027, V3042, V3080, V3095, V3100, V3125, V3145, V3146, V3148, V3149, V3152, V3153, V3168 Java: V6008, V6060, V6093 |
| 16 | CWE-798 | Use of Hard-coded Credentials | 6,27 | C++: V5013 C#: V5601 Java: V5305 |
| 17 | CWE-119 | Improper Restriction of Operations within the Bounds of a Memory Buffer | 5,84 | C++: V512, V557, V582, V769, V783, V1004 |
| 18 | CWE-862 | Missing Authorization | 5,47 | Coming in the future |
| 19 | CWE-276 | Incorrect Default Permissions | 5,09 | Coming in the future |
| 20 | CWE-200 | Exposure of Sensitive Information to an Unauthorized Actor | 4,74 | Coming in the future |
| 21 | CWE-522 | Insufficiently Protected Credentials | 4,21 | Coming in the future |
| 22 | CWE-732 | Incorrect Permission Assignment for Critical Resource | 4,20 | Coming in the future |
| 23 | CWE-611 | Improper Restriction of XML External Entity Reference | 4,02 | Coming in the future |
| 24 | CWE-918 | Server-Side Request Forgery (SSRF) | 3,78 | Coming in the future |
| 25 | CWE-77 | Improper Neutralization of Special Elements used in a Command (‘Command Injection’) | 3,58 | Coming in the future |
Как видно из таблицы, на данный момент статический анализатор PVS-Studio обеспечивает покрытие 52% (13 из 25) списка CWE Top 25 2021. Вроде 52% это не так и много, но тут стоит учесть, что работы в этом направлении продолжаются и в будущем мы сможем находить ещё больше дефектов. Если же сократить этот список до 10 наиболее опасных и распространённых недостатков, то картина станет лучше — общее покрытие вырастет до 80%. 🙂 Но это уже совсем другая история.
Изменения в CWE Top 25 за последний год
Для самых искушённых предлагаю посмотреть краткую статистку по передвижениям в CWE Top 25 за последний год.
Пять самых крупных передвижений вверх:
| # | CWE ID | Название | Позиция в 2020 г | Позиция в 2021 г | Изменение за год |
|---|---|---|---|---|---|
| 1 | CWE-276 | Incorrect Default Permissions | 41 | 19 | 22▲ |
| 2 | CWE-306 | Missing Authentication for Critical Function | 24 | 11 | 13▲ |
| 3 | CWE-502 | Deserialization of Untrusted Data | 21 | 13 | 8▲ |
| 4 | CWE-862 | Missing Authorization | 25 | 18 | 7▲ |
| 5 | CWE-77 | Improper Neutralization of Special Elements used in a Command (‘Command Injection’) | 31 | 25 | 6▲ |
Пять самых крупных передвижений вниз:
| # | CWE ID | Название | Позиция в 2020 г | Позиция в 2021 г | Изменение за год |
|---|---|---|---|---|---|
| 1 | CWE-200 | Exposure of Sensitive Information to an Unauthorized Actor | 7 | 20 | 13▼ |
| 2 | CWE-119 | Improper Restriction of Operations within the Bounds of a Memory Buffer | 5 | 17 | 12▼ |
| 3 | CWE-94 | Improper Control of Generation of Code (‘Code Injection’) | 17 | 28 | 11▼ |
| 4 | CWE-269 | Improper Privilege Management | 22 | 29 | 7▼ |
| 5 | CWE-732 | Incorrect Permission Assignment for Critical Resource | 16 | 22 | 6▼ |
Большинство CWE, представленных в таблице выше, относятся к категориям, которые трудно поддаются анализу. Объяснить их снижение в рейтинге (а соответственно и появление в этой таблице) можно тем, что сообщество улучшило свои образовательные, инструментальные и аналитические возможности, тем самым уменьшив частоту упоминания ошибок, относящихся к данным категориям.
| # | CWE ID | Название | Позиция в 2020 г | Позиция в 2021 г | Изменение за год |
|---|---|---|---|---|---|
| 1 | CWE-276 | Incorrect Default Permissions | 41 | 19 | 22▲ |
| 2 | CWE-918 | Server-Side Request Forgery (SSRF) | 27 | 24 | 3▲ |
| 3 | CWE-77 | Improper Neutralization of Special Elements used in a Command (‘Command Injection’) | 31 | 25 | 6▲ |
Ну и в конце – дефекты, которые выбыли из CWE Top 25 в 2021 году:
| # | CWE ID | Название | Позиция в 2020 г | Позиция в 2021 г | Изменение за год |
|---|---|---|---|---|---|
| 1 | CWE-400 | Uncontrolled Resource Consumption | 23 | 27 | 4▼ |
| 2 | CWE-94 | Improper Control of Generation of Code (‘Code Injection’) | 17 | 28 | 11▼ |
| 3 | CWE-269 | Improper Privilege Management | 22 | 29 | 7▼ |
Заключение
Надеюсь, что данный материал был для вас интересен и помог разобраться в актуальной терминологии.
К счастью, в борьбе с потенциальными уязвимостями нам могут помочь статические анализаторы и поэтому, по традиции, мне хотелось бы предложить вам скачать и попробовать проверить свой проект статическим анализатором PVS-Studio. Вдруг и у вас в код закралась парочка CWE, которые только и ждут удобного момента, чтобы стать полноценными CVE 🙂



