← Back

Поликопи — Полный аудит проекта (2026-06-24)

Аудит: Rust API (агент, ssh Malaysia) + React-фронт (агент, локально) + money-path ядро (Бендер: демон/executor/deposit-watch, ssh Malaysia). Read-only, ничего не менялось. Прод: poly-dev.szhub.space / Malaysia 72.62.247.119.

🔴 HIGH (исправлять в первую очередь)

H1 — /api/polymarket/sign открыт без auth (Rust, routes.rs:927-934, route 3718)

Любой из интернета (через nginx location /) POST-ит {method,path,body} → получает валидную builder-HMAC-подпись (POLYMARKET_BUILDER_SECRET) + возвращает builder apiKey+passphrase. Позволяет форжить authed builder-вызовы под нашей builder-identity. Самая эксплуатируемая дыра. Фикс: gate по SIWE/Privy-сессии или service-token; не возвращать key/passphrase; whitelist допустимых path/method.

H2 — service_ok timing/naive == на money-эндпоинтах демона (Rust, copytrade.rs:306-310)

/api/copy/{market-resolution,market-tokens,wallets,positions GET+POST} используют наивный == (timing-оракул на секрете, который гейтит запись позиций/resolution-истину). Рядом уже есть hardened service_token_ok (constant-time, строки 37-44), используемый /active и /pnl. Фикс: 1 строка — пустить service_ok через service_token_ok.

H3 — copy-config не валидируется на клиенте, сырьём уходит на бэкенд (Front, CopyConfigModal + useCopySubscriptions.ts:90)

min/max у NumInput — только HTML-атрибуты, не enforce. Юзер вводит allocValue/maxPerTrade/maxExposure/drawdownStop любым значением (999999, negatives через spinner-bypass) → PUT сырым. Демон это потребляет (sizing позиций). Фикс: clamp в set()/на сохранении (allocValue% ≤100 & >0; $-поля ≥0 & ≤ разумный cap; drawdownStop 0-100) + серверная валидация (не доверять клиенту). Сейчас клампятся только fadeMin/fadeMax.

🟠 MED

M1 — derive-key/create-key возвращают CLOB secret наружу, без auth (Rust, routes.rs:928-1048)

Публичные. Эхо secret/passphrase в JSON (комментарий говорит "secret never needs to leave backend" — но он уходит, строки 992/1046). Cross-user poisoning смягчён (CLOB валидирует подпись над address). Нет rate-limit → бесплатный прокси к CLOB derive. Фикс: не возвращать secret/passphrase (только apiKey для отображения); + auth-gate.

M2 — NaN-паника замораживает market-sync (Rust, gamma.rs:532)

.partial_cmp(...).unwrap() паникует на NaN из внешнего Gamma API → spawned cron-таск умирает → 2-мин синк цен/resolution встаёт навсегда (стейл-данные демону) до рестарта. Фикс: unwrap_or(Ordering::Equal) (паттерн уже есть в copytrade.rs:483).

M3 — priceMin/priceMax не упорядочены (Front, CopyConfigModal:209-214)

Нет guard priceMin ≤ priceMax. Юзер ставит min=60,max=5 → инвертированная полоса = "копировать ничего" молча/undefined. Фикс: enforce порядок на сохранении + сообщение.

🟡 LOW / заметки

✅ Чисто (проверено)

Приоритет действий

  1. H1 (sign-oracle) — remote, без кредов, самое опасное
  2. H2 (service_ok) — 1 строка, лёгкая победа
  3. H3 (валидация copy-config) — money-path конфиг
  4. M1 (secret echo) → M2 (NaN panic) → M3 (price ordering)

✅ СТАТУС ФИКСОВ (2026-06-24, ветка redesign-nav, всё на GitHub)

Сознательно НЕ сделано (с обоснованием)

Бэкапы всех изменённых файлов → ~/openclaw-backups/*.pre-{h1,h2,h3,m1,m2}-2026-06-24 на Malaysia.

📜 Git History

d1e69e6poli 2026-06-24: deposit auto-credit + Chunk6 + full audit (5 fixes)10 days ago
Show last diff
Loading...