montana/Русский/Совет/OpenAI/аудит_сетевого_уровня_08.01.2026_00:00.md

147 lines
10 KiB
Markdown
Raw Permalink Normal View History

# Security Audit: Network Layer (net/)
**Модель:** GPT-5.2
**Компания:** OpenAI
**Дата:** 08.01.2026 00:00 UTC
---
## 1. Понимание архитектуры
Montana — это ACP (Atemporal Coordinate Presence), где «вес» и консенсус привязаны не к вычислительным ресурсам, а к **реальному времени присутствия** (подписи принимаются только в текущем τ₂/τ₁). Сетевой слой в этой модели — критичен для **liveness** (доставка подписей/tx в окно τ₂ и grace period) и для корректного bootstrap (чтобы новый узел не принял ложное представление о сети).
Ключевые следствия для безопасности сети:
- **Атаки на liveness** (eclipse, деградация gossip, перегрузка) важнее «переписывания истории».
- Консенсусная безопасность в основном держится на криптографии и «время = ресурс», но **сетевой слой** должен обеспечивать ограничение ресурсов (CPU/RAM/FD) и разнообразие соединений.
- Bootstrap и time-consensus должны быть устойчивы к изоляции и к «poisoning» адресной базы.
---
## 2. Изученные файлы
| Файл | LOC | Ключевые компоненты |
|------|-----|---------------------|
| `Montana ACP/montana/src/net/mod.rs` | - | ре-экспорты компонентов net/ |
| `Montana ACP/montana/src/net/types.rs` | - | константы лимитов, типы сообщений/состояний |
| `Montana ACP/montana/src/net/message.rs` | - | wire message enum, max_size per command |
| `Montana ACP/montana/src/net/protocol.rs` | - | main P2P loop, handshake, relay/inv, size checks |
| `Montana ACP/montana/src/net/connection.rs` | - | лимиты соединений, per-ip/netgroup, bans, retry |
| `Montana ACP/montana/src/net/peer.rs` | - | состояние peer, bounded known_inv, rate limits, flow control |
| `Montana ACP/montana/src/net/addrman.rs` | - | addrman с бакетами, anti-poisoning, persistence size cap |
| `Montana ACP/montana/src/net/inventory.rs` | - | relay cache, bounded sets, per-peer request cap |
| `Montana ACP/montana/src/net/rate_limit.rs` | - | token buckets + global adaptive subnet limiter |
| `Montana ACP/montana/src/net/eviction.rs` | - | многоуровневая защита слотов + eviction |
| `Montana ACP/montana/src/net/feeler.rs` | - | feeler соединения + addr response cache |
| `Montana ACP/montana/src/net/discouraged.rs` | - | rolling bloom discouraged set |
| `Montana ACP/montana/src/net/noise.rs` | - | Noise XX + ML-KEM-768 гибрид |
| `Montana ACP/montana/src/net/encrypted.rs` | - | EncryptedStream поверх Noise |
| `Montana ACP/montana/src/net/dns.rs` | - | DNS seeds + fallback IPs |
| `Montana ACP/montana/src/net/hardcoded_identity.rs` | - | hardcoded nodes: IP→ML-DSA-65 pubkey |
| `Montana ACP/montana/src/net/bootstrap.rs` | - | bootstrap verification model |
| `Montana ACP/montana/src/net/verification.rs` | - | pre-network verification client |
| `Montana ACP/montana/src/net/subnet.rs` | - | subnet reputation tracking |
| `Montana ACP/montana/src/net/sync.rs` | - | headers-first sync, orphan pool, late signatures |
---
## 3. Attack Surface
- **Inbound TCP connections**: `protocol.rs` listener_loop, handshake (Noise) и дальнейший приём сообщений.
- **Wire message parsing**: magic/length/checksum + bincode decode.
- **Inventory/gossip**: `Inv/GetData` и relay.
- **Addr/AddrMan**: приём адресов, адресная база, DNS seeds/fallback.
- **Bootstrap verification** (до старта сети): `verification.rs` + `bootstrap.rs` + hardcoded identity.
- **Global subnet limiter**: контроль на входе/выходе (Erebus).
---
## 4. Найденные уязвимости
### [HIGH] Несогласованные лимиты размера сообщений (DoS/функциональная деградация, расхождение спецификации)
**Файл:** `Montana ACP/montana/src/net/types.rs:108-115` + `Montana ACP/montana/src/net/protocol.rs:1243-1276` + `Montana ACP/montana/src/net/verification.rs:696-737`
**Уязвимый код:**
- В `types.rs` явно указано: общий лимит сообщения `MESSAGE_SIZE_LIMIT = 2MB`, `inv` до ~1.8MB.
- В `protocol.rs` ранняя проверка читает `len` и сравнивает **с `MAX_TX_SIZE` (1MB)** до того, как определён тип сообщения:
- `if len > MAX_TX_SIZE { ... }`
- В `verification.rs` (pre-network bootstrap client) та же логика: `if length > MAX_TX_SIZE { ... }`.
**Вектор атаки:**
1. Атакующий (или просто честный peer) отправляет легитимный `inv` близкий к `MAX_INV_MSG_SIZE` (~1.8MB).
2. Узел отвергает кадр на раннем этапе, т.к. 1.8MB > 1MB.
3. Результат — систематический отказ от части протокола (и потенциальная деградация синхронизации/relay) при нормальном использовании.
**Импакт:**
- **Protocol mismatch / self-DoS:** узел не способен принимать сообщения, которые сам протокол допускает.
- **Повышенная вероятность деградации gossip/sync:** при большом инвентаре, особенно на старте/в bursts.
**Сложность:** низкая (любой peer может послать большой `inv`, без обхода криптографии).
**PoC сценарий:**
- Не привожу эксплуатационные шаги. Достаточно сконструировать `Inv` на ~50k items в рамках `MAX_INV_SIZE`.
**Рекомендации:**
- В ранней проверке использовать `MESSAGE_SIZE_LIMIT`, а не `MAX_TX_SIZE`.
- После десериализации дополнительно проверять per-command лимит через `Message::max_size_for_command()` (это уже делается). Аналогично — в `verification.rs`.
---
### [MEDIUM] Неконсистентные комментарии/оценки памяти в `sync.rs` (риск неверного hardening-а)
**Файл:** `Montana ACP/montana/src/net/sync.rs:13-23` и `Montana ACP/montana/src/net/types.rs:133-136`
**Описание:**
- `sync.rs` утверждает: «Each orphan is up to 4MB», что даёт 400MB worst case.
- `types.rs` фиксирует `MAX_SLICE_SIZE = 8KB` и рассчитывает orphan pool как 800KB.
**Импакт:**
- Это не прямая эксплуатационная уязвимость, но **опасный сигнал**: либо лимит реально где-то выше, либо документация/комментарии неверны. В обоих случаях можно ошибиться в настройках и пропустить DoS риск.
**Рекомендации:**
- Синхронизировать комментарии и реальные лимиты.
- Добавить unit test/assert, что wire decoder + `Message::max_size_for_command("slice")` реально ограничивает slice до `MAX_SLICE_SIZE`.
---
### [HIGH] Bootstrap hardcoded trust превращается в SPOF (availability)
**Файл:** `Montana ACP/montana/src/net/hardcoded_identity.rs:40-66`
**Уязвимость:**
- В mainnet/testnet определён фактически **1 hardcoded node**.
- Модель bootstrap/verification требует 75% ответов hardcoded. При 1 узле это означает: если он недоступен, bootstrap **всегда падает**.
**Импакт:**
- Целенаправленный DoS (или просто outage) одного адреса блокирует новые подключения/рестарты узлов.
**Сложность:** низкая для DoS по доступности.
**Рекомендации:**
- Увеличить набор hardcoded узлов (5+ минимум, 10+ лучше) и гео/ASN diversity.
- Подумать о fallback режиме (например: если hardcoded недоступны, но сеть уже синхронизирована локально — позволять стартовать с повышенными warningами, либо использовать pinned checkpoints).
---
## 5. Атаки, которые НЕ работают
- **«Подделать presence» через сеть**: не работает без подделки ML-DSA-65 или без возможности ретроактивно вставить подпись в закрытый τ₂ (привязка prev_slice_hash и окно времени).
- **MITM чтение/подмена трафика**: при корректной реализации Noise XX + hybrid ключей пассивная прослушка/подмена контента должна быть затруднена; остаётся DoS по доступности.
---
## 6. Рекомендации
- Привести ранние size-checks в `protocol.rs` и `verification.rs` к единому правилу:
- первичный лимит: `MESSAGE_SIZE_LIMIT`.
- вторичный лимит: per-command `Message::max_size_for_command()`.
- Согласовать лимиты и комментарии в `sync.rs`/`types.rs`, добавить тесты на реальные лимиты.
- Срочно расширить пул hardcoded узлов и обеспечить разнообразие.
---
## 7. Вердикт
[X] HIGH — есть серьёзные уязвимости