На Хабре вышла статья о краже цепочек рассуждений у закрытых моделей. Схема атаки: берётся зашифрованный блок сильной модели, подкладывается слабой модели того же провайдера, и та пересказывает содержимое дословно. В результате можно прочитать чужие мысли, включая случайно попавшие туда пароли и ключи. Атака описана в препринте и, судя по всему, работает.

Однако автор материала, разбиравший signature Claude по байтам ещё прошлой зимой, пришёл к выводу, что конверт вокруг рассуждения совсем не opaque. Это обычный protobuf, который читается вообще без ключей. Зашифрован внутри ровно один вложенный кусок — сам текст мысли. Всё остальное лежит открыто.

ПолеТипДлина (байт)Содержимое
field 1varint1версия схемы (16)
field 2len-delimited312вложенное сообщение
field 3varint1флаг (1)
field 1 (внутри)len-delimited135заголовок
field 2 (внутри)len-delimited12nonce
field 3 (внутри)len-delimited12nonce / aad
field 4 (внутри)len-delimited48MAC / подпись
field 5 (внутри)len-delimited94шифротекст

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

Заголовок блока содержит открытым текстом id модели (например, claude-opus-5) и UUID организации из ~/.claude.json.

Разбор одной подписи. Автор открыл свою рабочую сессию Claude Code (~/.claude/projects/…/*.jsonl), попросил модель коротко подумать над пустяковым шагом и выдернул из истории первый попавшийся блок thinking. В JSON он выглядит так: поле thinking пустое, но signature на 428 символов живая. Это означает, что модель думала, но текст мысли не сохраняется в истории.

Сама signature — это base64-строка, которая декодируется в 319 байт бинарных данных. Первые байты (08 02 12 b8 02 …) указывают на protobuf-сообщение. Внешний конверт содержит одно вложенное сообщение на 312 байт в поле 2, плюс два скалярных флажка по краям. Внутри поля 2 — заголовок (135 байт), nonce (12 байт), ещё один nonce или AAD (12 байт), MAC/подпись (48 байт) и шифротекст (94 байта). Три поля посередине имеют константную длину у всех полутора тысяч блоков, что указывает на классический расклад nonce + nonce_or_aad + tag/signature.

Заголовок, который никто не прятал. Разбор 135 байт заголовка тем же protobuf-способом, без единого ключа, даёт: версия схемы (16), тип блока (thinking), auth_blob (64 случайных байта), id модели открытым текстом (claude-opus-5), флаг (1), тип блока строкой (thinking) и UUID длиной 36 символов. Этот UUID — oauthAccount.organizationUuid из ~/.claude.json, то есть идентификатор организации, от имени которой работает аккаунт. В разных сессиях он один и тот же на протяжении месяца и меняется только при смене аккаунта.

Таким образом, каждый зашифрованный блок рассуждений таскает внутри заголовка, открытым текстом, id модели и id вашей организации. Это не абстрактный «технический идентификатор», а реальный ключ, по которому можно связать пользователя с его организацией в Anthropic. Лежит он ровно там, куда никто не смотрел, потому что signature все считали непрозрачной.

Практическое значение. Для обычного пользователя это означает, что приватность thinking-блоков не абсолютна: метаданные (модель, организация, UUID) доступны без расшифровки. Для исследователей безопасности — что атака на кражу цепочек рассуждений может быть дополнена анализом заголовков, которые раскрывают больше, чем предполагалось. Для разработчиков, использующих Claude Code, — что стоит быть осторожными с тем, что попадает в контекст, так как даже «зашифрованные» блоки могут содержать чувствительные метаданные.