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
}
}
Заключение
Эффективный чек-лист безопасности должен:
- Покрывать все области — приложение, инфраструктура, процессы
- Быть автоматизированным — где возможно
- Регулярно обновляться — с учетом новых угроз
- Интегрироваться в CI/CD — проверки на каждом деплое
- Генерировать отчеты — для отслеживания прогресса