anonym.legal
Назад к блогуТехнические

Фрагментация формата документов: почему PII остаются...

PII рассеяны по разным форматам: PDF, Excel, Word, сканированные изображения. Узнайте как обнаружить скрытую PII в документах на разных платформах.

April 21, 20267 мин чтения
document formatsPDF anonymizationExcel GDPRbatch processingDSAR compliance

Проблема: Данные во всех форматах

Типичная компания содержит PII в

  • 40% в PDF (контракты, истории, счета)
  • 30% в Excel (листы расчета, отчеты, базы данных)
  • 15% в Word (документы, письма, протоколы)
  • 10% в сканированных изображениях (бумажные архивы)
  • 5% в базах данных (ч/о, CRM)

Проблема: Разные форматы требуют разных инструментов для обнаружения PII.

Типовой сценарий GDPR нарушения

Компания A проводит GDPR аудит:

Проверяем базу данных: 500 записей PII найдено
Проверяем Word документы: 250 PII найдено
Проверяем PDF: 100 PII найдено
Проверяем Excel: 1,200 PII найдено (!)
Проверяем сканированные изображения: 300 PII найдено

Отчет: 2,350 найдено
Аудитор: "Вы пропустили Excel? Это 51% всех данных!"
Штраф GDPR: €500,000 за неправильный учет

Архитектура обнаружения по форматам

Слой 1: PDF обнаружение

import pdfplumber
from presidio_analyzer import AnalyzerEngine

analyzer = AnalyzerEngine()

def detect_pii_in_pdf(pdf_path):
    results = []
    
    with pdfplumber.open(pdf_path) as pdf:
        for page_num, page in enumerate(pdf.pages):
            # Извлекаем текст
            text = page.extract_text()
            
            # Анализируем
            entities = analyzer.analyze(
                text=text,
                language='en'
            )
            
            results.append({
                'page': page_num,
                'text': text,
                'entities': entities
            })
    
    return results

Слой 2: Excel обнаружение

import openpyxl
from presidio_analyzer import AnalyzerEngine

analyzer = AnalyzerEngine()

def detect_pii_in_excel(excel_path):
    results = []
    
    workbook = openpyxl.load_workbook(excel_path)
    
    for sheet_name in workbook.sheetnames:
        sheet = workbook[sheet_name]
        
        for row_num, row in enumerate(sheet.iter_rows(), 1):
            row_text = " ".join(
                str(cell.value) for cell in row if cell.value
            )
            
            entities = analyzer.analyze(
                text=row_text,
                language='en'
            )
            
            if entities:
                results.append({
                    'sheet': sheet_name,
                    'row': row_num,
                    'entities': entities
                })
    
    return results

Слой 3: Word обнаружение

from docx import Document
from presidio_analyzer import AnalyzerEngine

analyzer = AnalyzerEngine()

def detect_pii_in_word(docx_path):
    results = []
    
    doc = Document(docx_path)
    
    for para_num, para in enumerate(doc.paragraphs):
        entities = analyzer.analyze(
            text=para.text,
            language='en'
        )
        
        if entities:
            results.append({
                'paragraph': para_num,
                'text': para.text,
                'entities': entities
            })
    
    return results

Слой 4: Сканированные изображения (OCR)

import pytesseract
from PIL import Image
from presidio_analyzer import AnalyzerEngine

analyzer = AnalyzerEngine()

def detect_pii_in_scanned_image(image_path):
    results = []
    
    # Открываем изображение
    image = Image.open(image_path)
    
    # Извлекаем текст через OCR
    text = pytesseract.image_to_string(image)
    
    # Анализируем текст
    entities = analyzer.analyze(
        text=text,
        language='en'
    )
    
    return {
        'image': image_path,
        'ocr_text': text,
        'entities': entities
    }

Проблемы per-format

PDF проблемы

ПроблемаРешение
Скрытый текст под изображениямиИспользуйте OCR
Зашифрованные PDFТребует пароля
Неправильно кодированный текстПопробуйте несколько кодировок
Текст как изображениеНеобходим OCR

Excel проблемы

ПроблемаРешение
Скрытые листыРаскройте все листы
Скрытые колонкиПокажите все колонки
Формулы содержат PIIПроверьте формулы
Метаданные содержат PIIОчистите метаданные

Word проблемы

ПроблемаРешение
Отслеживание изменений содержит PIIУдалите всю историю
Скрытый текстПокажите скрытый текст
Комментарии содержат PIIУдалите все комментарии
Метаданные автораУдалите метаданные

Сканированные изображения проблемы

ПроблемаРешение
Низкое качество OCRУлучшить изображение
Множественные языкиOCR на нескольких языках
Рукописный текстНизкая точность OCR
Таблицы на изображенииСпециальная таблица OCR

Полная система обнаружения

import os
from pathlib import Path

class DocumentFragmentationScanner:
    def __init__(self):
        self.analyzer = AnalyzerEngine()
    
    def scan_directory(self, directory_path):
        all_results = {}
        
        for file_path in Path(directory_path).rglob('*'):
            if file_path.is_file():
                file_ext = file_path.suffix.lower()
                
                if file_ext == '.pdf':
                    all_results[str(file_path)] = self.detect_pii_in_pdf(str(file_path))
                elif file_ext in ['.xlsx', '.xls']:
                    all_results[str(file_path)] = self.detect_pii_in_excel(str(file_path))
                elif file_ext == '.docx':
                    all_results[str(file_path)] = self.detect_pii_in_word(str(file_path))
                elif file_ext in ['.png', '.jpg', '.jpeg', '.tiff']:
                    all_results[str(file_path)] = self.detect_pii_in_scanned_image(str(file_path))
        
        return all_results
    
    def generate_report(self, scan_results):
        total_files = len(scan_results)
        total_entities = sum(
            len(r.get('entities', []))
            for file_results in scan_results.values()
            for r in (file_results if isinstance(file_results, list) else [file_results])
        )
        
        return {
            'total_files_scanned': total_files,
            'total_pii_entities': total_entities,
            'files_with_pii': [
                file for file, results in scan_results.items()
                if any(r.get('entities') for r in (results if isinstance(results, list) else [results]))
            ]
        }

# Использование
scanner = DocumentFragmentationScanner()
results = scanner.scan_directory('/documents')
report = scanner.generate_report(results)

print(f"Найдено PII в {len(report['files_with_pii'])} файлах")
print(f"Всего PII сущностей: {report['total_pii_entities']}")

GDPR соответствие

Требуется

✅ Сканировать ВСЕ форматы документов ✅ Отслеживать какие данные где находятся ✅ Удалить PII согласно графику хранения ✅ Документировать процесс сканирования ✅ Регулярно пересканировать (quartile)

Вывод

Фрагментация документов означает, что 50%+ вашей PII может быть незащищенной. Сканируйте все форматы.

Готовы защитить ваши данные?

Начните анонимизацию PII с 285+ типов сущностей на 48 языках.