security

Составление проверочного листа

Чек-лист для аудита безопасности приложений и инфраструктуры

#security #audit #checklist #best-practices

Составление проверочного листа

Систематический подход к проверке безопасности с использованием чек-листов для различных областей.

Чек-лист безопасности приложений

interface SecurityChecklistItem {
  id: string;
  category: string;
  description: string;
  priority: 'Critical' | 'High' | 'Medium' | 'Low';
  status: 'Pass' | 'Fail' | 'N/A' | 'Pending';
  evidence?: string;
  remediation?: string;
}

class ApplicationSecurityChecklist {
  getChecklist(): SecurityChecklistItem[] {
    return [
      // Аутентификация
      {
        id: 'AUTH-001',
        category: 'Authentication',
        description: 'Многофакторная аутентификация (MFA) включена для всех пользователей',
        priority: 'Critical',
        status: 'Pending',
        remediation: 'Внедрить MFA через TOTP или SMS'
      },
      {
        id: 'AUTH-002',
        category: 'Authentication',
        description: 'Пароли хранятся с использованием bcrypt/argon2',
        priority: 'Critical',
        status: 'Pending',
        remediation: 'Мигрировать на bcrypt с cost factor >= 12'
      },
      {
        id: 'AUTH-003',
        category: 'Authentication',
        description: 'Политика паролей требует минимум 12 символов',
        priority: 'High',
        status: 'Pending'
      },
      {
        id: 'AUTH-004',
        category: 'Authentication',
        description: 'Блокировка аккаунта после 5 неудачных попыток входа',
        priority: 'High',
        status: 'Pending'
      },
      
      // Авторизация
      {
        id: 'AUTHZ-001',
        category: 'Authorization',
        description: 'Реализован RBAC или ABAC',
        priority: 'Critical',
        status: 'Pending'
      },
      {
        id: 'AUTHZ-002',
        category: 'Authorization',
        description: 'Проверка прав доступа на каждом запросе',
        priority: 'Critical',
        status: 'Pending'
      },
      {
        id: 'AUTHZ-003',
        category: 'Authorization',
        description: 'Принцип наименьших привилегий применен',
        priority: 'High',
        status: 'Pending'
      },
      
      // Защита данных
      {
        id: 'DATA-001',
        category: 'Data Protection',
        description: 'Шифрование данных в состоянии покоя (AES-256)',
        priority: 'Critical',
        status: 'Pending'
      },
      {
        id: 'DATA-002',
        category: 'Data Protection',
        description: 'TLS 1.3 используется для всех соединений',
        priority: 'Critical',
        status: 'Pending'
      },
      {
        id: 'DATA-003',
        category: 'Data Protection',
        description: 'Чувствительные данные маскируются в логах',
        priority: 'High',
        status: 'Pending'
      },
      {
        id: 'DATA-004',
        category: 'Data Protection',
        description: 'Резервное копирование настроено и тестируется',
        priority: 'High',
        status: 'Pending'
      },
      
      // Валидация входных данных
      {
        id: 'INPUT-001',
        category: 'Input Validation',
        description: 'Все входные данные валидируются на сервере',
        priority: 'Critical',
        status: 'Pending'
      },
      {
        id: 'INPUT-002',
        category: 'Input Validation',
        description: 'Используются параметризованные запросы (защита от SQL injection)',
        priority: 'Critical',
        status: 'Pending'
      },
      {
        id: 'INPUT-003',
        category: 'Input Validation',
        description: 'XSS защита через Content Security Policy',
        priority: 'High',
        status: 'Pending'
      },
      {
        id: 'INPUT-004',
        category: 'Input Validation',
        description: 'CSRF токены используются для изменяющих операций',
        priority: 'High',
        status: 'Pending'
      },
      
      // API Security
      {
        id: 'API-001',
        category: 'API Security',
        description: 'Rate limiting настроен для всех endpoints',
        priority: 'High',
        status: 'Pending'
      },
      {
        id: 'API-002',
        category: 'API Security',
        description: 'API ключи ротируются регулярно',
        priority: 'Medium',
        status: 'Pending'
      },
      {
        id: 'API-003',
        category: 'API Security',
        description: 'CORS настроен правильно',
        priority: 'High',
        status: 'Pending'
      },
      
      // Логирование и мониторинг
      {
        id: 'LOG-001',
        category: 'Logging',
        description: 'Все события безопасности логируются',
        priority: 'High',
        status: 'Pending'
      },
      {
        id: 'LOG-002',
        category: 'Logging',
        description: 'Логи хранятся в централизованной системе',
        priority: 'Medium',
        status: 'Pending'
      },
      {
        id: 'LOG-003',
        category: 'Logging',
        description: 'Алерты настроены для подозрительной активности',
        priority: 'High',
        status: 'Pending'
      },
      
      // Управление зависимостями
      {
        id: 'DEP-001',
        category: 'Dependencies',
        description: 'Все зависимости обновлены до последних безопасных версий',
        priority: 'High',
        status: 'Pending'
      },
      {
        id: 'DEP-002',
        category: 'Dependencies',
        description: 'Автоматическое сканирование уязвимостей настроено',
        priority: 'Medium',
        status: 'Pending'
      }
    ];
  }
}

Чек-лист инфраструктуры

class InfrastructureSecurityChecklist {
  getChecklist(): SecurityChecklistItem[] {
    return [
      // Сеть
      {
        id: 'NET-001',
        category: 'Network',
        description: 'Firewall настроен с правилом deny-all по умолчанию',
        priority: 'Critical',
        status: 'Pending'
      },
      {
        id: 'NET-002',
        category: 'Network',
        description: 'VPC изолирован, приватные подсети для backend',
        priority: 'Critical',
        status: 'Pending'
      },
      {
        id: 'NET-003',
        category: 'Network',
        description: 'DDoS защита активирована',
        priority: 'High',
        status: 'Pending'
      },
      {
        id: 'NET-004',
        category: 'Network',
        description: 'WAF настроен для защиты веб-приложений',
        priority: 'High',
        status: 'Pending'
      },
      
      // Серверы
      {
        id: 'SRV-001',
        category: 'Servers',
        description: 'Все серверы обновлены с последними патчами безопасности',
        priority: 'Critical',
        status: 'Pending'
      },
      {
        id: 'SRV-002',
        category: 'Servers',
        description: 'SSH доступ только по ключам, пароли отключены',
        priority: 'Critical',
        status: 'Pending'
      },
      {
        id: 'SRV-003',
        category: 'Servers',
        description: 'Неиспользуемые сервисы отключены',
        priority: 'High',
        status: 'Pending'
      },
      {
        id: 'SRV-004',
        category: 'Servers',
        description: 'Антивирус установлен и обновляется',
        priority: 'Medium',
        status: 'Pending'
      },
      
      // Контейнеры
      {
        id: 'CNT-001',
        category: 'Containers',
        description: 'Образы сканируются на уязвимости перед деплоем',
        priority: 'High',
        status: 'Pending'
      },
      {
        id: 'CNT-002',
        category: 'Containers',
        description: 'Контейнеры запускаются от непривилегированного пользователя',
        priority: 'High',
        status: 'Pending'
      },
      {
        id: 'CNT-003',
        category: 'Containers',
        description: 'Secrets не хранятся в образах',
        priority: 'Critical',
        status: 'Pending'
      },
      
      // Kubernetes
      {
        id: 'K8S-001',
        category: 'Kubernetes',
        description: 'RBAC настроен с принципом наименьших привилегий',
        priority: 'Critical',
        status: 'Pending'
      },
      {
        id: 'K8S-002',
        category: 'Kubernetes',
        description: 'Network policies ограничивают трафик между pods',
        priority: 'High',
        status: 'Pending'
      },
      {
        id: 'K8S-003',
        category: 'Kubernetes',
        description: 'Pod Security Policies применены',
        priority: 'High',
        status: 'Pending'
      },
      
      // Базы данных
      {
        id: 'DB-001',
        category: 'Database',
        description: 'Базы данных не доступны из интернета',
        priority: 'Critical',
        status: 'Pending'
      },
      {
        id: 'DB-002',
        category: 'Database',
        description: 'Шифрование в состоянии покоя включено',
        priority: 'Critical',
        status: 'Pending'
      },
      {
        id: 'DB-003',
        category: 'Database',
        description: 'Регулярные бэкапы настроены и тестируются',
        priority: 'Critical',
        status: 'Pending'
      },
      {
        id: 'DB-004',
        category: 'Database',
        description: 'Аудит доступа к БД включен',
        priority: 'High',
        status: 'Pending'
      }
    ];
  }
}

Автоматизированная проверка

class AutomatedSecurityChecker {
  async runChecks(checklist: SecurityChecklistItem[]): Promise<ChecklistReport> {
    const results: CheckResult[] = [];
    
    for (const item of checklist) {
      const result = await this.checkItem(item);
      results.push(result);
    }
    
    return {
      timestamp: new Date(),
      totalItems: checklist.length,
      passed: results.filter(r => r.status === 'Pass').length,
      failed: results.filter(r => r.status === 'Fail').length,
      pending: results.filter(r => r.status === 'Pending').length,
      results,
      summary: this.generateSummary(results)
    };
  }
  
  private async checkItem(item: SecurityChecklistItem): Promise<CheckResult> {
    try {
      // Выполняем автоматическую проверку
      const passed = await this.performCheck(item);
      
      return {
        itemId: item.id,
        status: passed ? 'Pass' : 'Fail',
        checkedAt: new Date(),
        evidence: passed ? 'Automated check passed' : 'Automated check failed'
      };
    } catch (error) {
      return {
        itemId: item.id,
        status: 'Pending',
        checkedAt: new Date(),
        evidence: 'Manual check required'
      };
    }
  }
  
  private async performCheck(item: SecurityChecklistItem): Promise<boolean> {
    // Реализация автоматических проверок
    switch (item.id) {
      case 'AUTH-002':
        return this.checkPasswordHashing();
      case 'DATA-002':
        return this.checkTLSVersion();
      case 'INPUT-002':
        return this.checkParameterizedQueries();
      default:
        throw new Error('Manual check required');
    }
  }
  
  private async checkPasswordHashing(): Promise<boolean> {
    // Проверяем использование bcrypt
    const config = await this.getAuthConfig();
    return config.hashAlgorithm === 'bcrypt';
  }
  
  private async checkTLSVersion(): Promise<boolean> {
    // Проверяем версию TLS
    const config = await this.getTLSConfig();
    return config.minVersion >= 1.3;
  }
  
  private async checkParameterizedQueries(): Promise<boolean> {
    // Проверяем использование параметризованных запросов
    return true;
  }
  
  private async getAuthConfig(): Promise<any> {
    return { hashAlgorithm: 'bcrypt' };
  }
  
  private async getTLSConfig(): Promise<any> {
    return { minVersion: 1.3 };
  }
  
  private generateSummary(results: CheckResult[]): ChecklistSummary {
    const critical = results.filter(r => 
      r.status === 'Fail' && this.getPriority(r.itemId) === 'Critical'
    ).length;
    
    const high = results.filter(r => 
      r.status === 'Fail' && this.getPriority(r.itemId) === 'High'
    ).length;
    
    return {
      criticalIssues: critical,
      highIssues: high,
      overallStatus: critical > 0 ? 'Critical' : high > 0 ? 'High' : 'Good'
    };
  }
  
  private getPriority(itemId: string): string {
    // Получаем приоритет элемента
    return 'High';
  }
}

interface CheckResult {
  itemId: string;
  status: 'Pass' | 'Fail' | 'Pending';
  checkedAt: Date;
  evidence: string;
}

interface ChecklistReport {
  timestamp: Date;
  totalItems: number;
  passed: number;
  failed: number;
  pending: number;
  results: CheckResult[];
  summary: ChecklistSummary;
}

interface ChecklistSummary {
  criticalIssues: number;
  highIssues: number;
  overallStatus: string;
}

Отчет по чек-листу

class ChecklistReportGenerator {
  generateReport(
    checklist: SecurityChecklistItem[],
    results: CheckResult[]
  ): string {
    let report = '# Security Audit Report\n\n';
    report += `Generated: ${new Date().toISOString()}\n\n`;
    
    // Executive Summary
    report += '## Executive Summary\n\n';
    const summary = this.calculateSummary(checklist, results);
    report += `- Total Items: ${checklist.length}\n`;
    report += `- Passed: ${summary.passed}\n`;
    report += `- Failed: ${summary.failed}\n`;
    report += `- Pending: ${summary.pending}\n\n`;
    
    // Critical Issues
    const criticalIssues = this.getCriticalIssues(checklist, results);
    if (criticalIssues.length > 0) {
      report += '## Critical Issues\n\n';
      criticalIssues.forEach(issue => {
        report += `### ${issue.id}: ${issue.description}\n`;
        report += `**Priority:** ${issue.priority}\n`;
        report += `**Status:** ${issue.status}\n`;
        if (issue.remediation) {
          report += `**Remediation:** ${issue.remediation}\n`;
        }
        report += '\n';
      });
    }
    
    // Detailed Results by Category
    report += '## Detailed Results\n\n';
    const categories = this.groupByCategory(checklist);
    
    for (const [category, items] of Object.entries(categories)) {
      report += `### ${category}\n\n`;
      
      items.forEach(item => {
        const result = results.find(r => r.itemId === item.id);
        const status = result?.status || 'Pending';
        const icon = status === 'Pass' ? '✅' : status === 'Fail' ? '❌' : '⏳';
        
        report += `${icon} **${item.id}**: ${item.description}\n`;
        report += `   Priority: ${item.priority} | Status: ${status}\n`;
        if (result?.evidence) {
          report += `   Evidence: ${result.evidence}\n`;
        }
        report += '\n';
      });
    }
    
    return report;
  }
  
  private calculateSummary(
    checklist: SecurityChecklistItem[],
    results: CheckResult[]
  ): any {
    return {
      passed: results.filter(r => r.status === 'Pass').length,
      failed: results.filter(r => r.status === 'Fail').length,
      pending: results.filter(r => r.status === 'Pending').length
    };
  }
  
  private getCriticalIssues(
    checklist: SecurityChecklistItem[],
    results: CheckResult[]
  ): SecurityChecklistItem[] {
    return checklist.filter(item => {
      const result = results.find(r => r.itemId === item.id);
      return item.priority === 'Critical' && result?.status === 'Fail';
    });
  }
  
  private groupByCategory(
    checklist: SecurityChecklistItem[]
  ): Record<string, SecurityChecklistItem[]> {
    const grouped: Record<string, SecurityChecklistItem[]> = {};
    
    checklist.forEach(item => {
      if (!grouped[item.category]) {
        grouped[item.category] = [];
      }
      grouped[item.category].push(item);
    });
    
    return grouped;
  }
}

Интеграция в CI/CD

class SecurityChecklistCI {
  async runInPipeline(): Promise<void> {
    console.log('Running security checklist...');
    
    // 1. Загружаем чек-лист
    const appChecklist = new ApplicationSecurityChecklist();
    const infraChecklist = new InfrastructureSecurityChecklist();
    
    const allItems = [
      ...appChecklist.getChecklist(),
      ...infraChecklist.getChecklist()
    ];
    
    // 2. Запускаем автоматические проверки
    const checker = new AutomatedSecurityChecker();
    const report = await checker.runChecks(allItems);
    
    // 3. Генерируем отчет
    const generator = new ChecklistReportGenerator();
    const markdown = generator.generateReport(allItems, report.results);
    
    // 4. Сохраняем отчет
    await fs.writeFile('security-report.md', markdown);
    
    // 5. Проверяем критичные проблемы
    if (report.summary.criticalIssues > 0) {
      console.error(`Found ${report.summary.criticalIssues} critical issues!`);
      process.exit(1); // Fail the build
    }
    
    console.log('Security checklist passed!');
  }
}

// GitHub Actions workflow
const githubWorkflow = `
name: Security Checklist

on: [push, pull_request]

jobs:
  security-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      
      - name: Run Security Checklist
        run: npm run security:check
      
      - name: Upload Report
        uses: actions/upload-artifact@v2
        with:
          name: security-report
          path: security-report.md
`;

Периодический аудит

class PeriodicSecurityAudit {
  async scheduleAudits(): Promise<void> {
    // Еженедельный автоматический аудит
    cron.schedule('0 0 * * 0', async () => {
      await this.runWeeklyAudit();
    });
    
    // Ежемесячный полный аудит
    cron.schedule('0 0 1 * *', async () => {
      await this.runMonthlyAudit();
    });
    
    // Ежеквартальный аудит соответствия
    cron.schedule('0 0 1 */3 *', async () => {
      await this.runComplianceAudit();
    });
  }
  
  private async runWeeklyAudit(): Promise<void> {
    console.log('Running weekly security audit...');
    
    const checker = new AutomatedSecurityChecker();
    const appChecklist = new ApplicationSecurityChecklist();
    const report = await checker.runChecks(appChecklist.getChecklist());
    
    // Отправляем отчет команде безопасности
    await this.sendReport(report, 'security-team@example.com');
  }
  
  private async runMonthlyAudit(): Promise<void> {
    console.log('Running monthly security audit...');
    
    // Полный аудит приложения и инфраструктуры
    const ci = new SecurityChecklistCI();
    await ci.runInPipeline();
  }
  
  private async runComplianceAudit(): Promise<void> {
    console.log('Running compliance audit...');
    
    // Аудит соответствия стандартам (GDPR, PCI DSS, etc.)
  }
  
  private async sendReport(report: ChecklistReport, email: string): Promise<void> {
    // Отправляем отчет по email
  }
}

Заключение

Эффективный чек-лист безопасности должен:

  1. Покрывать все области — приложение, инфраструктура, процессы
  2. Быть автоматизированным — где возможно
  3. Регулярно обновляться — с учетом новых угроз
  4. Интегрироваться в CI/CD — проверки на каждом деплое
  5. Генерировать отчеты — для отслеживания прогресса