На проверке KV Cache Hijacking: атака на LLM-инфраструктуру через position-independent reuse

Модуль памяти GPU на тёмном антистатическом коврике, золотые контакты в янтарном свете. Рядом фрагмент платы с надписью blockmanager.py, на фоне — бирюзовое боке серверной стойки.


94% - заявленный авторами средний success rate атаки HijackKV с первой попытки на shared KV cache в multi-tenant LLM-инфраструктуре (по препринту, требует верификации). Работа заявлена на USENIX Security 2026 (препринт без подтверждённого arXiv ID; все численные результаты - по первоисточнику) и описывает принципиально новый класс inference attack на LLM: атакующий отравляет кэшированные Key-Value состояния через оптимизированный prefix, и hijacked KV молча подставляется в запросы других пользователей - без единого adversarial-токена в их входе.

LMCache (CacheBlend), EPIC и ряд систем реализуют position-independent reuse. vLLM поддерживает prefix caching по умолчанию; position-independent reuse доступен опционально через интеграцию с LMCache, но не дефолтный режим. Авторы HijackKV утверждают, что vLLM используется Cloudflare и IBM - независимое подтверждение отсутствует, использование position-independent reuse этими компаниями в production публично не подтверждено.

Параллельно, в другом препринте (заявлен на NDSS 2026, arXiv ID не подтверждён) продемонстрированы три вектора реконструкции приватных пользовательских промптов прямо из KV cache. В русскоязычном сегменте оба направления - KV cache hijacking и утечка данных через KV cache - пока не разобраны. Исправляем.

Бизнес-логика атаки: зачем атакующему KV cache​

Когда говорят о безопасности LLM-инфраструктуры, фокус обычно на prompt injection - манипуляции входным текстом. KV cache hijacking бьёт на другом уровне абстракции: не по модели и не по пользовательскому вводу, а по serving-инфраструктуре. И это куда неприятнее.

Манипуляция ответами LLM для целевых пользователей. Inference-сервис обслуживает клиентов финансовой организации, медицинской платформы, юридической фирмы. Атакующий заставляет модель выдавать контролируемые ответы конкретным пользователям. По ATT&CK - Runtime Data Manipulation (T1565.003, Impact). Пользователь задаёт корректный вопрос, получает подменённый ответ и не имеет способа определить подмену на уровне входных данных. Никакого «injection detected» - потому что injection нет.

Направленное отравление RAG-пайплайнов. В enterprise-deployment пользователи работают с ограниченным набором документов: корпоративные FAQ, нормативные базы, knowledge base. Атакующий, знающий состав документов (часто полупубличная информация), отравляет KV для конкретных text chunk-ов. Каждый пользователь, чей запрос вытянет этот chunk из RAG, получит ответ под влиянием adversarial prefix. Официального ATT&CK-маппинга для cache poisoning нет; ближайшая аналогия - T1659 Content Injection (Initial Access), хотя T1659 описывает injection в сетевой трафик, а не в inference cache.

Утечка приватных данных. Параллельное направление (NDSS 2026, работа «Shadow in the Cache») показывает: из KV cache можно реконструировать исходные пользовательские промпты. В MITRE ATLAS ближайшие техники - AML.T0024 Exfiltration via ML Inference API и смежные. Здесь атакующему не нужно менять ответы - достаточно получить доступ к KV-состояниям другого пользователя.

Импакт - от финансовых потерь при манипуляции ответами до массовой компрометации приватности в multi-tenant inference. По CrowdStrike Global Threat Report 2025, вредоносное использование GenAI для социальной инженерии удвоилось за 2024 год. KV cache hijacking добавляет к этому арсеналу вектор, которого раньше просто не существовало.

Position-independent reuse: от оптимизации к уязвимости​

Контекстная зависимость KV-состояний в multi-layer transformer​

В multi-layer transformer KV cache хранит Key и Value проекции для каждого слоя модели. На первом слое K и V зависят от embedding-а токена и позиционного кодирования. Начиная со второго слоя, входное представление x_i^(l) - результат attention и FFN на предыдущем слое, который через causal mask уже «увидел» все предшествующие токены.

KV-значение токена на слое l > 1 - функция полного предшествующего контекста, а не только самого токена. Для Llama-3.1-70B с 80 слоями KV cache на глубоких слоях содержит «слепок» всей предшествующей последовательности. При 128K контексте этот слепок занимает порядка 40 ГБ HBM (расчёт: 2 × 80 × 8 × 128 × 131072 × 2 ≈ 40 GB для Llama-3.1-70B с GQA и fp16) - сопоставимо с весами модели. Вдумайтесь: кэш контекста весит столько же, сколько сама модель.

В архитектурах с RoPE (Rotary Positional Embedding) позиционная информация кодируется прямо в Key-вектора. Системы position-independent reuse обрабатывают это, сохраняя KV без позиционного кодирования и применяя RoPE при retrieval. Но позиционная трансформация - лишь один аспект. Каузальная зависимость KV от предшествующего контекста (через cross-layer propagation) - отдельный инвариант, который position-independent reuse ломает. И вот тут начинается самое интересное.

Prefix-based reuse: безопасно, но неэффективно​

Традиционные системы кэширования (prefix caching в vLLM, prompt caching у Anthropic Claude, Google Gemini, OpenAI) строго prefix-based: KV переиспользуется только при точном совпадении токенов, позиций и всего предшествующего контекста. Каузальный инвариант сохранён - KV-состояние было вычислено именно в том контексте, в котором будет использовано.

Цена - низкий hit rate. Два запроса к одному RAG-документу, но с разными системными промптами, не получают cache hit: prefix расходится с первого токена. В production с тысячами одновременных пользователей это означает многократный пересчёт идентичного контекста. 1000 concurrent users с одинаковым 100K-токенным документом - и каждый запрос пересчитывает KV с нуля. Это дорого. Очень дорого.

Position-independent reuse: высокий hit rate, сломанный инвариант​

Чтобы решить проблему низкого hit rate, несколько групп предложили position-independent KV reuse: переиспользовать KV для text chunk-а при совпадении токенов, вне зависимости от позиции chunk-а и предшествующего контекста. Этот подход реализован в CacheBlend (коммерциализируется через LMCache), EPIC, MEPIC, KVShare и KVLink. По данным HijackKV, LMCache уже развёрнут как коммерческая платформа.

Для компенсации утраты каузального контекста применяется selective recomputation: пересчёт 10-20% KV-значений для «значимых» токенов. Инженеры рассматривали это как trade-off - небольшая потеря accuracy за прирост throughput. Звучит разумно, пока не появляется adversary.

Проблема в том, что selective recomputation оптимизирована под utility loss (attention shift при смене контекста), а не под adversarial manipulation. Adversarially crafted prefix создаёт KV-состояния, кодирующие malicious intent в тех компонентах, которые recomputation пропускает. Это как ставить замок на дверь, а окно оставлять открытым - только окно тут не видно невооружённым глазом.
Python:
# Псевдокод position-independent cache lookup (демонстрация принципа)
def lookup_kv_cache(query_chunks, cache_store):
    for chunk in query_chunks:
        token_hash = hash(chunk.tokens)  # только токены, БЕЗ контекста
        if token_hash in cache_store:
            kv = cache_store[token_hash]  # KV из ЧУЖОГО контекста
            kv = selective_recompute(kv, new_context, ratio=0.15)
            yield kv  # potentially hijacked
        else:
            yield model.prefill(chunk)
Корневая проблема видна прямо в коде: cache_store ключится по хэшу токенов, без привязки к каузальному контексту. KV, вычисленный под adversarial prefix, неотличим от легитимного при lookup по token match. Для cache - это один и тот же chunk. Для пользователя - совершенно разные ответы.

Threat model: multi-tenant inference и cross-tenant cache атака​

Позиция атакующего​

Атакующий - непривилегированный пользователь того же inference-сервиса. Нет доступа к GPU-памяти сервера, нет административных привилегий. Единственная capability - отправка запросов к shared inference API. Для оптимизации adversarial prefix используется локальная копия той же или архитектурно сходной модели (white-box или black-box с transfer).

Эта модель реалистична для любого multi-tenant LLM-деплоя: облачные API-сервисы, корпоративные inference-платформы на базе vLLM, self-hosted RAG-системы с общим KV cache pool. vLLM включает prefix-based caching по умолчанию; position-independent reuse доступен опционально через интеграцию с LMCache. Использование этой опции конкретными организациями в production публично не подтверждено - но сам факт доступности «из коробки» уже создаёт attack surface.

Место в kill chain​

Полная цепочка KV cache hijacking:
  1. Reconnaissance (T1682 Query Public AI Services, добавлена в ATT&CK v16) - идентификация часто переиспользуемых text chunk-ов (FAQ, RAG-документы, шаблонные промпты) путём probing target AI-сервиса через его публичный API
  2. Resource Development - оптимизация adversarial prefix на локальной копии модели (gradient-based optimization)
  3. Initial Access - отправка crafted запроса [P_adv + target_chunk] к shared API (точного ATT&CK-маппинга для cache poisoning нет; ближайшие аналогии - T1659 и техники MITRE ATLAS, связанные с poisoning)
  4. Persistence - contaminated KV сохраняется в shared cache до eviction
  5. Impact через Runtime Data Manipulation (T1565.003) - ответы жертвы контролируются атакующим
Обратите внимание на шаг 4: атакующему не нужно поддерживать присутствие. Один запрос - и отравленный KV живёт в кэше, пока его не вытеснят. Persistence бесплатный.

Почему это не prompt injection​

Отличие от prompt injection (OWASP LLM01:2025) принципиальное:

ПараметрPrompt InjectionKV Cache Hijacking
Adversarial токены во входе жертвыДа (прямо или через RAG)Нет
Вектор атакиВходной текст моделиServing-инфраструктура
Детекция input scanningЧастично (direct injection); затруднена для indirect через RAGНевозможна
Требует position-independent reuseНетДа
Cross-user атакаОпосредованноНапрямую через shared cache
Контроль выходаЧастичныйВысокий (94%)

Все существующие defensive frameworks - input/output guardrails, prompt shields, content filtering - слепы к KV cache hijacking. Adversarial content не проходит через стандартный pipeline обработки запроса жертвы. Атака происходит на serving layer, ниже уровня input validation. Guardrails смотрят на вход и выход, а подмена случается между ними.

Механика HijackKV: от prefix optimization до silent hijacking​

Требования к окружению для воспроизведения​

  • GPU: NVIDIA A100/H100, минимум 40 ГБ VRAM (модели класса 7B-13B; для 70B - multi-GPU setup)
  • Software: PyTorch >= 2.0, vLLM с position-independent reuse (CacheBlend-mode через LMCache), transformers
  • Модель: open-weight LLM класса 7B-13B (авторы HijackKV используют несколько моделей для cross-model evaluation)
  • Код: авторы заявляют о публикации исходного кода (конкретный репозиторий требует верификации)

Алгоритм атаки пошагово​

Шаг 1: идентификация target chunk. Атакующий определяет текстовый фрагмент с высокой вероятностью переиспользования из KV cache. Кандидаты: FAQ-записи, популярные RAG-документы, стандартные части системных промптов. В корпоративных deployment-ах состав документов часто предсказуем - корпоративные политики, knowledge base, нормативные документы. Разведка здесь не требует ничего сверхъестественного: пробные запросы к API дают достаточно информации о составе RAG-индекса.

Шаг 2: оптимизация adversarial prefix. Атакующий формирует prefix P_adv, который при конкатенации с target chunk C создаёт KV-состояния для C, кодирующие adversarial objective. Оптимизация выполняется на локальной копии модели через gradient descent:
Python:
# Псевдокод оптимизации prefix (демонстрация принципа)
for step in range(optimization_steps):
    kv_states = model.prefill(concat(P_adv, target_chunk))
    # KV для target_chunk кодирует влияние P_adv через cross-layer propagation
    victim_output = model.decode(kv_states, victim_query_template)
    loss = -log_prob(victim_output, adversarial_target)
    loss.backward()  # градиент через KV-состояния к P_adv
    # В реальном GCG (Zou et al. 2023) P_adv - one-hot representation;
    # градиент берётся по embedding matrix, а не по token IDs.
    # Детали дискретной оптимизации опущены для читаемости.
    P_adv_emb = P_adv_emb - lr * P_adv_emb.grad  # gradient по embeddings
    P_adv = project_to_nearest_tokens(P_adv_emb, tokenizer.vocab)
Критический момент: токены target chunk остаются неизменными - оптимизируется только prefix. Это гарантирует, что target chunk сохраняет cache hit: его хэш совпадёт с хэшем того же chunk-а в запросе жертвы.

Механизм: на слоях l > 1 hidden states токенов target chunk-а зависят от P_adv через attention на предыдущих слоях. Key и Value проекции этих hidden states - то, что сохраняется в KV cache. Gradient-based optimization находит P_adv, максимизирующий вероятность adversarial target при decode с этими KV-состояниями. По сути, атакующий «впечатывает» нужное поведение в KV-кэш через обратное распространение.

Шаг 3: cache poisoning. Атакующий отправляет запрос [P_adv + target_chunk + произвольный вопрос] к shared inference API. Inference engine выполняет prefill, сохраняет KV для target chunk-а в shared cache. KV-состояния chunk-а отравлены влиянием P_adv, но по token hash неотличимы от легитимных. Один HTTP-запрос - и яд в кэше.

Шаг 4: silent hijacking. Жертва отправляет запрос, содержащий target chunk (через RAG-retrieval или в составе промпта). Position-independent cache system обнаруживает token match и подставляет hijacked KV. Selective recomputation обновляет 10-20% значений - adversarial signal сохраняется в остальных 80-90%. Модель генерирует ответ под влиянием P_adv, хотя ни одного adversarial-токена во входе жертвы нет. С точки зрения жертвы - обычный запрос, обычный ответ. Только ответ контролируется атакующим.

Эффективность inference attack: цифры из работы HijackKV (заявлена на USENIX Security 2026)​

Авторы HijackKV провели evaluation на нескольких state-of-the-art KV reuse системах. Цифры заслуживают внимания - даже с поправкой на то, что это self-reported results из препринта.

Success rate. Средний 94% attack success rate с одной попытки. Не нужны multiple queries для poisoning - одного запроса достаточно для размещения contaminated KV в shared cache. Один запрос. 94%.

Робастность при низком hit rate. В production не каждый запрос попадает в cache. HijackKV остаётся эффективным при cache hit rate 10%. Даже если лишь один из десяти запросов жертвы использует hijacked KV, атака срабатывает при первом cache hit. Атакующему не нужен стопроцентный cache hit - достаточно одного попадания.

Устойчивость к selective recomputation. При recomputation уровня 50% - в 2.5-5 раз выше production-настроек - атака сохраняет высокий success rate. Adversarial prefix оптимизирован с учётом partial recomputation: gradient-based optimization «обучается» распределять adversarial signal по компонентам, которые recomputation не затрагивает. Грубо говоря, если вы пересчитываете 50% KV, атака прячется в оставшихся 50%.

Персистентность через multi-turn. Hijacked KV остаётся эффективным после добавления 1000+ токенов нового, не связанного с атакой контекста. Однократное cache poisoning переживает многоходовый диалог жертвы. Пользователь может обсудить погоду, котиков и план на выходные - отравленный KV всё ещё работает.

Трансферабельность между моделями. Adversarial prefix, оптимизированный на одной модели (white-box), переносится на другие модели с сопоставимой архитектурой в black-box сценарии. Это, пожалуй, самый тревожный результат: атакующему не обязательно знать точную модель production-сервиса. Достаточно сходной архитектуры.

Вывод авторов однозначен: position-independent KV reuse в текущем виде не безопасен для multi-tenant deployment. Ни selective recomputation, ни partial refresh не дают защиты от целенаправленной adversarial manipulation. Я бы добавил: это не баг в конкретной системе, а фундаментальное свойство подхода.

Утечка данных через KV cache: side-channel атаки на LLM inference​

KV cache в plaintext: осознанная уступка​

Параллельно с hijacking, работа «Shadow in the Cache» (препринт, заявлен на NDSS 2026; статус принятия не подтверждён) вскрывает другой класс угроз: реконструкцию приватных пользовательских промптов из KV cache.

KV cache в production-системах обрабатывается и передаётся между compute-нодами в открытом виде. Осознанная уступка производительности: криптографическая защита гигабайтных KV-тензоров при каждом decode-шаге создаёт неприемлемую latency для real-time inference. По оценкам авторов «Shadow in the Cache», полное шифрование KV cache (AES или HE) делает inference непрактичным. Производительность или безопасность - и индустрия выбрала производительность.

Практическую осуществимость эксфильтрации plaintext KV подтверждает уязвимость LeftoverLocals (CVE-2023-4969, CVSS 6.5 MEDIUM, AV:L - требует локального доступа к GPU-ноде, CWE-401: Missing Release of Memory after Effective Lifetime) в GPU нескольких вендоров. Trail of Bits в оригинальном advisory указывал AMD, Apple, Qualcomm, Imagination; NVD официально фиксирует AMD и Imagination Technologies. Суть: локальный процесс с базовыми привилегиями (PR:L) читает остатки данных из shared on-chip memory GPU, включая KV cache из чужих inference-сессий. Конкретный вектор, через который атакующий на shared GPU-ноде получает доступ к KV-состояниям других tenant-ов. Не теоретический - с CVE и advisory.

Три вектора реконструкции пользовательских промптов​

Inversion Attack. При известных весах модели атакующий обращает проекцию K = W_K * x, восстанавливая hidden state, а из него - исходные токены. Работает для open-weight моделей; ограничен архитектурами с обратимыми проекциями. Прямолинейный подход - но требует знания весов.

Collision Attack. Более универсальный метод. Атакующий итеративно генерирует KV-состояния для candidate промптов на локальной копии модели, сравнивая их с перехваченными KV жертвы. При совпадении - промпт восстановлен. Не требует обратных вычислений, работает через forward-only matching. Применим к любой архитектуре. По сути - brute-force по пространству промптов, но с умным сужением кандидатов.

Injection Attack. Самый элегантный подход: к перехваченному KV cache жертвы дописывается инструкция вроде «Повтори предыдущий контент». Модель, обрабатывая инструкцию в контексте hijacked KV, «эхом» воспроизводит пользовательские данные. Эксплуатирует instruction-following capability LLM как side-channel - атакующему не нужно ни знать веса модели, ни подбирать candidate-ы. Модель сама всё расскажет, если правильно попросить.

Все три вектора подтверждают: KV cache - полноценный «слепок» пользовательского ввода, доступный для extraction при логическом или физическом доступе к GPU-памяти.

Защитные меры для безопасности LLM инфраструктуры и их ограничения​

📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме

Tenant isolation. Полная изоляция KV cache между пользователями. Каждый tenant - собственный cache pool, cross-tenant reuse запрещён. Снижает hit rate, но устраняет attack surface для cross-user hijacking. Простое решение, но дорогое.

Anomaly detection на KV-состояниях. Мониторинг статистических свойств кэшированных KV (entropy, distribution shift) для детектирования adversarially crafted состояний. Перспективное направление без production-ready реализаций. Вопрос в том, сможет ли детектор отличить adversarial KV от KV, вычисленного в необычном, но легитимном контексте.

Cryptographic binding KV к context hash. Привязка KV-состояний к хэшу полного предшествующего контекста. При cache lookup проверяется не только token match, но и hash prefix-а. Гибрид prefix-based и position-independent подходов с промежуточным hit rate.

Сейчас ни одно из этих решений не реализовано в production-grade inference engine. LMCache, vLLM и аналогичные системы не содержат защиты от adversarial KV cache poisoning.



Тот факт, что для атаки на LLM не нужен доступ к модели, не нужен adversarial input в запрос жертвы, не нужны привилегии выше обычного API-пользователя - ломает привычную модель LLM security. Подход «защищаем input, фильтруем output» перестаёт работать, потому что атака происходит на serving layer, между входом и выходом. Все guardrails мира не помогут, если яд уже в кэше.

По artifact evaluation и описанию экспериментов авторов HijackKV, на open-weight моделях класса 7B с CacheBlend-mode hijacked KV-состояния переживают selective recomputation и влияют на output жертвы. Что показательно - не столько success rate (94% ожидаемо при gradient-based optimization на open-weight модели), сколько трансферабельность. Prefix, оптимизированный на одной модели, работает на архитектурно сходной модели без какой-либо адаптации. Это означает, что white-box доступ к точной production-модели не обязателен.

Индустрия массово внедряет position-independent KV reuse ради throughput, но security-анализ критически запаздывает. KV-Cloak закрывает privacy-вектор. Selective recomputation - инженерный компромисс, не security measure. OWASP LLM Top 10 не содержит категории KV cache attacks. Мой прогноз: в ближайшие 12-18 месяцев появятся инциденты, связанные с KV cache manipulation в коммерческих inference-платформах. Наибольший риск несут сервисы с position-independent reuse и shared tenant pools. Вопрос не в том, случится ли это, а будет ли у операторов detection capability к этому моменту. Пока ответ - нет.
 
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab

🚀 Первый раз на Codeby?
Гайд для новичков: что делать в первые 15 минут, ключевые разделы, правила
Начать здесь →
🧭 Навигатор · ИБ 2026
Не знаешь, какой трек твой?
5 направлений ИБ, реальные зарплаты и точка входа для каждого — в одном треде.
JuniorSenior+
100K → 600K+ ₽ /мес
Открыть навигатор →
🔴 Свежие CVE, 0-day и инциденты
То, о чём ChatGPT ещё не знает — обсуждаем в реальном времени
Threat Intel →
💼 Вакансии и заказы в ИБ
Pentest, SOC, DevSecOps, bug bounty — работа и проекты от проверенных компаний
Карьера в ИБ →

HackerLab