Лекция №11. Безопасность модулей программного обеспечения. Анализ уязвимостей в зависимостях программного кода (SAST/DAST).
§11.1. Почему тестировщик должен думать о безопасности
За этот семестр мы научились тестировать многое:
| Лекция | Что тестировали |
|---|---|
| Лекция 6 | Модули и интеграцию с БД |
| Лекция 7 | Интерфейсы и E2E-сценарии |
| Лекция 8 | Производительность и нагрузку |
| Лекция 9 | CI/CD и автоматизацию |
| Лекция 10 | Совместимость микросервисов |
Осталось последнее: безопасность. Если система работает, но небезопасна — она не работает. Потому что:
- Данные пользователей могут быть украдены.
- Система может быть взломана.
- Бизнес может потерять репутацию и деньги.
Многие думают, что безопасность — это задача разработчиков. Но это не так. Кто отвечает за безопасность в проекте:
| Кто | Что делает |
|---|---|
| Разработчик | Пишет код и старается избегать уязвимостей |
| Архитектор | Проектирует систему с учетом безопасности |
| DevOps | Настраивает серверы и сеть |
| Тестировщик | Проверяет, что система безопасна |
Задача тестировщика
— убедиться, что уязвимости системы выявлены (а затем переданы разработчикам для исправления). Тестировщик анализирует систему с позиции внешнего наблюдателя, действуя подобно потенциальному злоумышленнику.
Тестировщик — последний рубеж перед продакшеном. Вот как выглядит путь кода от разработчика до пользователя:
wireframe
Разработчик пишет код → Code Review → CI/CD → Тестировщик → Продакшен
↑
ПОСЛЕДНИЙ РУБЕЖ!
Что это значит:
| Если тестировщик нашел уязвимость | Если тестировщик пропустил уязвимость |
|---|---|
| Уязвимость исправлена до релиза | Уязвимость попадает в продакшен |
| Пользователи в безопасности | Хакеры могут использовать уязвимость |
| Репутация компании сохранена | Скандалы, утечки данных, штрафы |
OWASP (Open Web Application Security Project)
— это международная организация, которая занимается безопасностью веб-приложений. Каждые несколько лет они публикуют список Top 10 — 10 самых опасных уязвимостей.
Зачем это знать тестировщику? Чтобы знать, на что обращать внимание.
Краткий обзор OWASP Top 10 (упрощенно):
| № | Уязвимость | Что это | Пример |
|---|---|---|---|
| 1 | Инъекции (SQL, NoSQL, OS) | Злоумышленник внедряет вредоносный код в запрос | ' OR '1'='1 в поле ввода — и он зашел без пароля |
| 2 | Потеря аутентификации | Пароли и токены украдены или слабые | Пароль 123456 — легко взломать |
| 3 | XSS (межсайтовый скриптинг) | Злоумышленник внедряет JavaScript на страницу | Пользователь кликает на ссылку — его данные украдены |
| 4 | Небезопасные зависимости | Используются устаревшие библиотеки с уязвимостями | Log4j, jQuery с известными CVE |
| 5 | Неправильная настройка безопасности | Сервер настроен небезопасно | Открытые порты, слабые пароли по умолчанию |
| 6 | Уязвимости в API | API не проверяет права доступа | Можно получить данные другого пользователя |
| 7 | Недостаточное логирование | Нет логов для расследования инцидентов | Непонятно, кто и когда взломал систему |
Запомните
Важно понимать, что не нужно запоминать все 10 уязвимостей. Мы не будем их все подробно разбирать в курсе. Достаточно понимать, что они существуют и что тестировщик должен знать о них хотя бы на базовом уровне.
Что нужно запомнить:
1. Опасность SQL-инъекций — злоумышленник может прочитать, изменить или удалить данные.
2. Опасность XSS — злоумышленник может украсть данные пользователей.
3. Опасность устаревших библиотек — в них уже известны уязвимости, и их легко использовать.
4. Опасность неправильных настроек — система может быть взломана из-за слабого пароля или открытого порта.
Существует два основных подхода к тестированию безопасности. Мы будем подробно разбирать их в следующих параграфах, но пока кратко:
| Подход | Что это | Когда проверяет | Что ищет |
|---|---|---|---|
| **Static (SAST) ** | Проверка кода без запуска | На этапе написания кода | SQL-инъекции, XSS, устаревшие библиотеки |
| Dynamic (DAST) | Проверка работающего приложения | На этапе тестирования (staging) | Неправильную авторизацию, открытые порты, уязвимости API |
Простая аналогия:
- SAST — это как проверка чертежа здания. Вы смотрите на план и ищете ошибки до того, как начали строить.
- DAST — это как проверка уже построенного здания. Вы ходите по коридорам, проверяете замки, смотрите, не открыты ли окна.
§11.2. SAST: Static Application Security Testing
Давайте разберем что такое SAST. SAST расшифровывается как Static Application Security Testing.
SAST
— статическое тестирование безопасности приложений.
Важно знать
Это значит, что SAST проверяет код без его запуска. Он анализирует исходный код, ищет потенциальные уязвимости и сообщает о них разработчику.
Пример:
csharp
// Вот такой код может содержать уязвимость
public IActionResult GetUser(string userId)
{
// SAST найдет проблему: SQL-инъекция!
var query = $"SELECT * FROM Users WHERE Id = '{userId}'";
// ↑
// userid приходит от пользователя
// злоумышленник может передать: ' OR '1'='1
var user = db.Execute(query);
return Ok(user);
}
SAST ищет не все уязвимости, а только те, которые можно найти в коде. Вот основные категории:
| Что ищет SAST | Пример | Почему это опасно |
|---|---|---|
| SQL-инъекции | "SELECT * FROM Users WHERE Id = '" + userId + "'" | Злоумышленник может украсть или удалить данные |
| XSS (межсайтовый скриптинг) | Response.Write(userInput) | Злоумышленник может внедрить JavaScript на страницу |
| Устаревшие библиотеки | Использование log4j старой версии с известной уязвимостью | Есть известные CVE, которые легко использовать |
| Ошибки конфигурации | Строка подключения с паролем в коде | Пароль виден всем, у кого есть доступ к коду |
| Небезопасные методы | Использование MD5 для хеширования паролей | MD5 можно взломать, нужно использовать bcrypt |
| Отсутствие валидации | Не проверяется ввод пользователя | Злоумышленник может отправить любые данные |
SAST запускается на ранних этапах разработки, как можно раньше.
| Где запускается | Когда | Зачем |
|---|---|---|
| В IDE (Visual Studio) | Пока разработчик пишет код | Мгновенная обратная связь |
| В CI/CD | При каждом git push | Автоматическая проверка |
| В Code Review | Перед вливанием в main | Проверка перед мержем |
В IDE это выглядит следующим образом. Разработчик пишет код:
csharp
// Разработчик пишет такой код
string query = $"SELECT * FROM Users WHERE Id = '{userId}'";
SAST (в IDE) подсвечивает строку красным и пишет:
wireframe
⚠️ Уязвимость: Возможна SQL-инъекция.
Используйте параметризованные запросы вместо конкатенации строк.
Разработчик исправляет:
csharp
// Исправленный код
var query = "SELECT * FROM Users WHERE Id = @UserId";
// Используем параметры, а не конкатенацию
В §9.7 лекции №9 мы говорили о линтерах (StyleCop, ESLint). На первый взгляд SAST и линтер делают похожее — проверяют код без запуска. Но разница есть.
| Характеристика | Линтер | SAST |
|---|---|---|
| Что ищет | Стиль и качество кода (отступы, названия) | Уязвимости безопасности (SQL-инъекции, XSS) |
| Тип ошибок | Косметические и стилистические | Критические (могут привести к взлому) |
| Последствия | Код некрасивый, но работает | Код может быть взломан |
| Когда использовать | Всегда | Всегда |
Простая аналогия:
- Линтер — это как учитель русского языка, который проверяет, правильно ли вы поставили запятые.
- SAST — это как редактор, который проверяет, не написали ли вы в тексте номер банковской карты.
И то, и другое важно, но SAST важнее, потому что он находит реальные угрозы.
Для .NET-проектов есть несколько популярных инструментов SAST:
1. Security Code Scan
Это бесплатный анализатор для .NET. Он встроен в Visual Studio и проверяет код на уязвимости прямо во время написания.
bash
# Установка через NuGet
dotnet add package SecurityCodeScan
Что проверяет:
- SQL-инъекции.
- XSS-уязвимости.
- Использование небезопасных методов.
- Слабые алгоритмы хеширования.
2. SonarQube
SonarQube
— это мощная платформа для анализа кода. Она проверяет не только уязвимости, но и качество кода, покрытие тестами, дублирование.
yaml
# В CI/CD (GitHub Actions)
- name: Run SonarQube analysis
run: |
dotnet tool install --global dotnet-sonarscanner
dotnet sonarscanner begin /k:"project-key" /d:sonar.host.url="http://sonarqube:9000"
dotnet build
dotnet sonarscanner end
Что проверяет:
- Все, что проверяет Security Code Scan.
- Плюс качество кода, сложность, тестовое покрытие.
- Плюс интеграцию с CI/CD.
3. OWASP Dependency Check (мы рассмотрим в §11.5)
Этот инструмент проверяет сторонние библиотеки на наличие известных уязвимостей.
Когда SAST находит уязвимость, разработчик видит что-то подобное. Разберем то, что они видят в IDE (Visual Studio):
wireframe
⚠️ Security Code Scan: SCS0001
SQL injection vulnerability detected.
The query is constructed using string concatenation with user input.
Recommendation: Use parameterized queries.
Location: UserController.cs, line 42
В CI/CD (отчет):
wireframe
=================================================================
Security Code Scan Report
=================================================================
1 critical issues found:
[CRITICAL] SQL injection vulnerability
File: UserController.cs
Line: 42
Description: Query uses string concatenation with user input.
Recommendation: Use parameterized queries.
=================================================================
Что делает разработчик:
1. Читает сообщение.
2. Понимает, где проблема и почему она опасна.
3. Исправляет код (использует параметризованный запрос).
4. Отправляет исправление снова.
§11.3. DAST: Dynamic Application Security Testing
DAST расшифровывается как Dynamic Application Security Testing.
DAST
— динамическое тестирование безопасности приложений.
Это значит, что DAST проверяет работающее приложение через внешние запросы. Он не смотрит на код, он ведет себя как злоумышленник — отправляет запросы, анализирует ответы и ищет уязвимости.
Чем DAST отличается от SAST:
| Характеристика | SAST | DAST |
|---|---|---|
| Что проверяет | Код (без запуска) | Работающее приложение |
| Когда | На этапе написания кода | На этапе тестирования (staging) |
| Знает код | Да (анализирует исходники) | Нет (как хакер) |
| Что находит | SQL-инъекции в коде, XSS, устаревшие библиотеки | Открытые порты, ошибки авторизации, неправильные заголовки |
| Требует запущенное приложение | Нет | Да |
| Скорость | Быстро (секунды) | Медленнее (минуты) |
Простая аналогия:
- SAST — это как проверка чертежа самолета. Вы смотрите, правильно ли спроектированы крылья.
- DAST — это как испытательный полет. Вы запускаете самолет, проверяете, открывается ли шасси, работает ли автопилот.
И SAST, и DAST нужны. Они находят разные типы проблем.
Что же может найти DAST? DAST находит уязвимости, которые видны снаружи, без доступа к коду.
| Что ищет DAST | Пример | Почему это опасно |
|---|---|---|
| Неправильная авторизация | Можно зайти в админку без логина | Любой может управлять системой |
| Открытые порты | Порт 8080 открыт, на нем висит база данных | Хакер может подключиться к БД |
| Слабые пароли | Пароль admin на тестовом сервере | Легко взломать |
| Неправильные заголовки | Нет X-Frame-Options, Content-Security-Policy | Уязвимость к XSS |
| Незащищенные эндпоинты | GET /api/users возвращает всех пользователей | Утечка данных |
| Инъекции | SQL-инъекции, XSS в работающем приложении | Кража данных |
DAST запускается на работающем приложении, когда оно уже развернуто в тестовой среде (staging).
| Где запускается | Когда | Зачем |
|---|---|---|
| Staging-среда | Перед релизом в продакшен | Проверить, что приложение безопасно |
| Продакшен | Регулярно (еженедельно, ежемесячно) | Проверить, не появились ли новые уязвимости |
| Периодически | По расписанию (ночью) | Не влияет на разработчиков |
Это примерно выглядит следующим образом:
wireframe
Разработка → Test → Staging → DAST → Результат → Продакшен
↑
DAST проверяет здесь
Для .NET-проектов (и не только) есть несколько популярных инструментов DAST. Самый известный и доступный — OWASP ZAP.
1. OWASP ZAP (Zed Attack Proxy)
Это бесплатный инструмент от OWASP для тестирования безопасности веб-приложений. Как работает:
1. Вы запускаете OWASP ZAP.
2. Указываете URL вашего приложения (например, https://staging.myapp.com).
3. ZAP начинает сканировать: отправляет запросы, анализирует ответы, ищет уязвимости.
4. Вы получаете отчет о найденных проблемах.
Что умеет ZAP:
| Возможность | Что делает |
|---|---|
| Автоматическое сканирование | Проверяет все эндпоинты на уязвимости |
| Spider | Ищет все страницы и эндпоинты приложения |
| Active Scan | Активно атакует приложение (SQL-инъекции, XSS) |
| Passive Scan | Анализирует ответы без атак |
| Прокси | Можно подхватывать и изменять запросы вручную |
Отчет в OWASP ZAP выглядит следующим образом:

2. Коммерческие решения (для больших проектов)
| Инструмент | Что делает | Когда нужен |
|---|---|---|
| Burp Suite | Профессиональный инструмент для тестирования безопасности | Для профессионального пентеста |
| Qualys | Облачное сканирование уязвимостей | Для корпоративных проектов |
Как выглядит работа с OWASP ZAP? Она выглядит в виде нескольких шагов.
Шаг №1. Запустить ZAP
bash
# Запуск ZAP (из командной строки)
./zap.sh -cmd -quickurl https://staging.myapp.com -quickout report.html
Шаг №2. ZAP сканирует приложение
ZAP отправляет множество запросов к вашему приложению:
wireframe
→ GET /api/users
← 200 OK
→ POST /api/login
← 200 OK
→ GET /api/admin
← 403 Forbidden (хорошо, авторизация работает)
→ POST /api/users?sql=...
← 500 Internal Server Error (возможна инъекция!)
Шаг №3. Получить отчет
wireframe
=================================================================
OWASP ZAP Security Report
=================================================================
High risk issues: 2
1. SQL Injection vulnerability found in /api/users
2. Cross-Site Scripting found in /api/search
Medium risk issues: 3
1. Missing security headers (X-Frame-Options)
2. Sensitive data in response body
3. Insecure cookie settings
Low risk issues: 1
1. Directory listing enabled
=================================================================
DAST можно (и нужно) встраивать в CI/CD-конвейер. Как это выглядит в GitHub Actions:
yaml
name: Security Scan
on:
push:
branches: [ main ]
jobs:
dast-scan:
runs-on: ubuntu-latest
steps:
- name: Deploy application to staging
run: |
# Развертываем приложение на тестовую среду
- name: Run OWASP ZAP scan
uses: zaproxy/action-baseline@v0.11.0
with:
target: 'https://staging.myapp.com'
- name: Upload results
uses: actions/upload-artifact@v4
with:
name: dast-report
path: report.html
Что получает команда при интеграции DAST в CI / CD:
| Результат | Действие |
|---|---|
| ✅ 0 уязвимостей | Релиз разрешен |
| ⚠️ 1 – 2 низкорисковые | Требуется подтверждение |
| ❌ Высокорисковые | Релиз блокируется |
§11.4. SAST vs DAST: что и когда использовать
Мы познакомились с двумя подходами к тестированию безопасности:
| Подход | Что проверяет | Когда |
|---|---|---|
| SAST | Код (без запуска) | На этапе разработки |
| DAST | Работающее приложение | На этапе тестирования |
Важно понять, что это не конкуренты
Они дополняют друг друга. SAST и DAST находят разные типы уязвимостей, и только вместе они дают полную картину безопасности.
Простая аналогия: вы покупаете дом.
- SAST — это проверка чертежей до начала строительства. Вы смотрите, правильно ли спроектированы стены, крыша, коммуникации.
- DAST — это проверка готового дома. Вы ходите по комнатам, проверяете, открываются ли двери, не дует ли из окон, работает ли электричество.
И то, и другое важно. Если чертежи плохие — дом не будет стоять. Если чертежи хорошие, но строители сделали ошибки — дом тоже не будет стоять.
Давайте сравним эти два подхода в виде таблицы:
| Характеристика | SAST | DAST |
|---|---|---|
| Что проверяет | Код (исходники) | Работающее приложение |
| Нужен ли запущенный код | Нет | Да |
| Знает ли код | Да (анализирует исходники) | Нет (как хакер) |
| Когда запускается | На этапе разработки (IDE, CI/CD) | На этапе тестирования (staging) |
| Скорость | Быстро (секунды) | Медленнее (минуты) |
| Что находит | SQL-инъекции в коде, XSS, устаревшие библиотеки | Открытые порты, ошибки авторизации, неправильные заголовки |
| Требует доступа к коду | Да | Нет |
| Может найти | Проблемы в коде | Проблемы в инфраструктуре |
| Итог | Проверяет, правильно ли написано | Проверяет, правильно ли работает |
Теперь давайте определим, когда какой инструмент использовать. SAST используем:
| Когда | Почему |
|---|---|
| На этапе написания кода (IDE) | Мгновенная обратная связь |
| При каждом git push (CI/CD) | Автоматическая проверка |
| Перед Code Review | Найти проблемы до того, как код увидят другие |
| Для проверки зависимостей | Найти устаревшие библиотеки |
DAST используем:
| Когда | Почему |
|---|---|
| После развертывания в staging | Проверить работающее приложение |
| Перед релизом в продакшен | Финальная проверка |
| Регулярно в продакшене | Проверить, не появились ли новые уязвимости |
| При изменении инфраструктуры | Проверить, не открылись ли новые порты |
Использование комбинации SAST + DAST является полным покрытием безопасности. Использовать только SAST — небезопасно, так как:
wireframe
SAST нашел проблемы в коде → Разработчик исправил → Релиз
↓
❌ DAST не запускали!
❌ Не проверены настройки,
❌ Не проверена авторизация,
❌ Не проверены заголовки
использовать только DAST — небезопасно:
wireframe
DAST нашел проблемы в работе → Администратор исправил → Релиз
↓
❌ SAST не запускали!
❌ Не проверены библиотеки,
❌ Не проверены SQL-инъекции в коде
использовать SAST + DAST — безопасно:

Что дает комбинация:
| SAST находит | DAST находит | Вместе находят |
|---|---|---|
| SQL-инъекции в коде | SQL-инъекции в работе | Всё |
| XSS в коде | XSS в работе | Всё |
| Устаревшие библиотеки | Неправильные заголовки | Всё |
| Ошибки конфигурации в коде | Открытые порты | Всё |
Давайте разберем практический пример. Возьмем, например, сценарий, когда команда разрабатывает интернет – магазин. Без проверки безопасности:
wireframe
Разработка → Тесты → Продакшен
↓
❌ Уязвимости найдены хакерами
❌ Данные пользователей украдены
❌ Репутация компании разрушена
С SAST (половина решения):
wireframe
Разработка → SAST → Тесты → Продакшен
↓
✅ Уязвимости в коде найдены
❌ Но уязвимости в настройках остались
С SAST + DAST (полное решение):
wireframe
Разработка → SAST → Тесты → DAST (Staging) → Продакшен
↓ ↓
✅ Уязвимости в ✅ Релиз безопасен
коде и настройках
найдены и исправлены
Давайте приведем простую аналогию, например, проверка чертежа и проверка готового здания. Проверка чертежа (SAST). Вы — архитектор. Вы смотрите на чертеж дома. Вы проверяете:
- Правильно ли расположены стены?
- Правильно ли рассчитана нагрузка?
- Есть ли запас прочности?
Проверка готового здания (DAST). Вы — инспектор по строительству. Вы ходите по построенному дому. Вы проверяете:
- Стоят ли стены ровно?
- Не протекает ли крыша?
- Закрываются ли двери?
- Есть ли запасной выход?
§11.5. Анализ уязвимостей в зависимостях (SCA)
SCA расшифровывается как Software Composition Analysis.
Software Composition Analysis
— анализ состава программного обеспечения.
Это значит, что SCA проверяет все сторонние библиотеки (NuGet-пакеты, npm-пакеты), которые использует ваш проект, и ищет среди них известные уязвимости.
Вот, например, вы покупаете готовый торт в магазине. Вы не знаете, из каких ингредиентов он сделан. SCA — это как проверка всех ингредиентов: «Этот шоколад просрочен? Эта мука безопасна?».
Современные проекты редко пишут всё с нуля. Мы используем готовые библиотеки. Обычно, 90% кода – чужие библиотеки.
| Тип библиотеки | Пример | Зачем |
|---|---|---|
| Фреймворки | ASP.NET Core, React | Основа приложения |
| Утилиты | Newtonsoft.Json, Lodash | Сериализация, обработка данных |
| Работа с БД | Entity Framework, Sequelize | Работа с базой данных |
| Тестирование | xUnit, Jest, Playwright | Написание тестов |
Сколько кода в проекте — ваш, а сколько — чужие библиотеки?

Это значит, что, если в одной из этих библиотек есть уязвимость — она есть во всем проекте. Вы можете написать идеальный код, но, если библиотека, которую вы используете, уязвима — ваша система тоже уязвима.
Например, вы строите дом. Вы сами построили стены и крышу (ваш код). Но вы купили готовые окна (библиотека). Если окна плохие — дом будет холодным, даже если стены идеальные.
Чем же опасны устаревшие библиотеки? CVE (Common Vulnerabilities and Exposures) — это база данных известных уязвимостей. Каждая уязвимость получает свой номер (например, CVE-2021-44228). Пример: уязвимость в Log4j (CVE-2021-44228).
В 2021 году в популярной Java-библиотеке Log4j нашли критическую уязвимость. Это позволило хакерам выполнять произвольный код на серверах, где использовалась эта библиотека.
| Что произошло | Последствия |
|---|---|
| Log4j использовали тысячи приложений | Огромное количество систем было уязвимо |
| Хакеры нашли уязвимость | Начались массовые атаки |
| Нужно было срочно обновлять библиотеку | Команды работали сутками, чтобы исправить |
А чем же опасны устаревшие библиотеки:
| Опасность | Что это значит |
|---|---|
| Известные уязвимости | Если CVE известно, хакеры могут использовать его |
| Легкая эксплуатация | Часто есть готовые скрипты для атаки |
| Сложно обнаружить | Уязвимость не в вашем коде, а в библиотеке |
| Быстрое распространение | Одна уязвимость может затронуть тысячи проектов |
Для .NET-проектов есть несколько инструментов для анализа зависимостей.
1. dotnet list package --vulnerable (встроенный)
Это встроенная команда в .NET SDK, которая проверяет пакеты на известные уязвимости.
bash
# Проверить уязвимости в проекте
dotnet list package --vulnerable
# Вывод
The following packages were found with known vulnerabilities:
┌────────────────────────────────────────────────────────────┐
│ Package │ Severity │ Advisory URL │
├───────────────────────────┼───────────┼────────────────────┤
│ Newtonsoft.Json 12.0.1 │ High │ https://... │
│ Microsoft.Data.SqlClient │ Moderate │ https://... │
└────────────────────────────────────────────────────────────┘
Она показывает название пакета, текущую версию, уровень серьезности и ссылку на описание уязвимости.
2. OWASP Dependency Check
Бесплатный инструмент от OWASP для проверки зависимостей.
bash
# Запуск проверки
dependency-check --scan ./src --format HTML --out ./reports
Она проверяет все зависимости (NuGet, npm, Maven) на наличие известных CVE.
3. Snyk
Популярный инструмент для проверки безопасности зависимостей.
bash
# Установка Snyk
npm install -g snyk
# Проверка .NET-проекта
snyk test --dotnet
Что дает Snyk:
- Проверка на уязвимости.
- Рекомендации по исправлению (какую версию установить).
- Интеграция с CI/CD.
SCA нужно встраивать в CI/CD так же, как и другие проверки безопасности.
Как это выглядит в GitHub Actions:
yaml
name: SCA Scan
on:
push:
branches: [ main, develop ]
jobs:
dependency-check:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0'
- name: Run SCA scan (dotnet)
run: |
dotnet list package --vulnerable
- name: Upload results
uses: actions/upload-artifact@v4
with:
name: sca-report
path: sca-report.txt
Как это выглядит в GitLab CI:
yaml
dependency-scan:
stage: test
image: mcr.microsoft.com/dotnet/sdk:8.0
script:
- dotnet list package --vulnerable
artifacts:
paths:
- sca-report.txt
Что делать, если найдена уязвимость? Следовать следующим шагам:
| Шаг | Что делать | Почему |
|---|---|---|
| 1. Посмотреть CVE | Открыть ссылку с описанием уязвимости | Понять, насколько это опасно |
| 2. Проверить версию | Узнать, какая версия библиотеки используется | Понять, подвержена ли она |
| 3. Обновить библиотеку | Перейти на версию, в которой исправлена уязвимость | Устранить проблему |
| 4. Протестировать | Запустить тесты, чтобы убедиться, что ничего не сломалось | Убедиться, что обновление безопасно |
| 5. Отправить код | Запушить изменения, CI/CD проверит снова | Получить зеленый отчет |
Если обновление невозможно:
| Вариант | Что делать |
|---|---|
| Поискать альтернативу | Использовать другую библиотеку |
| Написать обертку | Изолировать использование библиотеки |
| Принять риск | Но задокументировать его |
§11.6. Интеграция безопасности в CI/CD (DevSecOps)
Мы уже изучили три инструмента безопасности. Теперь посмотрим, как они встраиваются в конвейер. Схема конвейера с безопасностью:

Этапы конвейера с проверкой безопасности проходят в несколько этапов.
Этап №1. SAST при каждом push (быстро)
Запускается сразу после того, как разработчик отправляет код.
yaml
# GitHub Actions (упрощенно)
- name: Run SAST scan
run: dotnet run --project SecurityCodeScan
Он проверяет SQL-инъекции, XSS, устаревшие методы, ошибки конфигурации. Время выполнения примерно 10 – 30 секунд.
В случае возникновения ошибки, конвейер падает. Разработчик исправляет уязвимость в коде.
Этап №2. SCA при каждом push (быстро)
Запускается параллельно с SAST или сразу после него.
yaml
- name: Run SCA scan
run: dotnet list package --vulnerable
Он проверяет устаревшие библиотеки с известными уязвимостями (CVE). Время выполнения примерно 10 – 30 секунд.
В случае возникновения ошибки, конвейер падает. Разработчик обновляет уязвимую библиотеку.
Этап №3. DAST на развернутом приложении (в staging)
Запускается только после того, как приложение развернуто в staging-среде.
yaml
- name: Run DAST scan
run: |
# Развернуть приложение в staging
# Запустить OWASP ZAP против staging-приложения
Он проверяет открытые порты, ошибки авторизации, неправильные заголовки, инъекции в работающем приложении. Время выполнения примерно 2 – 5 минут (медленнее, чем SAST).
В случае возникновения ошибки, конвейер падает. Команда исправляет настройки или код.
Что делать, если уязвимость найдена: падать или только предупреждать? Это главный вопрос при настройке безопасности в CI/CD.
| Подход | Что происходит | Когда применять |
|---|---|---|
| Конвейер падает | Релиз блокируется | Для критических уязвимостей (SQL-инъекции, утечка данных) |
| Только предупреждение | Релиз продолжается | Для низкорисковых проблем (стиль, рекомендации) |
В случае, если конвейер падает:
yaml
- name: Run SAST scan
run: dotnet run --project SecurityCodeScan
# Если SAST нашел критическую уязвимость — конвейер падает
Когда использовать:
- SQL-инъекции.
- XSS.
- Критические CVE в библиотеках.
- Открытые порты в staging.
Почему:
- Эти уязвимости легко использовать для атаки.
- Они могут привести к утечке данных.
- Их нужно исправлять до релиза.
Только предупреждение:
yaml
- name: Run SAST scan
run: dotnet run --project SecurityCodeScan
continue-on-error: true
# Даже если SAST нашел проблемы — конвейер продолжается
Когда использовать:
- Низкорисковые уязвимости (некритические).
- Рекомендации по улучшению (не ошибки).
- Устаревшая, но безопасная библиотека.
Почему:
- Проблема не критична для релиза.
- Ее можно исправить в следующих версиях.
Это сложно понять на первый взгляд, но если знать правило «80 / 20», то все становится просто.
Рассмотрим это правило:
| Уровень серьезности | Действие | Пример |
|---|---|---|
| Критическая (Critical) | Конвейер падает ❌ | SQL-инъекция, утечка паролей |
| Высокая (High) | Конвейер падает ❌ | XSS, известная уязвимость в библиотеке |
| Средняя (Medium) | Предупреждение ⚠️ | Рекомендация по улучшению |
| Низкая (Low) | Предупреждение ⚠️ | Стилистическая проблема |
Конвейер для разработчиков выглядит в виде нескольких сценариев.
Сценарий №1. Всё хорошо
wireframe
✅ SAST (10s) → ✅ Все хорошо
✅ SCA (10s) → ✅ Все хорошо
✅ Build (30s) → ✅ Собрано
✅ Tests (60s) → ✅ Все тесты прошли
✅ Deploy (60s) → ✅ Развернуто
✅ DAST (120s) → ✅ Все хорошо
✅ Конвейер зеленый → Релиз разрешен!
Сценарий №2. SAST нашел уязвимость
wireframe
❌ SAST (10s) → ❌ Найдена SQL-инъекция!
→ Конвейер остановлен!
→ Разработчик: исправляю уязвимость.
→ Отправляю исправление.
→ Конвейер снова зеленый.
Сценарий №3. DAST нашел уязвимость
wireframe
✅ SAST (10s) → ✅ Все хорошо
✅ SCA (10s) → ✅ Все хорошо
✅ Build (30s) → ✅ Собрано
✅ Tests (60s) → ✅ Все тесты прошли
✅ Deploy (60s) → ✅ Развернуто
❌ DAST (120s) → ❌ Найдены открытые порты!
→ Конвейер остановлен!
→ DevOps: закрываю порты.
→ Отправляю исправление.
→ Конвейер снова зеленый.
§11.7. Антипаттерны в тестировании безопасности
В этой лекции мы изучили инструменты безопасности: SAST, DAST, SCA. Но инструменты — это только половина дела. Вторая половина — правильное использование.
Есть несколько типичных ошибок, которые сводят на нет все усилия по обеспечению безопасности. Они превращают безопасность из реальной защиты в иллюзию.
Главная мысль этого параграфа заключается в том, что безопасность —это постоянный процесс. И каждый член команды за него отвечает.
Антипаттерн №1. «Безопасность — это не моя работа»
Почему это опасно:
| Кто так думает | К чему это приводит |
|---|---|
| Разработчик | Пишет код с уязвимостями (SQL-инъекции, XSS) |
| Тестировщик | Не проверяет безопасность, пропускает уязвимости |
| DevOps | Настраивает сервер с открытыми портами |
| Все вместе | Система уязвима, данные пользователей под угрозой |
Как должно быть правильно:
| Кто | Что делает |
|---|---|
| Разработчик | Пишет безопасный код (использует параметризованные запросы, валидацию) |
| Тестировщик | Проверяет, что код безопасен (запускает SAST, проверяет авторизацию) |
| DevOps | Настраивает сервер безопасно (закрытые порты, HTTPS) |
| Все вместе | Безопасность — общая ответственность |
Для примера давайте посмотрим на аналогию. Безопасность в офисе — это не задача только охраны. Это задача всех. Каждый сотрудник закрывает дверь, не оставляет документы на столе, не сообщает пароли посторонним. Если кто-то думает «это не моя работа» — офис становится уязвимым.
Антипаттерн №2. «Мы проверили SAST, DAST не нужен»
Почему это опасно? SAST проверяет код, но не проверяет:
| Что проверяет SAST | Что НЕ проверяет SAST |
|---|---|
| SQL-инъекции в коде | SQL-инъекции в работающем приложении |
| XSS в коде | XSS в работающем приложении |
| Устаревшие библиотеки | Открытые порты |
| Ошибки конфигурации в коде | Неправильные заголовки в ответах |
Пример:
wireframe
SAST: ✅ Все хорошо. Код безопасен.
DAST: ❌ Найдена проблема: порт 8080 открыт, база данных доступна извне.
❌ Найдена проблема: отсутствуют заголовки безопасности.
Код безопасен, но система уязвима. Без DAST вы этого не узнаете.
Вот, например, вы проверили двигатель машины (SAST). Он работает идеально. Но вы не проверили, открыты ли двери, работает ли сигнализация, есть ли запасное колесо (DAST). Машина поедет, но она небезопасна.
Антипаттерн №3. «Запустили один раз и забыли»
Почему это опасно:
| Что происходит со временем | Последствия |
|---|---|
| Появляются новые CVE в библиотеках | Вы используете устаревшие, уязвимые версии |
| Изменяются стандарты безопасности | Вы не соответствуете современным требованиям |
| Появляются новые типы атак | Вы не защищены от новых угроз |
| Разработчики меняют код | Новый код может содержать уязвимости |
Пример:
wireframe
Месяц 1: Настроили SAST ✅
Месяц 3: Появилась уязвимость в Newtonsoft.Json (CVE)
SAST не обновлен → уязвимость не найдена
Месяц 6: Хакеры используют эту уязвимость ❌
Как должно быть правильно:
| Что делать | Как часто |
|---|---|
| Обновлять правила SAST | Ежемесячно |
| Проверять новые CVE | Еженедельно |
| Пересматривать настройки безопасности | После каждого релиза |
| Обновлять инструменты | При выходе новых версий |
Антипаттерн №4. «Игнорируем предупреждения»
Почему это опасно:
| Уровень предупреждения | Что это значит | Если игнорировать |
|---|---|---|
| Информация (Info) | Рекомендация | Нет проблем |
| Низкая (Low) | Потенциальная проблема | Может стать уязвимостью |
| Средняя (Medium) | Реальная проблема | Может привести к атаке |
| Высокая (High) | Критическая уязвимость | Атака почти гарантирована |
Пример:
wireframe
SAST: ⚠️ Предупреждение: используется MD5 для хеширования паролей.
Рекомендация: использовать bcrypt.
Разработчик: "Ну, работает же. Не буду трогать."
Через месяц:
Хакеры взламывают пароли (MD5 уязвим) ❌
Желтые предупреждения становятся красными уязвимостями.
Сравнительная таблица антипаттернов представлена ниже:
| Антипаттерн | Симптом | Последствия | Решение |
|---|---|---|---|
| «Не моя работа» | Никто не отвечает за безопасность | Система уязвима, все ждут другого | Безопасность — задача всех |
| «SAST достаточно» | Запускают только SAST | DAST находит проблемы в работе | Использовать SAST + DAST |
| «Запустили и забыли» | Инструменты не обновляются | Новые уязвимости не находятся | Обновлять регулярно |
| «Игнорируем предупреждения» | Желтые отчеты закрываются | Предупреждения становятся уязвимостями | Исправлять все, даже низкорисковые |
В заключение нужно разобрать что делать и как это делать правильно при работе с тестированием:
| Что нужно делать | Как |
|---|---|
| Признать ответственность | Безопасность — задача каждого члена команды |
| Использовать все инструменты | SAST + DAST + SCA — не один, а все |
| Обновлять регулярно | Инструменты, правила, библиотеки |
| Не игнорировать предупреждения | Исправлять все проблемы, даже низкорисковые |
| Проверять снова | После исправления — перезапускать проверку |