security

Как разработать проект архитектуры безопасности

Проектирование безопасной архитектуры приложений и систем

#security #architecture #design #best-practices

Как разработать проект архитектуры безопасности

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

Принципы безопасного дизайна

Defense in Depth (Эшелонированная защита)

class DefenseInDepth {
  // Уровень 1: Периметр
  perimeter = {
    firewall: 'AWS WAF',
    ddosProtection: 'CloudFlare',
    cdn: 'CloudFront'
  };
  
  // Уровень 2: Сеть
  network = {
    vpc: 'Isolated VPC',
    subnets: 'Private subnets for backend',
    securityGroups: 'Restrictive rules'
  };
  
  // Уровень 3: Приложение
  application = {
    authentication: 'OAuth 2.0 + MFA',
    authorization: 'RBAC',
    inputValidation: 'Server-side validation',
    outputEncoding: 'Context-aware encoding'
  };
  
  // Уровень 4: Данные
  data = {
    encryptionAtRest: 'AES-256',
    encryptionInTransit: 'TLS 1.3',
    dataClassification: 'PII, Confidential, Public',
    accessControl: 'Least privilege'
  };
  
  // Уровень 5: Мониторинг
  monitoring = {
    logging: 'Centralized logging',
    siem: 'Security Information and Event Management',
    alerting: 'Real-time alerts',
    incidentResponse: 'Automated response'
  };
}

Zero Trust Architecture

interface ZeroTrustPrinciples {
  // Никогда не доверяй, всегда проверяй
  verifyExplicitly: {
    authentication: 'Multi-factor authentication';
    authorization: 'Context-based access control';
    continuousValidation: 'Re-authenticate periodically';
  };
  
  // Наименьшие привилегии
  leastPrivilege: {
    justInTime: 'JIT access';
    justEnough: 'Minimal permissions';
    riskBased: 'Adaptive access';
  };
  
  // Предполагай нарушение
  assumeBreach: {
    segmentation: 'Micro-segmentation';
    encryption: 'End-to-end encryption';
    analytics: 'Behavioral analytics';
  };
}

class ZeroTrustImplementation {
  async authenticateRequest(request: Request): Promise<AuthResult> {
    // 1. Проверка идентичности
    const identity = await this.verifyIdentity(request);
    
    // 2. Проверка устройства
    const device = await this.verifyDevice(request);
    
    // 3. Проверка контекста
    const context = await this.analyzeContext(request);
    
    // 4. Оценка риска
    const riskScore = this.calculateRisk(identity, device, context);
    
    // 5. Принятие решения
    if (riskScore > 0.7) {
      return { allowed: false, reason: 'High risk' };
    }
    
    // 6. Выдача токена с ограниченным временем жизни
    const token = await this.issueToken(identity, { ttl: 300 });
    
    return { allowed: true, token };
  }
  
  private async verifyIdentity(request: Request): Promise<Identity> {
    // Проверка учетных данных + MFA
    return { userId: '123', verified: true };
  }
  
  private async verifyDevice(request: Request): Promise<Device> {
    // Проверка устройства (fingerprint, compliance)
    return { deviceId: 'abc', trusted: true };
  }
  
  private async analyzeContext(request: Request): Promise<Context> {
    // Анализ контекста (IP, location, time, behavior)
    return { location: 'US', time: new Date(), anomaly: false };
  }
  
  private calculateRisk(
    identity: Identity,
    device: Device,
    context: Context
  ): number {
    let risk = 0;
    
    if (!identity.verified) risk += 0.5;
    if (!device.trusted) risk += 0.3;
    if (context.anomaly) risk += 0.4;
    
    return Math.min(risk, 1);
  }
  
  private async issueToken(identity: Identity, options: any): Promise<string> {
    return 'jwt-token';
  }
}

interface AuthResult {
  allowed: boolean;
  token?: string;
  reason?: string;
}

interface Identity {
  userId: string;
  verified: boolean;
}

interface Device {
  deviceId: string;
  trusted: boolean;
}

interface Context {
  location: string;
  time: Date;
  anomaly: boolean;
}

Secure by Design

Аутентификация и авторизация

class SecureAuthSystem {
  // OAuth 2.0 + OIDC
  async authenticate(credentials: Credentials): Promise<TokenSet> {
    // 1. Проверка учетных данных
    const user = await this.verifyCredentials(credentials);
    
    // 2. MFA challenge
    if (user.mfaEnabled) {
      await this.verifyMFA(user);
    }
    
    // 3. Генерация токенов
    const accessToken = await this.generateAccessToken(user, { ttl: 900 });
    const refreshToken = await this.generateRefreshToken(user, { ttl: 86400 });
    
    // 4. Аудит
    await this.auditLog({
      event: 'authentication',
      userId: user.id,
      timestamp: new Date(),
      success: true
    });
    
    return { accessToken, refreshToken };
  }
  
  // RBAC Authorization
  async authorize(user: User, resource: string, action: string): Promise<boolean> {
    // 1. Получаем роли пользователя
    const roles = await this.getUserRoles(user.id);
    
    // 2. Получаем разрешения для ролей
    const permissions = await this.getRolePermissions(roles);
    
    // 3. Проверяем разрешение
    const allowed = permissions.some(p => 
      p.resource === resource && p.actions.includes(action)
    );
    
    // 4. Аудит
    await this.auditLog({
      event: 'authorization',
      userId: user.id,
      resource,
      action,
      allowed,
      timestamp: new Date()
    });
    
    return allowed;
  }
  
  private async verifyCredentials(credentials: Credentials): Promise<User> {
    // Используем bcrypt для хеширования паролей
    return { id: '123', mfaEnabled: true };
  }
  
  private async verifyMFA(user: User): Promise<void> {
    // TOTP verification
  }
  
  private async generateAccessToken(user: User, options: any): Promise<string> {
    // JWT с коротким временем жизни
    return 'access-token';
  }
  
  private async generateRefreshToken(user: User, options: any): Promise<string> {
    // Refresh token с длинным временем жизни
    return 'refresh-token';
  }
  
  private async getUserRoles(userId: string): Promise<string[]> {
    return ['user', 'editor'];
  }
  
  private async getRolePermissions(roles: string[]): Promise<Permission[]> {
    return [
      { resource: 'articles', actions: ['read', 'write'] }
    ];
  }
  
  private async auditLog(event: any): Promise<void> {
    // Логирование в SIEM
  }
}

interface Credentials {
  username: string;
  password: string;
}

interface TokenSet {
  accessToken: string;
  refreshToken: string;
}

interface User {
  id: string;
  mfaEnabled: boolean;
}

interface Permission {
  resource: string;
  actions: string[];
}

Защита данных

class DataProtection {
  // Шифрование в состоянии покоя
  async encryptAtRest(data: string, key: string): Promise<string> {
    const crypto = require('crypto');
    const algorithm = 'aes-256-gcm';
    const iv = crypto.randomBytes(16);
    
    const cipher = crypto.createCipheriv(algorithm, Buffer.from(key, 'hex'), iv);
    
    let encrypted = cipher.update(data, 'utf8', 'hex');
    encrypted += cipher.final('hex');
    
    const authTag = cipher.getAuthTag();
    
    return JSON.stringify({
      encrypted,
      iv: iv.toString('hex'),
      authTag: authTag.toString('hex')
    });
  }
  
  // Шифрование в transit
  configureHTTPS(): HTTPSConfig {
    return {
      protocol: 'TLS 1.3',
      ciphers: [
        'TLS_AES_256_GCM_SHA384',
        'TLS_CHACHA20_POLY1305_SHA256',
        'TLS_AES_128_GCM_SHA256'
      ],
      hsts: {
        maxAge: 31536000,
        includeSubDomains: true,
        preload: true
      },
      certificatePinning: true
    };
  }
  
  // Маскирование чувствительных данных
  maskSensitiveData(data: any): any {
    const masked = { ...data };
    
    // Маскируем PII
    if (masked.email) {
      masked.email = this.maskEmail(masked.email);
    }
    
    if (masked.phone) {
      masked.phone = this.maskPhone(masked.phone);
    }
    
    if (masked.creditCard) {
      masked.creditCard = this.maskCreditCard(masked.creditCard);
    }
    
    return masked;
  }
  
  private maskEmail(email: string): string {
    const [local, domain] = email.split('@');
    return `${local[0]}***@${domain}`;
  }
  
  private maskPhone(phone: string): string {
    return `***-***-${phone.slice(-4)}`;
  }
  
  private maskCreditCard(card: string): string {
    return `****-****-****-${card.slice(-4)}`;
  }
}

interface HTTPSConfig {
  protocol: string;
  ciphers: string[];
  hsts: {
    maxAge: number;
    includeSubDomains: boolean;
    preload: boolean;
  };
  certificatePinning: boolean;
}

Защита API

class APISecurityLayer {
  // Rate Limiting
  async rateLimit(userId: string, endpoint: string): Promise<boolean> {
    const key = `ratelimit:${userId}:${endpoint}`;
    const limit = 100; // requests per minute
    const window = 60; // seconds
    
    const current = await redis.incr(key);
    
    if (current === 1) {
      await redis.expire(key, window);
    }
    
    return current <= limit;
  }
  
  // Input Validation
  validateInput(data: any, schema: Schema): ValidationResult {
    const errors: string[] = [];
    
    for (const [field, rules] of Object.entries(schema)) {
      const value = data[field];
      
      if (rules.required && !value) {
        errors.push(`${field} is required`);
      }
      
      if (rules.type && typeof value !== rules.type) {
        errors.push(`${field} must be ${rules.type}`);
      }
      
      if (rules.pattern && !rules.pattern.test(value)) {
        errors.push(`${field} format is invalid`);
      }
      
      if (rules.maxLength && value.length > rules.maxLength) {
        errors.push(`${field} is too long`);
      }
    }
    
    return {
      valid: errors.length === 0,
      errors
    };
  }
  
  // CORS Configuration
  configureCORS(): CORSConfig {
    return {
      origin: ['https://example.com'],
      methods: ['GET', 'POST', 'PUT', 'DELETE'],
      allowedHeaders: ['Content-Type', 'Authorization'],
      exposedHeaders: ['X-Total-Count'],
      credentials: true,
      maxAge: 86400
    };
  }
  
  // API Key Management
  async generateAPIKey(userId: string): Promise<APIKey> {
    const key = crypto.randomBytes(32).toString('hex');
    const hash = await bcrypt.hash(key, 10);
    
    const apiKey: APIKey = {
      id: generateId(),
      userId,
      keyHash: hash,
      createdAt: new Date(),
      expiresAt: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000),
      scopes: ['read', 'write']
    };
    
    await db.apiKeys.insert(apiKey);
    
    return { ...apiKey, key }; // Возвращаем ключ только один раз
  }
}

interface Schema {
  [field: string]: {
    required?: boolean;
    type?: string;
    pattern?: RegExp;
    maxLength?: number;
  };
}

interface ValidationResult {
  valid: boolean;
  errors: string[];
}

interface CORSConfig {
  origin: string[];
  methods: string[];
  allowedHeaders: string[];
  exposedHeaders: string[];
  credentials: boolean;
  maxAge: number;
}

interface APIKey {
  id: string;
  userId: string;
  keyHash: string;
  key?: string;
  createdAt: Date;
  expiresAt: Date;
  scopes: string[];
}

Архитектурные паттерны безопасности

API Gateway Pattern

class SecureAPIGateway {
  async handleRequest(request: Request): Promise<Response> {
    try {
      // 1. Rate Limiting
      if (!await this.checkRateLimit(request)) {
        return { status: 429, body: 'Too Many Requests' };
      }
      
      // 2. Authentication
      const auth = await this.authenticate(request);
      if (!auth.success) {
        return { status: 401, body: 'Unauthorized' };
      }
      
      // 3. Authorization
      const authorized = await this.authorize(auth.user, request);
      if (!authorized) {
        return { status: 403, body: 'Forbidden' };
      }
      
      // 4. Input Validation
      const validation = this.validateInput(request.body);
      if (!validation.valid) {
        return { status: 400, body: validation.errors };
      }
      
      // 5. Proxy to backend
      const response = await this.proxyToBackend(request);
      
      // 6. Output sanitization
      const sanitized = this.sanitizeOutput(response);
      
      // 7. Security headers
      return this.addSecurityHeaders(sanitized);
      
    } catch (error) {
      // Не раскрываем детали ошибок
      return { status: 500, body: 'Internal Server Error' };
    }
  }
  
  private async checkRateLimit(request: Request): Promise<boolean> {
    return true;
  }
  
  private async authenticate(request: Request): Promise<any> {
    return { success: true, user: {} };
  }
  
  private async authorize(user: any, request: Request): Promise<boolean> {
    return true;
  }
  
  private validateInput(body: any): ValidationResult {
    return { valid: true, errors: [] };
  }
  
  private async proxyToBackend(request: Request): Promise<Response> {
    return { status: 200, body: {} };
  }
  
  private sanitizeOutput(response: Response): Response {
    return response;
  }
  
  private addSecurityHeaders(response: Response): Response {
    return {
      ...response,
      headers: {
        'X-Content-Type-Options': 'nosniff',
        'X-Frame-Options': 'DENY',
        'X-XSS-Protection': '1; mode=block',
        'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
        'Content-Security-Policy': "default-src 'self'"
      }
    };
  }
}

interface Request {
  method: string;
  path: string;
  headers: Record<string, string>;
  body: any;
}

interface Response {
  status: number;
  body: any;
  headers?: Record<string, string>;
}

Security Architecture Document

interface SecurityArchitectureDocument {
  // 1. Обзор
  overview: {
    purpose: string;
    scope: string;
    assumptions: string[];
  };
  
  // 2. Архитектурные принципы
  principles: {
    defenseInDepth: boolean;
    zeroTrust: boolean;
    leastPrivilege: boolean;
    secureByDefault: boolean;
  };
  
  // 3. Компоненты безопасности
  components: {
    authentication: AuthenticationDesign;
    authorization: AuthorizationDesign;
    encryption: EncryptionDesign;
    logging: LoggingDesign;
    monitoring: MonitoringDesign;
  };
  
  // 4. Границы доверия
  trustBoundaries: TrustBoundary[];
  
  // 5. Потоки данных
  dataFlows: DataFlow[];
  
  // 6. Контроли безопасности
  securityControls: SecurityControl[];
  
  // 7. Соответствие требованиям
  compliance: ComplianceRequirement[];
}

interface AuthenticationDesign {
  mechanism: string;
  mfaRequired: boolean;
  sessionManagement: string;
}

interface AuthorizationDesign {
  model: 'RBAC' | 'ABAC';
  enforcement: string;
}

interface EncryptionDesign {
  atRest: string;
  inTransit: string;
  keyManagement: string;
}

interface LoggingDesign {
  events: string[];
  retention: number;
  storage: string;
}

interface MonitoringDesign {
  metrics: string[];
  alerting: string;
  siem: string;
}

interface TrustBoundary {
  name: string;
  description: string;
  controls: string[];
}

interface DataFlow {
  from: string;
  to: string;
  data: string;
  protection: string[];
}

interface SecurityControl {
  id: string;
  type: 'Preventive' | 'Detective' | 'Corrective';
  description: string;
}

interface ComplianceRequirement {
  standard: string;
  requirements: string[];
  controls: string[];
}

Заключение

Безопасная архитектура требует:

  1. Встраивания безопасности с самого начала
  2. Многоуровневой защиты (Defense in Depth)
  3. Принципа Zero Trust
  4. Регулярного пересмотра и обновления
  5. Документирования архитектурных решений