Данные об уязвимостях
Как читать CVE: что запись CVE сообщает и о чём молчит
Запись CVE называет уязвимость и указывает на вендора, а исправленную версию определяет бюллетень вендора.
Что значит оценка CVSS вроде 9.8, как устроены векторы v4.0 и v3.1 и как разобрать и пересчитать вектор вручную.
CVSS — система оценки, на которой построено большинство опубликованных оценок уязвимостей. Вы увидите число от 0.0 до 10.0, слово, обозначающее критичность, например «Critical», и длинную строку, похожую на серийный номер. В этой статье разобрано, что значит каждая часть, как читать строку поле за полем и как самостоятельно проверить опубликованную оценку.
CVSS расшифровывается как Common Vulnerability Scoring System. Её поддерживает FIRST, Forum of Incident Response and Security Teams. Текущая версия 4.0 вышла в конце 2023 года. Версия 3.1 всё ещё встречается в большинстве старых advisories и в базе NVD, поэтому читать нужно обе.
CVSS присваивает уязвимости оценку от 0.0 до 10.0. Оценка зависит от свойств уязвимости: насколько трудно до неё добраться, что нужно атакующему заранее и какой ущерб она может причинить при эксплуатации. Большинство инструментов сопоставляет число с рейтингом:
| Рейтинг | Диапазон оценок |
|---|---|
| None | 0.0 |
| Low | от 0.1 до 3.9 |
| Medium | от 4.0 до 6.9 |
| High | от 7.0 до 8.9 |
| Critical | от 9.0 до 10.0 |
В v3.1 и v4.0 рейтинги одинаковые. Математика за числом у них разная.
Командам нужно общее слово для критичности. Вендор пишет advisory, сканер помечает актив, менеджер спрашивает, какой патч ставить первым, и все должны понимать под «high» одно и то же. CVSS даёт им общую шкалу. Вектор к тому же фиксирует ход рассуждений, поэтому читатель может проверить, подходит ли оценка к его системе.
У оценки есть пределы, и большинство ошибок возникает, когда о них забывают. Главный предел описан в разделе о критичности и вероятности.
В CVSS v4.0 метрики разбиты на четыре группы. Для получения оценки нужна только базовая группа.
Базовые метрики описывают уязвимость такой, какой она существует в уязвимом ПО, без знания о вашей сети. Advisories почти всегда их публикуют. В v4.0 они охватывают:
Метрики угрозы меняются со временем. Метрика угрозы в v4.0 называется E, это зрелость эксплойта. Она может быть A (attacked, есть свидетельства эксплуатации), P (существует proof of concept), U (unreported) или X (не определена, значение по умолчанию). Оценка с заданной E может отличаться от базовой и меняется вместе с картиной угроз.
Метрики окружения описывают ваше развёртывание. Метрики требований (CR, IR и AR для конфиденциальности, целостности и доступности) говорят, насколько важно для вас каждое свойство. Модифицированные базовые метрики позволяют переопределить базовое значение, если ваша конфигурация его меняет. Уязвимость на странице входа, открытой в интернет, и та же уязвимость в лабораторной VM без сетевого маршрута могут иметь одинаковую базовую оценку и всё же заслуживать в вашем окружении разного приоритета.
Дополнительные метрики добавляют контекст, например влияние на безопасность людей, возможность автоматизации, трудоёмкость восстановления или срочность. На оценку они не влияют. Они помогают команде сортировать работу.
Версия 3.1 использует группы Base, Temporal и Environmental. Дополнительной группы в ней нет, а её временные метрики (зрелость кода эксплойта, уровень устранения и достоверность отчёта) отличаются от единственной метрики E в v4.0.
Вектор — компактная форма метрик. Он начинается с версии, а затем перечисляет каждую метрику как Name:Value, через слеши. Каждое значение состоит из одной буквы. Когда вы знаете буквы, любую строку можно прочитать без таблицы.
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:NРазберём поле за полем:
| Поле | Значение | Смысл |
|---|---|---|
| CVSS | 4.0 | Версия спецификации |
| AV | N | Вектор атаки: сеть. Другие значения: A (смежная сеть), L (локальный) и P (физический). |
| AC | L | Сложность атаки: низкая. Другое значение: H. |
| AT | N | Требования к атаке: нет. Другое значение: P (есть), для условий вроде окна гонки или особой настройки развёртывания. |
| PR | N | Необходимые привилегии: нет. Другие: L (низкие) и H (высокие). |
| UI | N | Взаимодействие с пользователем: нет. Другие: P (пассивное) и A (активное). |
| VC | H | Влияние на конфиденциальность уязвимой системы: высокое. Другие: L и N. |
| VI | H | Влияние на целостность уязвимой системы: высокое. |
| VA | H | Влияние на доступность уязвимой системы: высокое. |
| SC | N | Влияние на конфиденциальность последующих систем: нет. Другие: L и H. |
| SI | N | Влияние на целостность последующих систем: нет. |
| SA | N | Влияние на доступность последующих систем: нет. |
Простыми словами: человек в сети может проэксплуатировать это без входа, без особой подготовки и без действий жертвы. Атака даёт полный контроль над конфиденциальностью, целостностью и доступностью уязвимого компонента, и ничем за его пределами. Калькулятор FIRST возвращает для этого вектора базовую оценку 9.3 (Critical). Как это проверить, показано в лабораторной ниже.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:HПоля v3.1 похожи, но есть три отличия. Поля AT нет. Поля влияния называются C, I и A, без разделения на уязвимую и последующие системы. И вместо этого появляется S (scope):
| Поле | Значение | Смысл |
|---|---|---|
| AV | N | Вектор атаки: сеть. Другие: A, L и P. |
| AC | L | Сложность атаки: низкая. Другое значение: H. |
| PR | N | Необходимые привилегии: нет. Другие: L и H. |
| UI | N | Взаимодействие с пользователем: нет. Другое значение: R (требуется). |
| S | C | Scope изменён: эксплойт может затронуть компонент за пределами того, в котором находится уязвимость. U значит unchanged. |
| C | H | Конфиденциальность: высокая. Другие: L и N. |
| I | H | Целостность: высокая. |
| A | H | Доступность: высокая. |
Поле S объясняет большую часть разницы между 9.8 и 10.0 далее в статье.
Изменения затрагивают структуру, поэтому, если читать оценку одной версии как оценку другой, возникают ошибки.
В advisories версии до сих пор перемешаны. Некоторые публикуют для одной уязвимости оценки и v3.1, и v4.0, и эти числа могут различаться. Прежде чем сравнивать два числа, проверьте префикс.
Это самое важное, и именно это чаще всего пропускают. CVSS измеряет, насколько серьёзна уязвимость, если её проэксплуатируют. Станет ли кто-то её эксплуатировать, CVSS не говорит.
Уязвимость с базовой оценкой Critical может годами оставаться неэксплуатируемой. Уязвимость Medium может подвергаться активным атакам на этой неделе. CVSS этого не видит. Группа угроз может содержать некоторые сведения об эксплуатации (например, E со значением A), но кто-то всё равно должен выставить это значение и поддерживать его в актуальном состоянии. На вопрос о вероятности отвечают другие источники:
Когда надо решить, что патчить первым, смотрите на критичность, вероятность и доступность извне вместе. Высокая оценка CVSS на системе, до которой никто не может добраться, обычно менее срочна, чем средняя оценка на публичной странице входа с зафиксированной эксплуатацией.
Об основах, то есть о том, что такое уязвимость и как она получает идентификатор, читайте в статьях что такое уязвимость и что такое идентификатор CVE.
Понадобятся терминал и браузер. Лабораторная использует только публичные данные. Она обращается к публичному API NVD и сайту FIRST, больше ни к чему.
API NVD возвращает оценки, которые NVD хранит для CVE. Для CVE-2021-44228, уязвимости Log4Shell в Apache Log4j, выполните:
curl -s 'https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2021-44228' | jq -r '.vulnerabilities[0].cve.metrics | .. | .vectorString? // empty'Фильтр обходит весь объект metrics и печатает каждый найденный vectorString. На машине, где проверялась эта статья, jq не был установлен. Тот же обход выполнялся на Node 24. Если у вас нет jq, используйте этот запасной вариант:
curl -s 'https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2021-44228' -o nvd_44228.json
node -e "const j=JSON.parse(require('fs').readFileSync('nvd_44228.json','utf8'));const out=[];(function walk(n){if(n&&typeof n==='object'){for(const[k,v]of Object.entries(n)){if(k==='vectorString')out.push(v);else walk(v);}}})(j.vulnerabilities[0].cve.metrics);console.log(out.join('\n'));"Вывод, полученный 8 ноября 2026 года:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
AV:N/AC:M/Au:N/C:C/I:C/A:CПервые две строки — вектор v3.1 из собственной записи NVD и из второй записи, которую указывает NVD. Третья строка — вектор CVSS v2.0, более старой шкалы. В этой лабораторной не обращайте на него внимания. NVD может обновить запись, поэтому ваш вывод может отличаться.
Возьмите первую строку и заполните таблицу наподобие приведённых выше. Запишите каждое поле и его смысл, прежде чем открывать калькулятор. Помогут два вопроса:
Второго взгляда заслуживает поле S:C. Оно означает, что эксплойт выходит за пределы компонента с уязвимостью. Поэтому такой вектор получает более высокую оценку, чем тот же вектор с S:U.
Откройте калькулятор для версии из вашей строки. Для v3.1 это https://www.first.org/cvss/calculator/3.1. Для v4.0 это https://www.first.org/cvss/calculator/4.0. Вектор можно вставить в URL после #, чтобы форма заполнилась заранее.
Для приведённого выше примера v4.0 откройте эту ссылку:
https://www.first.org/cvss/calculator/4.0#CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:NКалькулятор должен вернуть для этого вектора базовую оценку 9.3 (Critical). Во время написания статьи я не запускал его в браузере, поэтому считайте 9.3 значением, которое нужно подтвердить. Если результат другой, сравните каждую букву в форме со своей таблицей.
Для вектора v3.1 из NVD откройте калькулятор v3.1 и выставьте значения по своей таблице. Ожидаемая оценка 10.0. Если после загрузки страницы форма осталась пустой, выберите значения вручную, это само по себе полезная проверка.
В v3.1 базовая формула настолько коротка, что умещается в несколько строк. Этот скрипт следует спецификации v3.1. Он нужен для проверки понимания, в продакшене его использовать не стоит. Сохраните его как cvss31.js:
// CVSS v3.1 base score, following the FIRST v3.1 specification.
function roundup(x) {
const i = Math.round(x * 100000);
return i % 10000 === 0 ? i / 100000 : (Math.floor(i / 10000) + 1) / 10;
}
function base(vec) {
const m = Object.fromEntries(vec.split('/').slice(1).map(p => p.split(':')));
const S = m.S === 'C';
const AV = { N: 0.85, A: 0.62, L: 0.55, P: 0.2 }[m.AV];
const AC = { L: 0.77, H: 0.44 }[m.AC];
const PR = { N: 0.85, L: S ? 0.68 : 0.62, H: S ? 0.5 : 0.27 }[m.PR];
const UI = { N: 0.85, R: 0.62 }[m.UI];
const cia = { H: 0.56, L: 0.22, N: 0 };
const iss = 1 - (1 - cia[m.C]) * (1 - cia[m.I]) * (1 - cia[m.A]);
const imp = S ? 7.52 * (iss - 0.029) - 3.25 * Math.pow(iss - 0.02, 15) : 6.42 * iss;
const expl = 8.22 * AV * AC * PR * UI;
if (imp <= 0) return 0;
return S ? roundup(Math.min(1.08 * (imp + expl), 10)) : roundup(Math.min(imp + expl, 10));
}
for (const v of process.argv.slice(2)) console.log(v, '->', base(v).toFixed(1));Запустите его на векторе NVD и на том же векторе со scope unchanged:
node cvss31.js "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H" "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"Вывод, полученный 8 ноября 2026 года:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H -> 10.0
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H -> 9.8Первая строка совпадает с оценкой NVD 10.0. Вторая даёт 9.8, которые многие помнят для этой уязвимости. Единственное изменение — S:U. Увидев оценку, прочитайте её вектор, прежде чем доверять числу.
Если ваша таблица, калькулятор и скрипт совпали, вы умеете читать строку CVSS. Если нет, найдите поле с расхождением. Обычные причины: неверная буква (AV:L значит local, а не low), путаница между C, I и A или сравнение оценки v3.1 с оценкой v4.0 как будто на одной шкале.
Сначала прочитайте определения базовых метрик в спецификации. Они короткие, и ответы на вопросы кроются в точных формулировках каждого значения. Затем разберите на бумаге пять или шесть опубликованных векторов, прежде чем проверять каждый в калькуляторе. Выберите несколько с S:C или AT:P и посмотрите, как меняется оценка.
После этого почитайте об эксплуатации: что оценивает EPSS и что фиксирует каталог KEV. Они отвечают на вопрос, который CVSS оставляет открытым: атакует ли кто-нибудь эту уязвимость прямо сейчас.
Данные об уязвимостях
Запись CVE называет уязвимость и указывает на вендора, а исправленную версию определяет бюллетень вендора.
Данные об уязвимостях
Расставляем приоритеты CVE по каталогу CISA KEV и оценкам EPSS от FIRST рядом с CVSS, затем строим таблицу приоритетов из обоих бесплатных фидов.