- moduleForPath: quik-mnp (QUIK, обмен с DEPO, ручной поиск в DEPO), quik-export, web-cabinet (bj-lk);
- в настройках каждый модуль по своему признаку (раньше Экспорт QUIK и Кабинет шли общим условием);
- разделы Fancy/QUIK открыты при лицензии QUIK МНП без пароля перспективных модулей.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
- L2b: CSRF для изменяющих запросов админки — проверка Origin (иначе Referer)
против Host на всех не-GET под /admin (sameOriginRequest в authMiddleware);
за loopback-прокси учитывается X-Forwarded-Host. Второй слой поверх
SameSite=Lax, без правки десятков форм настроек.
- L3: /back-to-admin меняет состояние — только POST + csrfOK (форма уже с токеном,
проверки в обработчике не было).
- L6: EXEC процедуры DEPO по имени из настроек — через execProc с проверкой
идентификатора (sqlident.go, см. коммит строчных событий).
- L7: сессия просмотра (impersonate) снимает IsAdmin цели — сотрудник не действует
от имени другого администратора; свои действия — из своей сессии.
- L8: bootstrap администратора кабинета под замком lkBootstrapMu — два
параллельных запроса не заведут двух админов (TOCTOU).
- L10: allowlist перезапуска служб не пропускает пустое имя.
- L11: ретранслятор — лимит тела проверяется по Content-Length до чтения и
чтение ограничено RELAY_MAX_BODY+1.
- M4: .htaccess дополнительно запрещает *.lock (код установки), если данные
оказались в веб-корне; nginx-запрет /data уже в README.
L4 (привязка сессии к сети по умолчанию выкл.) и L9 (косметическая cookie
bj_lk_admin, арбитр — ядро) оставлены как есть, отмечены в отчёте.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q4YVo4UMopqT5DzicqpPjL
Продолжение исправлений по security-аудиту.
M1 (MEDIUM) — установщик PHP-ретранслятора был открыт без входа: до создания
админа атакующий из интернета мог завести админа кабинета или подменить адрес
ядра/ключ. Добавлен «код установки»: генерируется в файл install.lock рядом с
данными (вне веб-корня), прочитать его можно только с доступом к файловой
системе (FTP/файловый менеджер) — то есть владельцу сервера. Шаги connect и
admin (включая «пропустить») требуют верный код. Регексп loopback заякорен
(`http://127.0.0.1.attacker.com` больше не проходит как loopback). Код удаляется
по завершении установки. Проверено встроенным php-сервером.
M3 (MEDIUM) — распаковка 7z в мастере ключа (ExtractISO) сохраняла пути из
архива → запись «../…» вышла бы за каталог. Перед распаковкой архив
просматривается (7z l -slt, без записи); при абсолютном пути или выходе за
корень распаковка отклоняется. Тест TestUnsafeArchivePath.
L1 — target_device не проверялся перед root mount: значение не из списка
съёмных теперь отклоняется (иначе root смонтировал бы произвольный девайс).
L5 — likeEscape в ручном поиске DEPO (manualDepoSearch): метасимволы LIKE от
пользователя больше не «расползаются» по базе.
L2a — кука сессии ядра получает Secure и за TLS-терминирующим прокси на loopback
(reqIsHTTPS учитывает X-Forwarded-Proto только от loopback).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q4YVo4UMopqT5DzicqpPjL
По результатам security-аудита (docs, run-1). Три верифицированные находки.
H1 (HIGH) — fail-open аутентификация. loadUsers() при ошибке чтения/парсинга
users.json молча возвращал пустой стор → authOpen() считал это первичной
настройкой → после удаления first-run файла весь /admin отдавался без входа.
Теперь: постоянный маркер configured (пишется при создании первого админа и
бэкфиллится при загрузке валидного стора); authOpen() открыт только на реально
свежей системе; при пустом/битом сторе на настроенной системе — 503 и блокировка
до восстановления файла (authLockedOut). Тест TestAuthFailClosed (4 сценария).
H2 (HIGH) — интернет-слой доверял клиентскому X-Forwarded-For/X-Real-IP, что
позволяло обойти лимит входа по IP и травить аудит. Теперь заголовкам доверяем
только от доверенного прокси (по умолчанию loopback; расширяется
BJ_TRUSTED_PROXIES), из XFF берём правый элемент. Исправлено и в Go-модуле
(modules/lk/security.go), и в PHP-ретрансляторе. Тесты TestClientIPTrust (Go) и
прогон логики PHP.
M2 (MEDIUM) — POST /order (поручение на списание бумаг) не проверял CSRF, в
отличие от /login и /impersonate. Добавлен csrfOK (форма уже несла токен).
Тест TestOrderCSRF.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q4YVo4UMopqT5DzicqpPjL
Пока лицензия разрешает режим разработки, в шапке висит баннер; нажатие выключает режим визуально для этого пользователя и включает обратно. В шаблонах .DevMode заменён на devOn.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q4YVo4UMopqT5DzicqpPjL
- cmd/bj-installer (вместо веб-мастера): проверка Debian 13 / Astra, пакеты, пользователь и
каталоги, активация лицензии ключом продукта, PostgreSQL и миграции m2m_core, компоненты
по лицензии с проверкой подписи, root-скрипты и службы, одноразовый код и итоговый экран
с адресом http://<сервер>:8080/first-run; проверка в песочнице (--steps, --root)
- bj: /first-run — пока нет пользователей и установщик оставил код, по коду создаётся
первый администратор (прежние установки без файла работают как раньше)
- internal/release/install.go — общая установка компонентов (bj-component-install и
установщик); bj-component-install стал компонентом ядра
- открытые ключи вынесены в internal/license и internal/release; миграции и файлы
развёртывания встроены (migrations/embed.go, deploy/embed.go); unit bj-server исправлен
- scripts/build-release.sh: сборка с версиями, подпись, публикация на сервер обновлений
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- bj_exchange и «кран» Fancy убраны: данные модуля ЛК в PostgreSQL (схема lk)
- трансферные таблицы FTV_M2M: создание при установке, события, справочник участников
- сверка с DEPO: счёт, ФИО, дата рождения, ИИС по договору, квал-инвестор из опции DEPO
- боевой ЛК ЕСИА Финанс при тестовом ИШ: журнал, отказ через DEPO, статусы в ЛК
- онлайн-лицензирование в bj, план тестирования M2M для контрагента (интерактивный HTML)
- модули QUIK МНП, экспорт QUIK, НПР/УДС; документы и тестовые материалы
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>