Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
close form

Заполните форму в два простых шага ниже:

Ваши контактные данные:

Шаг 1
Поздравляем! У вас есть промокод!

Тип желаемой лицензии:

Шаг 2
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности
close form
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Бесплатная лицензия PVS‑Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
check circle
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте, отфильтровано ли письмо в одну из следующих стандартных папок:

  • Промоакции
  • Оповещения
  • Спам

>
>
SAST или DAST

SAST или DAST

06 Апр 2023

SAST и DAST – это два разных подхода к задаче поиска в коде ошибок и уязвимостей. На самом деле, нет никакого противопоставления, и следует использовать обе методики. Давайте разберём слабые и сильные их стороны.

1042_SAST_vs_DAST_ru/image1.png

Это статья не о том, что одна методология лучше или хуже другой. Они вообще не противопоставлены друг другу, а дополняют друг друга. Нельзя сказать, что лучше использовать для строительства дома: экскаватор или подъёмный кран. Аналогично дело обстоит с SAST и DAST.

Что такое SAST и DAST

Static Application Security Testing (SAST) – это процесс тестирования приложения на наличие ошибок и уязвимостей в исходном коде с применением статического анализа.

Dynamic application security testing (DAST) – это процесс тестирования приложений, имитирующий вредоносные внешние атаки, пытающиеся использовать распространённые уязвимости.

Задача SAST и DAST защитить приложение от уязвимостей нулевого дня. Под уязвимостями нулевого дня понимаются ошибки, которые найдены злоумышленником и могут им эксплуатироваться. При этом у разработчиков было 0 дней для того, чтобы их устранить. Другими словами, задача SAST и DAST – обнаружить дефекты безопасности на этапе разработки приложения и не дать это сделать хакеру.

Более подробное описание методик обеспечения безопасности вы найдёте в статье "Виды Application Security Testing. Как не запутаться среди SAST, DAST и IAST".

В чём отличие SAST от DAST

Фундаментальная разница заключается в том, что SAST работает только с исходным кодом приложения. DAST подразумевает запуск скомпилированного исходного кода на различных наборах входных данных.

SAST и DAST обнаруживает два множества разновидностей ошибок, которые только частично пересекаются между собой. Рассмотрим, почему так происходит.

void foo(struct Object *p1, struct Object *p2)
{
  if (p1 == NULL || p1 == NULL)
    return;
  if (memcmp(p1, p2, sizeof(p1)) == 0)
    start();
}

Код этой функции на языке C содержит сразу две ошибки. Первая опечатка: два раза проверяется указатель p1 и не проверяется указатель p2. Вторая опечатка: оператор sizeof вычисляет размер указателя, а не объекта.

Эти ошибки легко выявить с помощью SAST. Например, анализатор PVS-Studio выдаёт соответствующие предупреждения:

  • V560: A part of conditional expression is always false: p1 == NULL.
  • V568: It's odd that 'sizeof()' operator evaluates the size of a pointer to a class, but not the size of the 'p1' class object.

Рассмотренные ошибки скрыты от DAST. Вернее, их обнаружение зависит от стечения обстоятельств. DAST работает со скомпилированным кодом. Этот двоичный код будет эквивалентен следующему исходному коду:

void foo(struct Object *p1, struct Object *p2)
{
  if (p1 == NULL)
    return;
  if (memcmp(p1, p2, 8) == 0)
    start();
}

Компилятор удалит повторную проверку указателя. Поэтому нет информации, чтобы заподозрить, что условие является некорректным. Ошибка будет замечена только в том случае, если указатель p2 окажется нулевым и будет передан в функцию memcmp. Впрочем, для этого специальный инструмент и не нужен. Мы и так заметим возникновение access violation.

Вместо выражения sizeof(p1) в двоичном коде будет использоваться значение 8 (предполагается, что мы компилируем 64-битную программу, где размер указателя равен 8 байтам). Возможность выявления ошибки зависит от размера объекта Object:

  • sizeof(Object) < 8. В данном случае DAST, возможно, выявит ошибку, так как произойдёт выход за границу объекта. Но если указатели ссылаются на элементы массива, то, возможно, инструмент всё равно промолчит.
  • sizeof(Object) == 8. Код некорректен, но благодаря везению работает так, как нужно. Для DAST эта ошибка невидима.
  • sizeof(Object) >= 8. Сравнивается часть объекта. Для DAST эта ошибка невидима.

Означает ли это, что SAST полезнее, чем DAST? Конечно же, нет. Рассмотрим обратную ситуацию.

size_t foo(size_t n)
{
  if (n < 3)
    return 0;
  size_t *arr = (size_t *)malloc(sizeof(size_t) * n);
  if (arr == NULL)
    return 0;

  for (size_t i = 0; i < n; i++)
    arr[i] = i;
  size_t indexOutOfBounds = arr[n - 1] + arr[n - 2];
  size_t x = arr[indexOutOfBounds]; // Bug
  free(arr);
  return x;
}

Ошибка в этом коде легко может быть выявлена при динамическом анализе. Предположим, что в функцию передали значение 10. Тогда значение переменной indexOutOfBounds будет равно 8+9=17. Возникает выход за границу массива, содержащий всего 10 элементов. Эта ситуация легко отлавливается динамическими анализаторами, но это почти недостижимо для статических анализаторов.

Для того, чтобы статическому анализатору найти ошибку, ему придётся виртуально выполнить эту программу, создавать массивы, хранить в них значения и так далее. Теоретически это возможно, но на практике такой анализатор будет работать крайне медленно и крайне долго. Более подробно ограничения статических анализаторов описаны в статье "Что нельзя найти с помощью статического анализа".

Примечание. Возможно, какой-то статический анализатор сможет найти именно эту ошибку. Но это только благодаря тому, что на самом деле код прост, и вся логика собрана в одной функции. Чуть усложни ситуацию и статический анализатор спасует.

Как видите, SAST и DAST по-разному справляются с поиском различных видов ошибок. Рационально их использовать совместно, чтобы выявить максимальное количество ошибок и дефектов безопасности (security weaknesses).

Обнаружение уязвимостей с помощью SAST и DAST

SAST помогает выявлять компоненты с известными уязвимостями и потенциальные уязвимости в коде приложения. Если уязвимость известна и описана в одной из баз уязвимостей, то статический анализ может импортировать информацию из этой базы и использовать для проверки используемых в проекте компонентов. Это называется SCA (software composition analysis).

Также SAST выявляет потенциальные уязвимости. Анализатор не может сказать, является та или иная ошибка в коде настоящей (эксплуатируемой) уязвимостью. Однако если ошибка классифицируется согласно Common Weakness Enumeration (CWE), то значит такая вероятность существует. Т.е. перед нами потенциальная уязвимость, которою следует исправить.

Важной составляющей обнаружений уязвимостей является технология taint-анализа (taint checking). Она позволяет отслеживать распространение непроверенных внешних данных по программе. Попадание таких данных в некоторые ключевые точки может приводить к возникновению различных уязвимостей, среди которых SQL injection, cross-site scripting (XSS), path traversal и другие.

DAST так же помогает выявлять уязвимости, используя технологию фаззинга.

Фаззинг – техника тестирования программ, заключающаяся в передаче на вход приложению неправильных/непредусмотренных/случайных данных и отслеживании поведения системы. Если в ходе проведения фаззинга система упала/зависла/неправильно себя повела – это является свидетельством ошибки.

В отличии от статического анализа, фаззинг выявляет в коде дефекты, которые точно проявляют себя в ходе работы приложения. Иначе говоря, такой подход лишён ложных срабатываний и в этом его большое преимущество перед SAST.

Сравнение SAST и DAST

Давайте подытожим описанное. Надо понимать, что это не таблица типа "лучше/хуже". Она демонстрирует различия подходов. И именно потому, что подходы так различны, следует использовать их совместно для создания качественных и безопасных приложений.

SAST

DAST

Используется тестирование по принципу белого ящика (анализаторы работают с исходным кодом приложений).

Используется тестирование по принципу чёрного ящика (на самом деле это не всегда так, поскольку некоторые анализаторы внедряют в код дополнительные проверки и по факту тоже работают с исходным кодом приложений).

Имеются ложные срабатывания (нужно тратить время, чтобы понять, следует править код или следует подавить предупреждение).

Нет ложных срабатываний.

Необходим исходный код приложений, а поиск дефектов осуществляется с помощью методологии статического анализа кода.

Исходный код не требуется, но необходим запуск скомпилированных приложений.

Ошибки и уязвимости могут быть выявлены на самом раннем этапе (ещё в процессе написания кода).

Ошибки могут быть выявлены как в процессе разработки приложения, так и после.

Низкая стоимость исправления ошибок и уязвимостей (дефекты обнаруживаются практически сразу после их появления в коде, а значит их просто исправить).

Стоимость исправления ошибок и уязвимостей чуть выше, чем у SAST (найденные дефекты возвращаются к разработчику спустя некоторое время, когда он может работать уже над другой функциональностью).

Полный анализ кода (можно проверить даже те участки кода, которые редко получают управление).

Сложно добиться высокого покрытия кода (сложно и ресурсозатратно подготовить наборы входных данных, чтобы выполнить как можно больше веток кода).

Примеры инструментов: PVS-Studio, Coverity, Klocwork, SonarQube.

Примеры инструментов: AddressSanitizer, BoundsChecker, Valgrind.

Дополнительные ссылки

Популярные статьи по теме


Комментарии (0)

Следующие комментарии next comments
close comment form