/
monik
/
lab2_cicd_monitoring
Обзор
Документация
Войти
/
monik
/
lab2_cicd_monitoring
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
scripts/ci/simulate-security-issues.sh
299 строк
11 KB
Kirill Kazarin
first_commit
24 авг 2025, 15:25
24 авг 2025, 15:25
5454277
Код
Авторство
О чём код?
#!/bin/bash # Скрипт для эмуляции проблем безопасности в CI/CD пайплайне # Использование: ./scripts/ci/simulate-security-issues.sh [issue_type] set -e # Цвета для вывода RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Функция логирования log() { echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1" } error() { echo -e "${RED}[ERROR]${NC} $1" } success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } # Проверка аргументов if [ $# -eq 0 ]; then echo "Использование: $0 [issue_type]" echo "" echo "Доступные типы проблем:" echo " sca - Уязвимая библиотека (SCA)" echo " secrets - Секрет в коде" echo " lint - Нарушение стиля кода" echo " tests - Сломанные unit тесты" echo " trivy - Уязвимый базовый образ" echo " all - Все проблемы одновременно" echo " restore - Восстановление рабочего состояния" exit 1 fi ISSUE_TYPE=$1 # Функция создания backup create_backup() { log "Создание backup текущего состояния..." BACKUP_DIR="backup_$(date +%Y%m%d_%H%M%S)" mkdir -p "$BACKUP_DIR" # Копируем основные файлы cp app.py "$BACKUP_DIR/" 2>/dev/null || true cp requirements.txt "$BACKUP_DIR/" 2>/dev/null || true cp Dockerfile "$BACKUP_DIR/" 2>/dev/null || true cp tests/test_app.py "$BACKUP_DIR/" 2>/dev/null || true log "Backup создан в директории: $BACKUP_DIR" } # Функция восстановления из backup restore_from_backup() { if [ -z "$1" ]; then error "Не указана директория backup для восстановления" exit 1 fi BACKUP_DIR=$1 if [ ! -d "$BACKUP_DIR" ]; then error "Директория backup не найдена: $BACKUP_DIR" exit 1 fi log "Восстановление из backup: $BACKUP_DIR" # Восстанавливаем файлы cp "$BACKUP_DIR/app.py" . 2>/dev/null || true cp "$BACKUP_DIR/requirements.txt" . 2>/dev/null || true cp "$BACKUP_DIR/Dockerfile" . 2>/dev/null || true cp "$BACKUP_DIR/test_app.py" tests/ 2>/dev/null || true success "Восстановление завершено" } # Функция эмуляции уязвимой библиотеки (SCA) simulate_sca_issue() { log "Эмуляция проблемы SCA: добавление уязвимой библиотеки" # Добавляем уязвимую версию requests echo "requests==2.25.1" >> requirements.txt # Добавляем комментарий echo "# Уязвимая версия для тестирования SCA" >> requirements.txt success "Добавлена уязвимая библиотека requests==2.25.1" warning "Ожидаемый результат: падение на этапе deps_licenses" } # Функция эмуляции секрета в коде simulate_secrets_issue() { log "Эмуляция проблемы Secrets: добавление секрета в код" # Добавляем секрет в app.py cat >> app.py << 'EOF' # ВНИМАНИЕ: Это тестовый секрет для демонстрации gitleaks! # В реальном проекте НИКОГДА не коммитьте секреты! API_KEY = "sk-1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" DATABASE_PASSWORD = "super_secret_password_123" AWS_ACCESS_KEY = "AKIAIOSFODNN7EXAMPLE" AWS_SECRET_KEY = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" EOF success "Добавлены тестовые секреты в app.py" warning "Ожидаемый результат: падение на этапе secrets" } # Функция эмуляции нарушения стиля кода simulate_lint_issue() { log "Эмуляция проблемы Lint: нарушение PEP8" # Добавляем плохо отформатированный код cat >> app.py << 'EOF' # Плохо отформатированный код для тестирования линтера def bad_function( ): x=1+2 if x==3: print("bad formatting") return x class BadClass: def __init__(self,param1,param2): self.param1=param1 self.param2=param2 EOF success "Добавлен плохо отформатированный код" warning "Ожидаемый результат: падение на этапе lint" } # Функция эмуляции сломанных тестов simulate_tests_issue() { log "Эмуляция проблемы Tests: добавление сломанного теста" # Добавляем сломанный тест cat >> tests/test_app.py << 'EOF' def test_broken_function(): """Этот тест всегда падает для демонстрации""" assert False, "Этот тест специально сломан для демонстрации CI/CD" def test_division_by_zero(): """Тест с делением на ноль""" result = 1 / 0 assert result == 0 def test_nonexistent_attribute(): """Тест с несуществующим атрибутом""" obj = object() assert obj.nonexistent_attribute == "value" EOF success "Добавлены сломанные тесты" warning "Ожидаемый результат: падение на этапе unit" } # Функция эмуляции уязвимого базового образа simulate_trivy_issue() { log "Эмуляция проблемы Trivy: уязвимый базовый образ" # Создаем backup текущего Dockerfile cp Dockerfile Dockerfile.backup # Заменяем на уязвимую версию sed -i 's/FROM python:3.11-slim/FROM python:3.9-slim/' Dockerfile # Добавляем комментарий sed -i '1i# ВНИМАНИЕ: Уязвимая версия для тестирования Trivy!' Dockerfile success "Dockerfile изменен на уязвимую версию python:3.9-slim" warning "Ожидаемый результат: падение на этапе scan_image" } # Функция эмуляции всех проблем simulate_all_issues() { log "Эмуляция всех проблем безопасности одновременно" simulate_sca_issue simulate_secrets_issue simulate_lint_issue simulate_tests_issue simulate_trivy_issue warning "Все проблемы добавлены! CI/CD пайплайн должен упасть на первом же этапе" } # Функция восстановления рабочего состояния restore_working_state() { log "Восстановление рабочего состояния" # Восстанавливаем requirements.txt if [ -f "requirements.txt.backup" ]; then cp requirements.txt.backup requirements.txt success "requirements.txt восстановлен" else # Удаляем уязвимую библиотеку sed -i '/requests==2.25.1/d' requirements.txt sed -i '/# Уязвимая версия для тестирования SCA/d' requirements.txt fi # Восстанавливаем app.py if [ -f "app.py.backup" ]; then cp app.py.backup app.py success "app.py восстановлен" else # Удаляем добавленные секреты и плохой код sed -i '/# ВНИМАНИЕ: Это тестовый секрет/,/wJalrXUtnFEMI\/K7MDENG\/bPxRfiCYEXAMPLEKEY/d' app.py sed -i '/# Плохо отформатированный код/,/class BadClass:/d' app.py sed -i '/def bad_function/,/return x/d' app.py sed -i '/class BadClass/,/self.param2=param2/d' app.py fi # Восстанавливаем тесты if [ -f "tests/test_app.py.backup" ]; then cp tests/test_app.py.backup tests/test_app.py success "test_app.py восстановлен" else # Удаляем сломанные тесты sed -i '/def test_broken_function/,/assert obj.nonexistent_attribute == "value"/d' tests/test_app.py fi # Восстанавливаем Dockerfile if [ -f "Dockerfile.backup" ]; then cp Dockerfile.backup Dockerfile success "Dockerfile восстановлен" else # Возвращаем безопасную версию sed -i 's/FROM python:3.9-slim/FROM python:3.11-slim/' Dockerfile sed -i '/# ВНИМАНИЕ: Уязвимая версия для тестирования Trivy!/d' Dockerfile fi success "Рабочее состояние восстановлено" } # Основная логика main() { log "Начало эмуляции проблем безопасности: $ISSUE_TYPE" case $ISSUE_TYPE in "sca") create_backup simulate_sca_issue ;; "secrets") create_backup simulate_secrets_issue ;; "lint") create_backup simulate_lint_issue ;; "tests") create_backup simulate_tests_issue ;; "trivy") create_backup simulate_trivy_issue ;; "all") create_backup simulate_all_issues ;; "restore") restore_working_state ;; *) error "Неизвестный тип проблемы: $ISSUE_TYPE" exit 1 ;; esac if [ "$ISSUE_TYPE" != "restore" ]; then echo "" log "Проблема добавлена! Теперь можно:" echo "1. Закоммитить изменения: git add . && git commit -m 'Add security issue: $ISSUE_TYPE'" echo "2. Запустить CI/CD: git push origin main" echo "3. Наблюдать падение пайплайна" echo "" log "Для восстановления используйте: $0 restore" fi } # Запуск основной функции main "$@"