security

Классификация данных

Категоризация данных по уровням конфиденциальности и требованиям защиты

#security #data-protection #classification #governance

Классификация данных

Классификация данных — процесс категоризации информации по уровням конфиденциальности для применения соответствующих мер защиты.

Уровни классификации

enum DataClassification {
  PUBLIC = 'Public',
  INTERNAL = 'Internal',
  CONFIDENTIAL = 'Confidential',
  RESTRICTED = 'Restricted'
}

interface ClassifiedData {
  id: string;
  content: any;
  classification: DataClassification;
  owner: string;
  createdAt: Date;
  retentionPeriod: number; // дни
  encryptionRequired: boolean;
  accessControl: AccessControl;
}

interface AccessControl {
  allowedRoles: string[];
  allowedUsers: string[];
  requiresMFA: boolean;
  auditAccess: boolean;
}

Критерии классификации

class DataClassifier {
  classify(data: any, context: ClassificationContext): DataClassification {
    // 1. Проверяем наличие PII (Personally Identifiable Information)
    if (this.containsPII(data)) {
      return DataClassification.RESTRICTED;
    }
    
    // 2. Проверяем финансовые данные
    if (this.containsFinancialData(data)) {
      return DataClassification.RESTRICTED;
    }
    
    // 3. Проверяем коммерческую тайну
    if (context.isTradeSecret) {
      return DataClassification.CONFIDENTIAL;
    }
    
    // 4. Проверяем внутреннюю информацию
    if (context.isInternal) {
      return DataClassification.INTERNAL;
    }
    
    // 5. По умолчанию - публичные данные
    return DataClassification.PUBLIC;
  }
  
  private containsPII(data: any): boolean {
    const piiFields = [
      'ssn', 'passport', 'driverLicense',
      'creditCard', 'bankAccount',
      'medicalRecord', 'biometric'
    ];
    
    return piiFields.some(field => field in data);
  }
  
  private containsFinancialData(data: any): boolean {
    const financialFields = [
      'salary', 'revenue', 'profit',
      'accountBalance', 'transaction'
    ];
    
    return financialFields.some(field => field in data);
  }
}

interface ClassificationContext {
  isTradeSecret: boolean;
  isInternal: boolean;
  regulatoryRequirements: string[];
}

Автоматическая классификация

class AutomaticClassifier {
  async classifyDocument(document: Document): Promise<ClassifiedData> {
    // 1. Анализ содержимого
    const content = await this.extractContent(document);
    
    // 2. Поиск паттернов
    const patterns = this.detectPatterns(content);
    
    // 3. Определение классификации
    const classification = this.determineClassification(patterns);
    
    // 4. Применение меток
    const labeled = await this.applyLabels(document, classification);
    
    return {
      id: document.id,
      content: labeled,
      classification,
      owner: document.owner,
      createdAt: new Date(),
      retentionPeriod: this.getRetentionPeriod(classification),
      encryptionRequired: this.requiresEncryption(classification),
      accessControl: this.getAccessControl(classification)
    };
  }
  
  private async extractContent(document: Document): Promise<string> {
    // Извлекаем текст из документа
    return document.content;
  }
  
  private detectPatterns(content: string): DetectedPattern[] {
    const patterns: DetectedPattern[] = [];
    
    // Паттерны для PII
    const emailPattern = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g;
    const phonePattern = /\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/g;
    const ssnPattern = /\b\d{3}-\d{2}-\d{4}\b/g;
    const creditCardPattern = /\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/g;
    
    if (emailPattern.test(content)) {
      patterns.push({ type: 'email', sensitivity: 'medium' });
    }
    
    if (phonePattern.test(content)) {
      patterns.push({ type: 'phone', sensitivity: 'medium' });
    }
    
    if (ssnPattern.test(content)) {
      patterns.push({ type: 'ssn', sensitivity: 'high' });
    }
    
    if (creditCardPattern.test(content)) {
      patterns.push({ type: 'credit_card', sensitivity: 'high' });
    }
    
    return patterns;
  }
  
  private determineClassification(patterns: DetectedPattern[]): DataClassification {
    const highSensitivity = patterns.some(p => p.sensitivity === 'high');
    const mediumSensitivity = patterns.some(p => p.sensitivity === 'medium');
    
    if (highSensitivity) {
      return DataClassification.RESTRICTED;
    }
    
    if (mediumSensitivity) {
      return DataClassification.CONFIDENTIAL;
    }
    
    return DataClassification.INTERNAL;
  }
  
  private async applyLabels(
    document: Document,
    classification: DataClassification
  ): Promise<any> {
    // Применяем метки классификации к документу
    return {
      ...document.content,
      _classification: classification,
      _classifiedAt: new Date()
    };
  }
  
  private getRetentionPeriod(classification: DataClassification): number {
    const periods = {
      [DataClassification.PUBLIC]: 365 * 10,      // 10 лет
      [DataClassification.INTERNAL]: 365 * 7,     // 7 лет
      [DataClassification.CONFIDENTIAL]: 365 * 5, // 5 лет
      [DataClassification.RESTRICTED]: 365 * 3    // 3 года
    };
    
    return periods[classification];
  }
  
  private requiresEncryption(classification: DataClassification): boolean {
    return classification === DataClassification.CONFIDENTIAL ||
           classification === DataClassification.RESTRICTED;
  }
  
  private getAccessControl(classification: DataClassification): AccessControl {
    const controls = {
      [DataClassification.PUBLIC]: {
        allowedRoles: ['*'],
        allowedUsers: ['*'],
        requiresMFA: false,
        auditAccess: false
      },
      [DataClassification.INTERNAL]: {
        allowedRoles: ['employee'],
        allowedUsers: [],
        requiresMFA: false,
        auditAccess: true
      },
      [DataClassification.CONFIDENTIAL]: {
        allowedRoles: ['manager', 'admin'],
        allowedUsers: [],
        requiresMFA: true,
        auditAccess: true
      },
      [DataClassification.RESTRICTED]: {
        allowedRoles: ['admin'],
        allowedUsers: [],
        requiresMFA: true,
        auditAccess: true
      }
    };
    
    return controls[classification];
  }
}

interface Document {
  id: string;
  content: any;
  owner: string;
}

interface DetectedPattern {
  type: string;
  sensitivity: 'low' | 'medium' | 'high';
}

Data Loss Prevention (DLP)

class DLPEngine {
  async scanOutboundData(data: any, destination: string): Promise<DLPResult> {
    // 1. Классифицируем данные
    const classification = await this.classifyData(data);
    
    // 2. Проверяем политику
    const policy = await this.getPolicy(classification, destination);
    
    // 3. Применяем действие
    const action = this.determineAction(policy);
    
    // 4. Логируем
    await this.auditLog({
      event: 'dlp_scan',
      classification,
      destination,
      action,
      timestamp: new Date()
    });
    
    return {
      allowed: action === 'allow',
      action,
      reason: policy.reason
    };
  }
  
  async monitorDataMovement(): Promise<void> {
    // Мониторинг перемещения конфиденциальных данных
    const events = await this.getDataMovementEvents();
    
    for (const event of events) {
      const classification = await this.classifyData(event.data);
      
      if (classification === DataClassification.RESTRICTED) {
        await this.alertSecurityTeam({
          event: 'restricted_data_movement',
          userId: event.userId,
          source: event.source,
          destination: event.destination,
          timestamp: event.timestamp
        });
      }
    }
  }
  
  private async classifyData(data: any): Promise<DataClassification> {
    const classifier = new AutomaticClassifier();
    const classified = await classifier.classifyDocument({
      id: 'temp',
      content: data,
      owner: 'system'
    });
    
    return classified.classification;
  }
  
  private async getPolicy(
    classification: DataClassification,
    destination: string
  ): Promise<DLPPolicy> {
    // Получаем политику DLP
    return {
      classification,
      destination,
      action: 'block',
      reason: 'Restricted data cannot be sent externally'
    };
  }
  
  private determineAction(policy: DLPPolicy): 'allow' | 'block' | 'quarantine' {
    return policy.action;
  }
  
  private async getDataMovementEvents(): Promise<DataMovementEvent[]> {
    return [];
  }
  
  private async alertSecurityTeam(alert: any): Promise<void> {
    // Отправляем алерт команде безопасности
  }
  
  private async auditLog(event: any): Promise<void> {
    await db.auditLog.insert(event);
  }
}

interface DLPResult {
  allowed: boolean;
  action: string;
  reason: string;
}

interface DLPPolicy {
  classification: DataClassification;
  destination: string;
  action: 'allow' | 'block' | 'quarantine';
  reason: string;
}

interface DataMovementEvent {
  userId: string;
  data: any;
  source: string;
  destination: string;
  timestamp: Date;
}

Управление жизненным циклом данных

class DataLifecycleManager {
  async manageLifecycle(data: ClassifiedData): Promise<void> {
    const age = this.calculateAge(data.createdAt);
    
    // 1. Проверяем срок хранения
    if (age > data.retentionPeriod) {
      await this.handleExpiredData(data);
      return;
    }
    
    // 2. Проверяем необходимость архивирования
    const archiveThreshold = data.retentionPeriod * 0.7;
    if (age > archiveThreshold) {
      await this.archiveData(data);
      return;
    }
    
    // 3. Обновляем метаданные
    await this.updateMetadata(data);
  }
  
  private calculateAge(createdAt: Date): number {
    const now = new Date();
    const diff = now.getTime() - createdAt.getTime();
    return Math.floor(diff / (1000 * 60 * 60 * 24)); // дни
  }
  
  private async handleExpiredData(data: ClassifiedData): Promise<void> {
    // Проверяем legal hold
    const legalHold = await this.checkLegalHold(data.id);
    if (legalHold) {
      await this.extendRetention(data.id);
      return;
    }
    
    // Удаляем или анонимизируем
    if (data.classification === DataClassification.RESTRICTED) {
      await this.secureDelete(data);
    } else {
      await this.anonymize(data);
    }
    
    await this.auditLog({
      event: 'data_lifecycle_action',
      dataId: data.id,
      action: 'deleted',
      timestamp: new Date()
    });
  }
  
  private async archiveData(data: ClassifiedData): Promise<void> {
    // Перемещаем в архивное хранилище
    await storage.moveToArchive(data.id);
    
    await this.auditLog({
      event: 'data_lifecycle_action',
      dataId: data.id,
      action: 'archived',
      timestamp: new Date()
    });
  }
  
  private async updateMetadata(data: ClassifiedData): Promise<void> {
    // Обновляем метаданные
    await db.data.update(data.id, {
      lastReviewed: new Date()
    });
  }
  
  private async checkLegalHold(dataId: string): Promise<boolean> {
    const hold = await db.legalHolds.findOne({ dataId });
    return hold !== null;
  }
  
  private async extendRetention(dataId: string): Promise<void> {
    await db.data.update(dataId, {
      retentionExtended: true,
      extendedUntil: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000)
    });
  }
  
  private async secureDelete(data: ClassifiedData): Promise<void> {
    // Безопасное удаление (перезапись)
    await storage.secureDelete(data.id);
  }
  
  private async anonymize(data: ClassifiedData): Promise<void> {
    // Анонимизация данных
    await db.data.update(data.id, {
      content: this.anonymizeContent(data.content)
    });
  }
  
  private anonymizeContent(content: any): any {
    // Удаляем идентифицирующую информацию
    return {
      ...content,
      name: '[REDACTED]',
      email: '[REDACTED]',
      phone: '[REDACTED]'
    };
  }
  
  private async auditLog(event: any): Promise<void> {
    await db.auditLog.insert(event);
  }
}

Маркировка данных

class DataLabeling {
  applyVisualMarking(document: Document, classification: DataClassification): Document {
    const markings = {
      [DataClassification.PUBLIC]: {
        header: '',
        footer: '',
        watermark: ''
      },
      [DataClassification.INTERNAL]: {
        header: 'INTERNAL USE ONLY',
        footer: 'INTERNAL USE ONLY',
        watermark: 'INTERNAL'
      },
      [DataClassification.CONFIDENTIAL]: {
        header: 'CONFIDENTIAL',
        footer: 'CONFIDENTIAL',
        watermark: 'CONFIDENTIAL'
      },
      [DataClassification.RESTRICTED]: {
        header: 'RESTRICTED - DO NOT DISTRIBUTE',
        footer: 'RESTRICTED - DO NOT DISTRIBUTE',
        watermark: 'RESTRICTED'
      }
    };
    
    const marking = markings[classification];
    
    return {
      ...document,
      metadata: {
        ...document.metadata,
        classification,
        header: marking.header,
        footer: marking.footer,
        watermark: marking.watermark
      }
    };
  }
  
  applyMetadataLabels(data: any, classification: DataClassification): any {
    return {
      ...data,
      _metadata: {
        classification,
        classifiedAt: new Date(),
        classifiedBy: 'system',
        reviewDate: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000)
      }
    };
  }
}

Обучение и осведомленность

class DataClassificationTraining {
  async conductTraining(userId: string): Promise<TrainingResult> {
    const modules = [
      {
        id: 'classification-basics',
        title: 'Основы классификации данных',
        duration: 15,
        content: 'Уровни классификации и их значение'
      },
      {
        id: 'handling-procedures',
        title: 'Процедуры обработки данных',
        duration: 20,
        content: 'Как правильно обрабатывать данные разных уровней'
      },
      {
        id: 'incident-response',
        title: 'Реагирование на инциденты',
        duration: 10,
        content: 'Что делать при утечке данных'
      }
    ];
    
    const results: ModuleResult[] = [];
    
    for (const module of modules) {
      const result = await this.completeModule(userId, module);
      results.push(result);
    }
    
    const passed = results.every(r => r.score >= 80);
    
    if (passed) {
      await this.issueCertificate(userId);
    }
    
    return {
      userId,
      completedAt: new Date(),
      modules: results,
      passed,
      certificateIssued: passed
    };
  }
  
  private async completeModule(userId: string, module: any): Promise<ModuleResult> {
    // Пользователь проходит модуль
    return {
      moduleId: module.id,
      score: 85,
      completedAt: new Date()
    };
  }
  
  private async issueCertificate(userId: string): Promise<void> {
    await db.certificates.insert({
      userId,
      type: 'data_classification',
      issuedAt: new Date(),
      expiresAt: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000)
    });
  }
}

interface TrainingResult {
  userId: string;
  completedAt: Date;
  modules: ModuleResult[];
  passed: boolean;
  certificateIssued: boolean;
}

interface ModuleResult {
  moduleId: string;
  score: number;
  completedAt: Date;
}

Заключение

Эффективная классификация данных требует:

  1. Четких критериев — определение уровней классификации
  2. Автоматизации — автоматическое обнаружение и маркировка
  3. Контролей — DLP, шифрование, контроль доступа
  4. Управления жизненным циклом — хранение, архивирование, удаление
  5. Обучения — осведомленность сотрудников о процедурах