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

LangChain CVE-2025-68664: как персональные данные утекают через ваш RAG-конвейер

CVSS 9.3. Функции сериализации LangChain передают переменные окружения и секреты подконтрольным атакующим LLM. Как обнаружить и устранить утечки персональных данных.

March 16, 20268 мин чтения
LangChainRAG pipelineCVEPII leakagedeveloper securityAPI keysLLM security

Обновлено для 2026 года.

В конце 2025 года в LangChain была обнаружена критическая уязвимость. CVE: CVE-2025-68664. Оценка CVSS: 9.3 (Критическая).

Уязвимость затрагивает код сериализации LangChain.

Что делает CVE-2025-68664

В LangChain есть две функции сериализации: dumps() и dumpd(). Они конвертируют объекты Python в текст.

Уязвимость связана с обработкой замыканий.

Когда LangChain сериализует вызываемый объект, он захватывает контекст замыкания.

Атакующий, контролирующий ответ LLM, может вызвать dumps(). После этого функция читает переменные окружения из процесса Python.

Результат — раскрытие данных. API-ключи, строки подключения к БД, JWT-секреты и учётные данные AWS могут появиться в выводе модели.

Атакующий, который внедрил текст в документ RAG-источника, может прочитать ваши продакшн-секреты.

Уязвимые версии: LangChain ниже 0.3.22 (Python). Версия 0.3.22 содержит исправление.

Данные PyPI показывают широкое использование устаревших версий по март 2026 года включительно.

Как персональные данные утекают через RAG-конвейеры

CVE-2025-68664 — яркий пример. Но это лишь частный случай более широкой проблемы.

Данные через RAG-конвейеры утекают постоянно. Атака для этого не нужна.

Вот типичная корпоративная RAG-система.

Первый этап — индексирование. Вы загружаете корпоративные документы в векторное хранилище. Это могут быть обращения в поддержку, письма клиентов, договоры и кадровые записи.

Распространённые векторные хранилища — Pinecone, Weaviate и pgvector.

Следующий этап — извлечение. Пользователь задаёт вопрос. Система извлекает пять наиболее релевантных фрагментов из хранилища.

Затем — генерация. Эти фрагменты передаются в LLM — GPT-4o, Claude или Gemini — как контекст.

Второй этап — источник проблемы. Извлечённые фрагменты содержат всё то, что было в исходных документах. В том числе:

  • Имена клиентов, электронные адреса и номера телефонов
  • Суммы по договорам, номера счетов и налоговые идентификаторы
  • Данные о зарплатах сотрудников и заметки по оценке эффективности
  • Имена пациентов в клинических записях
  • Номера национальных идентификаторов в иммиграционных файлах

Всё это передаётся в LLM как есть. Оно может появиться в выводе модели.

Оно логируется провайдером LLM. Оно хранится в истории разговора. Оно попадает в стек мониторинга.

Атака для этого не нужна. Именно так RAG работает по замыслу. А этот замысел создаёт реальные риски для конфиденциальности.

68 шаблонов секретов в корпоративных хранилищах документов

Инструменты безопасности отслеживают 68 известных шаблонов секретов. Они встречаются чаще, чем ожидают команды.

Вот самые распространённые.

  • AWS Access Key IDs (AKIA...)
  • API-ключи OpenAI (sk-...)
  • API-ключи Anthropic (sk-ant-...)
  • URI баз данных (postgresql://user:password@host/db)
  • JWT-токены (заголовки в кодировке base64)
  • Personal Access Tokens GitHub
  • Секретные ключи Stripe (sk_live_...)
  • API-ключи SendGrid
  • Account SID и Auth Token Twilio
  • Блоки PEM с приватными ключами

Обращение в поддержку может содержать API-ключ клиента из отладочной сессии.

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

Конфигурационный файл, случайно проиндексированный, может раскрыть целое хранилище секретов.

Когда эти файлы попадают в векторное хранилище без санитизации, каждый запрос может передать секреты в LLM.

Они могут дойти и до конечного пользователя.

Решение: анонимизировать до встраивания

Правильный подход — анонимизировать документы перед разбивкой на фрагменты и встраиванием.

Этот шаг обязателен для любой системы, работающей с клиентскими данными.

Вот пример на Python с использованием API anonym.legal:

import requests
import os

ANONYM_API_KEY = os.environ["ANONYM_API_KEY"]
ANONYM_BASE_URL = "https://anonym.legal/api"

def anonymize_before_embedding(text: str) -> tuple[str, dict]:
    """Анонимизирует персональные данные перед встраиванием."""
    response = requests.post(
        f"{ANONYM_BASE_URL}/presidio/anonymize",
        json={
            "text": text,
            "language": "en",
            "anonymizers": {
                "DEFAULT": {"type": "replace", "new_value": "[REDACTED]"},
                "PERSON": {"type": "mask", "masking_char": "*", "chars_to_mask": 4, "from_end": False},
                "EMAIL_ADDRESS": {"type": "replace", "new_value": "[EMAIL]"},
                "PHONE_NUMBER": {"type": "replace", "new_value": "[PHONE]"},
                "CRYPTO": {"type": "replace", "new_value": "[SECRET]"},
                "URL": {"type": "keep"},
            }
        },
        headers={"Authorization": f"Bearer {ANONYM_API_KEY}"}
    )
    result = response.json()
    return result["text"], result.get("items", [])


def build_rag_index(documents: list[str], vectorstore):
    """Строит RAG-индекс только из чистых документов."""
    anonymized_docs = []
    for doc in documents:
        clean_text, entities = anonymize_before_embedding(doc)
        anonymized_docs.append(clean_text)
        print(f"Удалено {len(entities)} сущностей персональных данных из документа")
    vectorstore.add_texts(anonymized_docs)

API anonym.legal охватывает 273 типов сущностей. Имена, электронные адреса, номера телефонов, национальные идентификаторы, API-ключи и URI баз данных — всё обнаруживается.

В векторное хранилище не попадает ничего конфиденциального. Значит, ничего конфиденциального не может утечь к пользователям.

См. руководство для разработчиков с паттернами настройки для LangChain и LlamaIndex.

Исправьте CVE-2025-68664 прямо сейчас

Если вы используете LangChain ниже версии 0.3.22, обновитесь немедленно:

pip install "langchain>=0.3.22" "langchain-core>=0.3.22"

После установки патча проверьте конфигурации цепочек на наличие рисков внедрения. Вот три шага.

Первый — валидируйте извлечённые фрагменты перед передачей в LLM.

Удаляйте содержимое, соответствующее шаблонам внедрения, например ignore previous instructions, system: или <INST>.

Второй — анонимизируйте до встраивания. Это уменьшает поверхность атаки.

Если внедрение всё же произойдёт, конфиденциальных данных там просто не окажется.

Третий — ограничьте права цепочек. LangChain-цепочки не должны читать переменные окружения, кроме необходимых.

Используйте сервисный аккаунт с минимально необходимыми правами.

Арифметика проста

Оценка CVSS — 9.3. Исправление — один API-вызов на документ.

Сочетание CVE-2025-68664 и общих рисков RAG для данных — реальная ответственность.

Решение очевидно: анонимизируйте при индексировании, а не в момент запроса.

Подробнее о требованиях к корпоративному RAG — на странице безопасности и соответствия.

Источники

  • NVD CVE-2025-68664, CVSS 9.3, уязвимость сериализации LangChain
  • Рекомендация по безопасности LangChain, langchain-ai/langchain GitHub, 2025
  • OWASP LLM Top 10: LLM01 Внедрение промптов, LLM06 Раскрытие конфиденциальной информации
  • Документация по типам сущностей anonym.legal — поддерживается 273 типов

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

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