fix(auth): закрыть обход JWT через закодированные URL
This commit is contained in:
1 parent
727e35f985
commit
7d86af7e8b
19 files changed
+1656
-23
No files matched your search
@@ -1,6 +1,6 @@
|
||||
# UX/UI: протокол внешней приёмки 12.5
|
||||
|
||||
Актуальное продолжение 2026-10-13: блок 210 завершён. GRE создаётся с default keepalive 10s,10; минутные значения читаются в секундах, PATCH другого поля сохраняет native timer. Валидатор каталога IPsec исправлен для Filters/карты/диагностики. Пройдены SQL/API14, E2E13 и live GRE/Filters UI4; собственные интерфейсы удалены. Backend/frontend ux-gre210, source475/527 и compiled1048 совпали. Срочный следующий блок 211 — auth/RBAC для закодированных URL; baseline анонимного обхода подтверждён. Этап 12.5 открыт.
|
||||
Актуальное продолжение 2026-10-13: блок 211 завершён. Закрыт анонимный обход JWT и section RBAC через encoded URL: проверяется маршрут Fastify, HEAD наследует GET policy, OSPF parameter routes сохраняют права. Пройдены auth42, production SQL/API29 и live26; тестовые DB/role/users удалены. Backend ux-auth211/source477/compiled1048, frontend ux-gre210. Следующий212 — совместимость GRE FastPath/PSK и шаблон экспорта недопустимого keepalive. Этап12.5 открыт.
|
||||
|
||||
IPsec78: реальный PSK responder established, mode-config198.18.78.10 и online=true подтверждены API; точные собственные объекты удалены. Сертификатный/DN online, late failure и history restore остаются открытыми. [Отчёт](ux-ui/acceptance/ipsec-mode-config-2026-10-09.json), [журнал](ux-ui-progress.md).
|
||||
|
||||
@@ -2556,3 +2556,18 @@ Runtime ux-gre210: backend healthy, source475/527 и compiled1048 matched. На
|
||||
|
||||
Протоколы: [native syntax](ux-ui/acceptance/gre210-native-range-2026-10-13.json), [дополнительный синтаксис](ux-ui/acceptance/gre210-native-range-extra-2026-10-13.json), [SQL/API14](ux-ui/acceptance/gre210-keepalive-result.json), [профили](ux-ui/acceptance/gre210-profile-2026-10-13.json), [E2E13](ux-ui/acceptance/gre210-e2e-2026-10-13.json), [native/UI/cleanup](ux-ui/acceptance/gre210-native-live-2026-10-13.json), [source](ux-ui/acceptance/source210-result.json), [compiled](ux-ui/acceptance/compiled210-result.json), [deployment](ux-ui/acceptance/gre210-deployment-2026-10-13.json).
|
||||
|
||||
|
||||
## 12.5.211 — JWT/RBAC для закодированных URL (2026-10-13)
|
||||
|
||||
Actual baseline: обычный /api/servers без JWT возвращал401, но /%61pi/servers возвращал200 и server rows с непустыми паролями. Fastify распознаёт encoded static segments; middleware сравнивал raw URL и пропускал auth для encoded /api prefix. Для encoded имени раздела можно было также получить fallback dashboard permission. В evidence сохранены только статусы, число строк и boolean наличия пароля; raw body, credentials и JWT не сохранялись и не выводились.
|
||||
|
||||
Общий preHandler и requireAuth теперь используют request.routeOptions.url — фактически выбранный Fastify маршрут. Проверка public auth config/health сохранена; percent decoding не выполняется повторно вручную. Permission mapping OSPF принимает доверенные parameter templates наряду с прежними numeric paths; HEAD получает те же read permissions, что GET. Политики ролей и AUTH_REQUIRED=false не расширены. Frontend и RouterOS конфигурация не менялись.
|
||||
|
||||
42 канонических auth fixtures: encoded static prefix/раздел, GET/HEAD/PATCH, denied handler count0, OSPF reader/preview и servers-only denial, public config/health. Прежние test:auth, GeoIP JWT и NetFlow private export guards прошли; backend build прошёл. Изменена общая auth-основа, поэтому добавлены профильные проверки разных ресурсов и параметризованных маршрутов; полный UI regression192 не повторялся для backend-only изменения.
|
||||
|
||||
Production compiled SQL/API29 на собственной ограниченной DB/role: anonymous401, dashboard-only403, network reader/writer GET и PSK redaction, denied PATCH403 до native, public config200. Native writes0; DB/role/container удалены. Backend ux-auth211 развёрнут healthy; source477 и compiled1048 совпали. Frontend ux-gre210 сохранён. Live26 с настоящими Portal JWT: анонимные GET/HEAD401, обычные/encoded server и GRE GET по ролям, пустой PATCH403. Пустое тело гарантирует отсутствие native apply даже при ошибке защиты. Два временных Portal user удалены; секреты не публиковались. Пароли CHR не менялись.
|
||||
|
||||
Протоколы: [actual baseline](ux-ui/acceptance/auth211-baseline-live-2026-10-13.json), [профиль](ux-ui/acceptance/auth211-profile-2026-10-13.json), [production SQL/API29](ux-ui/acceptance/auth211-production-result.json), [live26](ux-ui/acceptance/auth211-live-2026-10-13.json), [source](ux-ui/acceptance/source211-result.json), [compiled](ux-ui/acceptance/compiled211-result.json), [deployment](ux-ui/acceptance/auth211-deployment-2026-10-13.json).
|
||||
|
||||
Следующий212: GRE create с PSK и опущенным FastPath, explicit incompatible combination, экспорт недопустимого/неизвестного keepalive. 12.5 остаётся открытой по внешней матрице.
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# План реализации UX/UI по пятичасовым окнам
|
||||
|
||||
Актуальное продолжение 2026-10-13: блок 210 завершён. GRE создаётся с default keepalive 10s,10; минутные значения читаются в секундах, PATCH другого поля сохраняет native timer. Валидатор каталога IPsec исправлен для Filters/карты/диагностики. Пройдены SQL/API14, E2E13 и live GRE/Filters UI4; собственные интерфейсы удалены. Backend/frontend ux-gre210, source475/527 и compiled1048 совпали. Срочный следующий блок 211 — auth/RBAC для закодированных URL; baseline анонимного обхода подтверждён. Этап 12.5 открыт.
|
||||
Актуальное продолжение 2026-10-13: блок 211 завершён. Закрыт анонимный обход JWT и section RBAC через encoded URL: проверяется маршрут Fastify, HEAD наследует GET policy, OSPF parameter routes сохраняют права. Пройдены auth42, production SQL/API29 и live26; тестовые DB/role/users удалены. Backend ux-auth211/source477/compiled1048, frontend ux-gre210. Следующий212 — совместимость GRE FastPath/PSK и шаблон экспорта недопустимого keepalive. Этап12.5 открыт.
|
||||
|
||||
Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-13. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат.
|
||||
|
||||
|
||||
+15
-1
@@ -1,6 +1,6 @@
|
||||
# UX/UI: журнал реализации
|
||||
|
||||
Актуальное продолжение 2026-10-13: блок 210 завершён. GRE создаётся с default keepalive 10s,10; минутные значения читаются в секундах, PATCH другого поля сохраняет native timer. Валидатор каталога IPsec исправлен для Filters/карты/диагностики. Пройдены SQL/API14, E2E13 и live GRE/Filters UI4; собственные интерфейсы удалены. Backend/frontend ux-gre210, source475/527 и compiled1048 совпали. Срочный следующий блок 211 — auth/RBAC для закодированных URL; baseline анонимного обхода подтверждён. Этап 12.5 открыт.
|
||||
Актуальное продолжение 2026-10-13: блок 211 завершён. Закрыт анонимный обход JWT и section RBAC через encoded URL: проверяется маршрут Fastify, HEAD наследует GET policy, OSPF parameter routes сохраняют права. Пройдены auth42, production SQL/API29 и live26; тестовые DB/role/users удалены. Backend ux-auth211/source477/compiled1048, frontend ux-gre210. Следующий212 — совместимость GRE FastPath/PSK и шаблон экспорта недопустимого keepalive. Этап12.5 открыт.
|
||||
|
||||
Общий план: [UX/UI по этапам и пятичасовым окнам](ux-ui-plan.md). План задаёт объём, этот журнал фиксирует выполненные блоки и ограничения. Записи расположены от новых к старым; подробная история этапа12 также сохранена в [ux-ui-stage-12.md](ux-ui-stage-12.md).
|
||||
|
||||
@@ -38,6 +38,20 @@
|
||||
| 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | Завершён в границах локальной приёмки 2026-10-03; ограничения и evidence в11Б.7 |
|
||||
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в границах12.3.83; внешняя12.5 в работе, выполненные блоки1–196 и ограничения ниже. Runtime backend/frontend ux-peak196. |
|
||||
|
||||
## 12.5.211 — JWT/RBAC для закодированных URL (2026-10-13)
|
||||
|
||||
Actual baseline: обычный /api/servers без JWT возвращал401, но /%61pi/servers возвращал200 и server rows с непустыми паролями. Fastify распознаёт encoded static segments; middleware сравнивал raw URL и пропускал auth для encoded /api prefix. Для encoded имени раздела можно было также получить fallback dashboard permission. В evidence сохранены только статусы, число строк и boolean наличия пароля; raw body, credentials и JWT не сохранялись и не выводились.
|
||||
|
||||
Общий preHandler и requireAuth теперь используют request.routeOptions.url — фактически выбранный Fastify маршрут. Проверка public auth config/health сохранена; percent decoding не выполняется повторно вручную. Permission mapping OSPF принимает доверенные parameter templates наряду с прежними numeric paths; HEAD получает те же read permissions, что GET. Политики ролей и AUTH_REQUIRED=false не расширены. Frontend и RouterOS конфигурация не менялись.
|
||||
|
||||
42 канонических auth fixtures: encoded static prefix/раздел, GET/HEAD/PATCH, denied handler count0, OSPF reader/preview и servers-only denial, public config/health. Прежние test:auth, GeoIP JWT и NetFlow private export guards прошли; backend build прошёл. Изменена общая auth-основа, поэтому добавлены профильные проверки разных ресурсов и параметризованных маршрутов; полный UI regression192 не повторялся для backend-only изменения.
|
||||
|
||||
Production compiled SQL/API29 на собственной ограниченной DB/role: anonymous401, dashboard-only403, network reader/writer GET и PSK redaction, denied PATCH403 до native, public config200. Native writes0; DB/role/container удалены. Backend ux-auth211 развёрнут healthy; source477 и compiled1048 совпали. Frontend ux-gre210 сохранён. Live26 с настоящими Portal JWT: анонимные GET/HEAD401, обычные/encoded server и GRE GET по ролям, пустой PATCH403. Пустое тело гарантирует отсутствие native apply даже при ошибке защиты. Два временных Portal user удалены; секреты не публиковались. Пароли CHR не менялись.
|
||||
|
||||
Протоколы: [actual baseline](ux-ui/acceptance/auth211-baseline-live-2026-10-13.json), [профиль](ux-ui/acceptance/auth211-profile-2026-10-13.json), [production SQL/API29](ux-ui/acceptance/auth211-production-result.json), [live26](ux-ui/acceptance/auth211-live-2026-10-13.json), [source](ux-ui/acceptance/source211-result.json), [compiled](ux-ui/acceptance/compiled211-result.json), [deployment](ux-ui/acceptance/auth211-deployment-2026-10-13.json).
|
||||
|
||||
Следующий212: GRE create с PSK и опущенным FastPath, explicit incompatible combination, экспорт недопустимого/неизвестного keepalive. 12.5 остаётся открытой по внешней матрице.
|
||||
|
||||
## 12.5.210 — GRE keepalive и совместимость публичного каталога (2026-10-13)
|
||||
|
||||
На обоих CHR собственные отключённые интерфейсы подтвердили: native REST отклоняет 0, none, пустую строку, disabled, no и ноль попыток. Дробные интервалы принимаются, но сокращаются RouterOS до целых секунд. Поэтому форма и write schema требуют целые значения 1..4294967295 вместо обещания «0 = откл.». Неверный ввод сохраняет форму и не отправляет запрос. Официальный default 10s,10: [MikroTik GRE](https://help.mikrotik.com/docs/spaces/ROS/pages/24805531/GRE).
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Оставшаяся внешняя приёмка — 2026-10-13
|
||||
|
||||
Актуальное продолжение 2026-10-13: блок 210 завершён. GRE создаётся с default keepalive 10s,10; минутные значения читаются в секундах, PATCH другого поля сохраняет native timer. Валидатор каталога IPsec исправлен для Filters/карты/диагностики. Пройдены SQL/API14, E2E13 и live GRE/Filters UI4; собственные интерфейсы удалены. Backend/frontend ux-gre210, source475/527 и compiled1048 совпали. Срочный следующий блок 211 — auth/RBAC для закодированных URL; baseline анонимного обхода подтверждён. Этап 12.5 открыт.
|
||||
Актуальное продолжение 2026-10-13: блок 211 завершён. Закрыт анонимный обход JWT и section RBAC через encoded URL: проверяется маршрут Fastify, HEAD наследует GET policy, OSPF parameter routes сохраняют права. Пройдены auth42, production SQL/API29 и live26; тестовые DB/role/users удалены. Backend ux-auth211/source477/compiled1048, frontend ux-gre210. Следующий212 — совместимость GRE FastPath/PSK и шаблон экспорта недопустимого keepalive. Этап12.5 открыт.
|
||||
|
||||
Это актуальная матрица после 12.5.210. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии.
|
||||
Это актуальная матрица после 12.5.211. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии.
|
||||
|
||||
Стенд: Debian13/Compose, PostgreSQL18.6, два CHR RouterOS7.24.5. Backend/frontend `ux-gre210`; production lab с195 использует AUTH_REQUIRED=true и Portal1.3.1. Подписанные JWT/RBAC проверялись в изолированных процессах. Все собственные объекты112 удалены, исходные13 коллекций×2 (включая logging/certificates/files/routes) проверены; пароли не менялись.
|
||||
Стенд: Debian13/Compose, PostgreSQL18.6, два CHR RouterOS7.24.5. Backend `ux-auth211`, frontend `ux-gre210`; production lab с195 использует AUTH_REQUIRED=true и Portal1.3.1. Подписанные JWT/RBAC проверялись в изолированных процессах. Все собственные объекты112 удалены, исходные13 коллекций×2 (включая logging/certificates/files/routes) проверены; пароли не менялись.
|
||||
|
||||
| Раздел | Подтверждено | Осталось / условие завершения |
|
||||
| --- | --- | --- |
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
## Следующая последовательность — 2026-10-13
|
||||
|
||||
1. **211 — canonical auth path:** закрыть обход JWT/RBAC через encoded API prefix; actual anonymous baseline200 сохранён без raw body/секретов. После него — FastPath/PSK default и экспорт неизвестного keepalive.
|
||||
1. **212 — GRE compatibility:** PSK/FastPath default и explicit conflict; экспорт недопустимого/неизвестного keepalive. Canonical auth/RBAC211 закрыт и развёрнут.
|
||||
2. **Профильный контроль:** для новых изменений выполнять затронутые SQL/API/UI проверки. Общая регрессия192 выполнена; не повторять её без изменений общей основы или нового основания.
|
||||
3. **Внешние зависимости:** Portal issuer/login/revoke, Telegram bot/chat/разрешённое сообщение, клиентские ОС, независимые WAN/public IPv6 и scale/multi-instance — отдельные группы по таблице выше. Ограничения текущего стенда не превращать в обещание приёмки всех конфигураций.
|
||||
|
||||
@@ -1474,3 +1474,18 @@ Runtime ux-gre210: backend healthy, source475/527 и compiled1048 matched. На
|
||||
|
||||
Протоколы: [native syntax](ux-ui/acceptance/gre210-native-range-2026-10-13.json), [дополнительный синтаксис](ux-ui/acceptance/gre210-native-range-extra-2026-10-13.json), [SQL/API14](ux-ui/acceptance/gre210-keepalive-result.json), [профили](ux-ui/acceptance/gre210-profile-2026-10-13.json), [E2E13](ux-ui/acceptance/gre210-e2e-2026-10-13.json), [native/UI/cleanup](ux-ui/acceptance/gre210-native-live-2026-10-13.json), [source](ux-ui/acceptance/source210-result.json), [compiled](ux-ui/acceptance/compiled210-result.json), [deployment](ux-ui/acceptance/gre210-deployment-2026-10-13.json).
|
||||
|
||||
|
||||
## 12.5.211 — JWT/RBAC для закодированных URL (2026-10-13)
|
||||
|
||||
Actual baseline: обычный /api/servers без JWT возвращал401, но /%61pi/servers возвращал200 и server rows с непустыми паролями. Fastify распознаёт encoded static segments; middleware сравнивал raw URL и пропускал auth для encoded /api prefix. Для encoded имени раздела можно было также получить fallback dashboard permission. В evidence сохранены только статусы, число строк и boolean наличия пароля; raw body, credentials и JWT не сохранялись и не выводились.
|
||||
|
||||
Общий preHandler и requireAuth теперь используют request.routeOptions.url — фактически выбранный Fastify маршрут. Проверка public auth config/health сохранена; percent decoding не выполняется повторно вручную. Permission mapping OSPF принимает доверенные parameter templates наряду с прежними numeric paths; HEAD получает те же read permissions, что GET. Политики ролей и AUTH_REQUIRED=false не расширены. Frontend и RouterOS конфигурация не менялись.
|
||||
|
||||
42 канонических auth fixtures: encoded static prefix/раздел, GET/HEAD/PATCH, denied handler count0, OSPF reader/preview и servers-only denial, public config/health. Прежние test:auth, GeoIP JWT и NetFlow private export guards прошли; backend build прошёл. Изменена общая auth-основа, поэтому добавлены профильные проверки разных ресурсов и параметризованных маршрутов; полный UI regression192 не повторялся для backend-only изменения.
|
||||
|
||||
Production compiled SQL/API29 на собственной ограниченной DB/role: anonymous401, dashboard-only403, network reader/writer GET и PSK redaction, denied PATCH403 до native, public config200. Native writes0; DB/role/container удалены. Backend ux-auth211 развёрнут healthy; source477 и compiled1048 совпали. Frontend ux-gre210 сохранён. Live26 с настоящими Portal JWT: анонимные GET/HEAD401, обычные/encoded server и GRE GET по ролям, пустой PATCH403. Пустое тело гарантирует отсутствие native apply даже при ошибке защиты. Два временных Portal user удалены; секреты не публиковались. Пароли CHR не менялись.
|
||||
|
||||
Протоколы: [actual baseline](ux-ui/acceptance/auth211-baseline-live-2026-10-13.json), [профиль](ux-ui/acceptance/auth211-profile-2026-10-13.json), [production SQL/API29](ux-ui/acceptance/auth211-production-result.json), [live26](ux-ui/acceptance/auth211-live-2026-10-13.json), [source](ux-ui/acceptance/source211-result.json), [compiled](ux-ui/acceptance/compiled211-result.json), [deployment](ux-ui/acceptance/auth211-deployment-2026-10-13.json).
|
||||
|
||||
Следующий212: GRE create с PSK и опущенным FastPath, explicit incompatible combination, экспорт недопустимого/неизвестного keepalive. 12.5 остаётся открытой по внешней матрице.
|
||||
|
||||
+16
-1
@@ -1,6 +1,6 @@
|
||||
# Этап 12: итоговая приёмка UX/UI
|
||||
|
||||
Актуальное продолжение 2026-10-13: блок 210 завершён. GRE создаётся с default keepalive 10s,10; минутные значения читаются в секундах, PATCH другого поля сохраняет native timer. Валидатор каталога IPsec исправлен для Filters/карты/диагностики. Пройдены SQL/API14, E2E13 и live GRE/Filters UI4; собственные интерфейсы удалены. Backend/frontend ux-gre210, source475/527 и compiled1048 совпали. Срочный следующий блок 211 — auth/RBAC для закодированных URL; baseline анонимного обхода подтверждён. Этап 12.5 открыт.
|
||||
Актуальное продолжение 2026-10-13: блок 211 завершён. Закрыт анонимный обход JWT и section RBAC через encoded URL: проверяется маршрут Fastify, HEAD наследует GET policy, OSPF parameter routes сохраняют права. Пройдены auth42, production SQL/API29 и live26; тестовые DB/role/users удалены. Backend ux-auth211/source477/compiled1048, frontend ux-gre210. Следующий212 — совместимость GRE FastPath/PSK и шаблон экспорта недопустимого keepalive. Этап12.5 открыт.
|
||||
|
||||
План: [ux-ui-plan.md](ux-ui-plan.md). Фактические результаты: [ux-ui-progress.md](ux-ui-progress.md). Подготовлен после сводных проверок 11Б; завершение каждого блока требует локального коммита без push.
|
||||
|
||||
@@ -3863,3 +3863,18 @@ Runtime ux-gre210: backend healthy, source475/527 и compiled1048 matched. На
|
||||
|
||||
Протоколы: [native syntax](ux-ui/acceptance/gre210-native-range-2026-10-13.json), [дополнительный синтаксис](ux-ui/acceptance/gre210-native-range-extra-2026-10-13.json), [SQL/API14](ux-ui/acceptance/gre210-keepalive-result.json), [профили](ux-ui/acceptance/gre210-profile-2026-10-13.json), [E2E13](ux-ui/acceptance/gre210-e2e-2026-10-13.json), [native/UI/cleanup](ux-ui/acceptance/gre210-native-live-2026-10-13.json), [source](ux-ui/acceptance/source210-result.json), [compiled](ux-ui/acceptance/compiled210-result.json), [deployment](ux-ui/acceptance/gre210-deployment-2026-10-13.json).
|
||||
|
||||
|
||||
## 12.5.211 — JWT/RBAC для закодированных URL (2026-10-13)
|
||||
|
||||
Actual baseline: обычный /api/servers без JWT возвращал401, но /%61pi/servers возвращал200 и server rows с непустыми паролями. Fastify распознаёт encoded static segments; middleware сравнивал raw URL и пропускал auth для encoded /api prefix. Для encoded имени раздела можно было также получить fallback dashboard permission. В evidence сохранены только статусы, число строк и boolean наличия пароля; raw body, credentials и JWT не сохранялись и не выводились.
|
||||
|
||||
Общий preHandler и requireAuth теперь используют request.routeOptions.url — фактически выбранный Fastify маршрут. Проверка public auth config/health сохранена; percent decoding не выполняется повторно вручную. Permission mapping OSPF принимает доверенные parameter templates наряду с прежними numeric paths; HEAD получает те же read permissions, что GET. Политики ролей и AUTH_REQUIRED=false не расширены. Frontend и RouterOS конфигурация не менялись.
|
||||
|
||||
42 канонических auth fixtures: encoded static prefix/раздел, GET/HEAD/PATCH, denied handler count0, OSPF reader/preview и servers-only denial, public config/health. Прежние test:auth, GeoIP JWT и NetFlow private export guards прошли; backend build прошёл. Изменена общая auth-основа, поэтому добавлены профильные проверки разных ресурсов и параметризованных маршрутов; полный UI regression192 не повторялся для backend-only изменения.
|
||||
|
||||
Production compiled SQL/API29 на собственной ограниченной DB/role: anonymous401, dashboard-only403, network reader/writer GET и PSK redaction, denied PATCH403 до native, public config200. Native writes0; DB/role/container удалены. Backend ux-auth211 развёрнут healthy; source477 и compiled1048 совпали. Frontend ux-gre210 сохранён. Live26 с настоящими Portal JWT: анонимные GET/HEAD401, обычные/encoded server и GRE GET по ролям, пустой PATCH403. Пустое тело гарантирует отсутствие native apply даже при ошибке защиты. Два временных Portal user удалены; секреты не публиковались. Пароли CHR не менялись.
|
||||
|
||||
Протоколы: [actual baseline](ux-ui/acceptance/auth211-baseline-live-2026-10-13.json), [профиль](ux-ui/acceptance/auth211-profile-2026-10-13.json), [production SQL/API29](ux-ui/acceptance/auth211-production-result.json), [live26](ux-ui/acceptance/auth211-live-2026-10-13.json), [source](ux-ui/acceptance/source211-result.json), [compiled](ux-ui/acceptance/compiled211-result.json), [deployment](ux-ui/acceptance/auth211-deployment-2026-10-13.json).
|
||||
|
||||
Следующий212: GRE create с PSK и опущенным FastPath, explicit incompatible combination, экспорт недопустимого/неизвестного keepalive. 12.5 остаётся открытой по внешней матрице.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Тестовый сервер UX/UI — 2026-10-10
|
||||
|
||||
Актуальное продолжение 2026-10-13: блок 210 завершён. GRE создаётся с default keepalive 10s,10; минутные значения читаются в секундах, PATCH другого поля сохраняет native timer. Валидатор каталога IPsec исправлен для Filters/карты/диагностики. Пройдены SQL/API14, E2E13 и live GRE/Filters UI4; собственные интерфейсы удалены. Backend/frontend ux-gre210, source475/527 и compiled1048 совпали. Срочный следующий блок 211 — auth/RBAC для закодированных URL; baseline анонимного обхода подтверждён. Этап 12.5 открыт.
|
||||
Актуальное продолжение 2026-10-13: блок 211 завершён. Закрыт анонимный обход JWT и section RBAC через encoded URL: проверяется маршрут Fastify, HEAD наследует GET policy, OSPF parameter routes сохраняют права. Пройдены auth42, production SQL/API29 и live26; тестовые DB/role/users удалены. Backend ux-auth211/source477/compiled1048, frontend ux-gre210. Следующий212 — совместимость GRE FastPath/PSK и шаблон экспорта недопустимого keepalive. Этап12.5 открыт.
|
||||
|
||||
| Параметр | Проверенное состояние |
|
||||
| --- | --- |
|
||||
@@ -2287,3 +2287,18 @@ Runtime ux-gre210: backend healthy, source475/527 и compiled1048 matched. На
|
||||
|
||||
Протоколы: [native syntax](ux-ui/acceptance/gre210-native-range-2026-10-13.json), [дополнительный синтаксис](ux-ui/acceptance/gre210-native-range-extra-2026-10-13.json), [SQL/API14](ux-ui/acceptance/gre210-keepalive-result.json), [профили](ux-ui/acceptance/gre210-profile-2026-10-13.json), [E2E13](ux-ui/acceptance/gre210-e2e-2026-10-13.json), [native/UI/cleanup](ux-ui/acceptance/gre210-native-live-2026-10-13.json), [source](ux-ui/acceptance/source210-result.json), [compiled](ux-ui/acceptance/compiled210-result.json), [deployment](ux-ui/acceptance/gre210-deployment-2026-10-13.json).
|
||||
|
||||
|
||||
## 12.5.211 — JWT/RBAC для закодированных URL (2026-10-13)
|
||||
|
||||
Actual baseline: обычный /api/servers без JWT возвращал401, но /%61pi/servers возвращал200 и server rows с непустыми паролями. Fastify распознаёт encoded static segments; middleware сравнивал raw URL и пропускал auth для encoded /api prefix. Для encoded имени раздела можно было также получить fallback dashboard permission. В evidence сохранены только статусы, число строк и boolean наличия пароля; raw body, credentials и JWT не сохранялись и не выводились.
|
||||
|
||||
Общий preHandler и requireAuth теперь используют request.routeOptions.url — фактически выбранный Fastify маршрут. Проверка public auth config/health сохранена; percent decoding не выполняется повторно вручную. Permission mapping OSPF принимает доверенные parameter templates наряду с прежними numeric paths; HEAD получает те же read permissions, что GET. Политики ролей и AUTH_REQUIRED=false не расширены. Frontend и RouterOS конфигурация не менялись.
|
||||
|
||||
42 канонических auth fixtures: encoded static prefix/раздел, GET/HEAD/PATCH, denied handler count0, OSPF reader/preview и servers-only denial, public config/health. Прежние test:auth, GeoIP JWT и NetFlow private export guards прошли; backend build прошёл. Изменена общая auth-основа, поэтому добавлены профильные проверки разных ресурсов и параметризованных маршрутов; полный UI regression192 не повторялся для backend-only изменения.
|
||||
|
||||
Production compiled SQL/API29 на собственной ограниченной DB/role: anonymous401, dashboard-only403, network reader/writer GET и PSK redaction, denied PATCH403 до native, public config200. Native writes0; DB/role/container удалены. Backend ux-auth211 развёрнут healthy; source477 и compiled1048 совпали. Frontend ux-gre210 сохранён. Live26 с настоящими Portal JWT: анонимные GET/HEAD401, обычные/encoded server и GRE GET по ролям, пустой PATCH403. Пустое тело гарантирует отсутствие native apply даже при ошибке защиты. Два временных Portal user удалены; секреты не публиковались. Пароли CHR не менялись.
|
||||
|
||||
Протоколы: [actual baseline](ux-ui/acceptance/auth211-baseline-live-2026-10-13.json), [профиль](ux-ui/acceptance/auth211-profile-2026-10-13.json), [production SQL/API29](ux-ui/acceptance/auth211-production-result.json), [live26](ux-ui/acceptance/auth211-live-2026-10-13.json), [source](ux-ui/acceptance/source211-result.json), [compiled](ux-ui/acceptance/compiled211-result.json), [deployment](ux-ui/acceptance/auth211-deployment-2026-10-13.json).
|
||||
|
||||
Следующий212: GRE create с PSK и опущенным FastPath, explicit incompatible combination, экспорт недопустимого/неизвестного keepalive. 12.5 остаётся открытой по внешней матрице.
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"date": "2026-10-13",
|
||||
"block": "12.5.211",
|
||||
"runtime": "ux-gre209",
|
||||
"cases": [
|
||||
{
|
||||
"path": "/api/servers",
|
||||
"status": 401,
|
||||
"anonymous": true,
|
||||
"serverRows": 0,
|
||||
"nonemptyPasswordPresent": false
|
||||
},
|
||||
{
|
||||
"path": "/api/%73ervers",
|
||||
"status": 401,
|
||||
"anonymous": true,
|
||||
"serverRows": 0,
|
||||
"nonemptyPasswordPresent": false
|
||||
},
|
||||
{
|
||||
"path": "/%61pi/servers",
|
||||
"status": 200,
|
||||
"anonymous": true,
|
||||
"serverRows": 2,
|
||||
"nonemptyPasswordPresent": true
|
||||
}
|
||||
],
|
||||
"rawBodyStored": false,
|
||||
"mutationRequests": 0
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"date": "2026-10-13",
|
||||
"block": "12.5.211",
|
||||
"services": {
|
||||
"backend": {
|
||||
"image": "mmapp-test/backend:ux-auth211",
|
||||
"imageId": "sha256:904c844a729465e8cdb48278a1f2829c88fe2764941ae60b4a0d05dc2f2d3b18",
|
||||
"running": true,
|
||||
"health": "healthy"
|
||||
},
|
||||
"frontend": {
|
||||
"image": "mmapp-test/frontend:ux-gre210",
|
||||
"imageId": "sha256:b4b1280f729e89de83b30bd242d37bda831306720b3c78cb9eef6048c3e3178e",
|
||||
"running": true,
|
||||
"health": null
|
||||
}
|
||||
},
|
||||
"rollbackTags": {
|
||||
"backend": "ux-gre210",
|
||||
"frontend": "ux-gre210"
|
||||
},
|
||||
"backendSourceMatched": 477,
|
||||
"compiledMatched": 1048
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
{
|
||||
"date": "2026-10-13",
|
||||
"block": "12.5.211",
|
||||
"backend": "ux-auth211",
|
||||
"frontend": "ux-gre210",
|
||||
"cases": [
|
||||
{
|
||||
"role": "anonymous",
|
||||
"path": "/api/servers",
|
||||
"method": "GET",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"role": "anonymous",
|
||||
"path": "/api/servers",
|
||||
"method": "HEAD",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"role": "anonymous",
|
||||
"path": "/api/%73ervers",
|
||||
"method": "GET",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"role": "anonymous",
|
||||
"path": "/api/%73ervers",
|
||||
"method": "HEAD",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"role": "anonymous",
|
||||
"path": "/%61pi/servers",
|
||||
"method": "GET",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"role": "anonymous",
|
||||
"path": "/%61pi/servers",
|
||||
"method": "HEAD",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"role": "anonymous",
|
||||
"path": "/%61%70%69/servers",
|
||||
"method": "GET",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"role": "anonymous",
|
||||
"path": "/%61%70%69/servers",
|
||||
"method": "HEAD",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"role": "dashboard",
|
||||
"path": "/api/servers",
|
||||
"method": "GET",
|
||||
"status": 403,
|
||||
"privateMaterialAbsent": true
|
||||
},
|
||||
{
|
||||
"role": "dashboard",
|
||||
"path": "/api/%73ervers",
|
||||
"method": "GET",
|
||||
"status": 403,
|
||||
"privateMaterialAbsent": true
|
||||
},
|
||||
{
|
||||
"role": "dashboard",
|
||||
"path": "/%61pi/servers",
|
||||
"method": "GET",
|
||||
"status": 403,
|
||||
"privateMaterialAbsent": true
|
||||
},
|
||||
{
|
||||
"role": "dashboard",
|
||||
"path": "/api/gre/tunnels",
|
||||
"method": "GET",
|
||||
"status": 403,
|
||||
"pskAbsent": true
|
||||
},
|
||||
{
|
||||
"role": "dashboard",
|
||||
"path": "/api/gre/tunnels",
|
||||
"method": "PATCH",
|
||||
"status": 403,
|
||||
"emptyBody": true,
|
||||
"nativeApplication": false
|
||||
},
|
||||
{
|
||||
"role": "dashboard",
|
||||
"path": "/api/%67re/tunnels",
|
||||
"method": "GET",
|
||||
"status": 403,
|
||||
"pskAbsent": true
|
||||
},
|
||||
{
|
||||
"role": "dashboard",
|
||||
"path": "/api/%67re/tunnels",
|
||||
"method": "PATCH",
|
||||
"status": 403,
|
||||
"emptyBody": true,
|
||||
"nativeApplication": false
|
||||
},
|
||||
{
|
||||
"role": "dashboard",
|
||||
"path": "/%61pi/gre/tunnels",
|
||||
"method": "GET",
|
||||
"status": 403,
|
||||
"pskAbsent": true
|
||||
},
|
||||
{
|
||||
"role": "dashboard",
|
||||
"path": "/%61pi/gre/tunnels",
|
||||
"method": "PATCH",
|
||||
"status": 403,
|
||||
"emptyBody": true,
|
||||
"nativeApplication": false
|
||||
},
|
||||
{
|
||||
"role": "reader",
|
||||
"path": "/api/servers",
|
||||
"method": "GET",
|
||||
"status": 200,
|
||||
"privateMaterialAbsent": true
|
||||
},
|
||||
{
|
||||
"role": "reader",
|
||||
"path": "/api/%73ervers",
|
||||
"method": "GET",
|
||||
"status": 200,
|
||||
"privateMaterialAbsent": true
|
||||
},
|
||||
{
|
||||
"role": "reader",
|
||||
"path": "/%61pi/servers",
|
||||
"method": "GET",
|
||||
"status": 200,
|
||||
"privateMaterialAbsent": true
|
||||
},
|
||||
{
|
||||
"role": "reader",
|
||||
"path": "/api/gre/tunnels",
|
||||
"method": "GET",
|
||||
"status": 200,
|
||||
"pskAbsent": true
|
||||
},
|
||||
{
|
||||
"role": "reader",
|
||||
"path": "/api/gre/tunnels",
|
||||
"method": "PATCH",
|
||||
"status": 403,
|
||||
"emptyBody": true,
|
||||
"nativeApplication": false
|
||||
},
|
||||
{
|
||||
"role": "reader",
|
||||
"path": "/api/%67re/tunnels",
|
||||
"method": "GET",
|
||||
"status": 200,
|
||||
"pskAbsent": true
|
||||
},
|
||||
{
|
||||
"role": "reader",
|
||||
"path": "/api/%67re/tunnels",
|
||||
"method": "PATCH",
|
||||
"status": 403,
|
||||
"emptyBody": true,
|
||||
"nativeApplication": false
|
||||
},
|
||||
{
|
||||
"role": "reader",
|
||||
"path": "/%61pi/gre/tunnels",
|
||||
"method": "GET",
|
||||
"status": 200,
|
||||
"pskAbsent": true
|
||||
},
|
||||
{
|
||||
"role": "reader",
|
||||
"path": "/%61pi/gre/tunnels",
|
||||
"method": "PATCH",
|
||||
"status": 403,
|
||||
"emptyBody": true,
|
||||
"nativeApplication": false
|
||||
}
|
||||
],
|
||||
"publicAuthConfig": 200,
|
||||
"realPortalJWT": true,
|
||||
"rawResponseBodiesStored": false,
|
||||
"ownedUsersRemoved": true,
|
||||
"scope": "Anonymous GET/HEAD and actual restricted roles; denied PATCH uses empty body and cannot apply native objects"
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
{
|
||||
"date": "2026-10-13",
|
||||
"block": "12.5.211",
|
||||
"database": "mm_accept_166_1791901195054",
|
||||
"baseline": false,
|
||||
"cases": [
|
||||
{
|
||||
"path": "/api/servers",
|
||||
"method": "GET",
|
||||
"role": "anonymous",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"path": "/api/servers",
|
||||
"method": "HEAD",
|
||||
"role": "anonymous",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"path": "/api/%73ervers",
|
||||
"method": "GET",
|
||||
"role": "anonymous",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"path": "/api/%73ervers",
|
||||
"method": "HEAD",
|
||||
"role": "anonymous",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"path": "/%61pi/servers",
|
||||
"method": "GET",
|
||||
"role": "anonymous",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"path": "/%61pi/servers",
|
||||
"method": "HEAD",
|
||||
"role": "anonymous",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"path": "/%61%70%69/servers",
|
||||
"method": "GET",
|
||||
"role": "anonymous",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"path": "/%61%70%69/servers",
|
||||
"method": "HEAD",
|
||||
"role": "anonymous",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"path": "/api/gre/tunnels",
|
||||
"method": "GET",
|
||||
"role": "anonymous",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"path": "/api/gre/tunnels",
|
||||
"method": "HEAD",
|
||||
"role": "anonymous",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"path": "/%61pi/gre/tunnels",
|
||||
"method": "GET",
|
||||
"role": "anonymous",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"path": "/%61pi/gre/tunnels",
|
||||
"method": "HEAD",
|
||||
"role": "anonymous",
|
||||
"status": 401
|
||||
},
|
||||
{
|
||||
"path": "/api/gre/tunnels",
|
||||
"method": "GET",
|
||||
"role": "dashboard",
|
||||
"status": 403,
|
||||
"privateMaterialStored": false
|
||||
},
|
||||
{
|
||||
"path": "/api/gre/tunnels",
|
||||
"method": "PATCH",
|
||||
"role": "dashboard",
|
||||
"status": 403
|
||||
},
|
||||
{
|
||||
"path": "/api/gre/tunnels",
|
||||
"method": "GET",
|
||||
"role": "reader",
|
||||
"status": 200,
|
||||
"privateMaterialStored": false
|
||||
},
|
||||
{
|
||||
"path": "/api/gre/tunnels",
|
||||
"method": "PATCH",
|
||||
"role": "reader",
|
||||
"status": 403
|
||||
},
|
||||
{
|
||||
"path": "/api/gre/tunnels",
|
||||
"method": "GET",
|
||||
"role": "writer",
|
||||
"status": 200,
|
||||
"privateMaterialStored": false
|
||||
},
|
||||
{
|
||||
"path": "/api/%67re/tunnels",
|
||||
"method": "GET",
|
||||
"role": "dashboard",
|
||||
"status": 403,
|
||||
"privateMaterialStored": false
|
||||
},
|
||||
{
|
||||
"path": "/api/%67re/tunnels",
|
||||
"method": "PATCH",
|
||||
"role": "dashboard",
|
||||
"status": 403
|
||||
},
|
||||
{
|
||||
"path": "/api/%67re/tunnels",
|
||||
"method": "GET",
|
||||
"role": "reader",
|
||||
"status": 200,
|
||||
"privateMaterialStored": false
|
||||
},
|
||||
{
|
||||
"path": "/api/%67re/tunnels",
|
||||
"method": "PATCH",
|
||||
"role": "reader",
|
||||
"status": 403
|
||||
},
|
||||
{
|
||||
"path": "/api/%67re/tunnels",
|
||||
"method": "GET",
|
||||
"role": "writer",
|
||||
"status": 200,
|
||||
"privateMaterialStored": false
|
||||
},
|
||||
{
|
||||
"path": "/%61pi/gre/tunnels",
|
||||
"method": "GET",
|
||||
"role": "dashboard",
|
||||
"status": 403,
|
||||
"privateMaterialStored": false
|
||||
},
|
||||
{
|
||||
"path": "/%61pi/gre/tunnels",
|
||||
"method": "PATCH",
|
||||
"role": "dashboard",
|
||||
"status": 403
|
||||
},
|
||||
{
|
||||
"path": "/%61pi/gre/tunnels",
|
||||
"method": "GET",
|
||||
"role": "reader",
|
||||
"status": 200,
|
||||
"privateMaterialStored": false
|
||||
},
|
||||
{
|
||||
"path": "/%61pi/gre/tunnels",
|
||||
"method": "PATCH",
|
||||
"role": "reader",
|
||||
"status": 403
|
||||
},
|
||||
{
|
||||
"path": "/%61pi/gre/tunnels",
|
||||
"method": "GET",
|
||||
"role": "writer",
|
||||
"status": 200,
|
||||
"privateMaterialStored": false
|
||||
},
|
||||
{
|
||||
"path": "/api/auth/config",
|
||||
"role": "anonymous",
|
||||
"status": 200,
|
||||
"publicConfig": true
|
||||
},
|
||||
{
|
||||
"path": "/%61pi/auth/config",
|
||||
"role": "anonymous",
|
||||
"status": 200,
|
||||
"publicConfig": true
|
||||
}
|
||||
],
|
||||
"scope": "Production compiled canonical auth/RBAC using own restricted PostgreSQL, local native HTTP fixture and synthetic JWT/PSK",
|
||||
"passed": true,
|
||||
"nativeWrites": 0,
|
||||
"databaseAndRoleRemoved": true
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"date": "2026-10-13",
|
||||
"block": "12.5.211",
|
||||
"canonicalAuthCases": 42,
|
||||
"commands": [
|
||||
"npm --prefix backend run test:auth",
|
||||
"npx tsx backend/src/plugins/auth.geoip.test.ts",
|
||||
"npx tsx backend/src/plugins/auth.netflow-settings.test.ts"
|
||||
],
|
||||
"passed": true,
|
||||
"backendBuildPassed": true,
|
||||
"scope": "Matched static/parameter routes, GET/HEAD/PATCH, OSPF read preview, public auth config/health, existing auth/GeoIP/private NetFlow export policy"
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"date": "2026-10-13",
|
||||
"block": "12.5.211",
|
||||
"kinds": [
|
||||
{
|
||||
"kind": "backend",
|
||||
"matched": 477
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user