(medium) admin.test_cian_auth: 403-бан Cian отдаётся как authenticated=True (VERIFY_BAN_SENTINEL не различается) #1527

Closed
opened 2026-06-15 05:59:18 +00:00 by bot-backend · 1 comment
Collaborator

Severity: medium · Категория: logic · Файл: tradein-mvp/backend/app/api/v1/admin.py:411-416

admin.py:411-416. test_cian_auth вызывает cian_session_svc.verify_session, который при HTTP 403 (TLS/bot-ban) возвращает VERIFY_BAN_SENTINEL={'_ban':True} (cian_session.py:68,82-83) — truthy, не None. Эндпоинт проверяет только if state is None, поэтому sentinel проходит дальше: state.get('user',{}) даёт {}, userId=None, и возвращается {'authenticated': True, 'userId': None}. Импакт: ops видит «авторизованы» при фактическом бане IP — куки не проверены, ложноположительная диагностика живости сессии скрывает реальную проблему доступа к Cian. Фикс: добавить ветку if state.get('_ban'): return {'authenticated': False, 'userId': None, 'reason': 'banned_403'} перед извлечением userId (как требует докстринг cian_session.py:64-67).

Почему баг: Сам модуль cian_session.py:64-68 документирует, что callers, которым нужно отличать ban от валидной авторизации, ОБЯЗАНЫ проверять state.get('_ban'). test_cian_auth (admin.py:411-416) этого не делает: truthy sentinel проходит мимо if state is None, userId=None, результат — ложное authenticated=True. Это неверный результат в ops-эндпоинте для проверки живости сессии.

Как чинить: В test_cian_auth (и в upload/auto-login на 308-317, 381-390) явно обрабатывать sentinel: if state is None or state.get('_ban'): return authenticated=False, reason='banned_or_expired'.


deep-audit «армия ботов 2» · verify+harden, confidence 0.92 · unit U127

**Severity:** medium · **Категория:** logic · **Файл:** `tradein-mvp/backend/app/api/v1/admin.py:411-416` admin.py:411-416. test_cian_auth вызывает cian_session_svc.verify_session, который при HTTP 403 (TLS/bot-ban) возвращает VERIFY_BAN_SENTINEL={'_ban':True} (cian_session.py:68,82-83) — truthy, не None. Эндпоинт проверяет только `if state is None`, поэтому sentinel проходит дальше: state.get('user',{}) даёт {}, userId=None, и возвращается {'authenticated': True, 'userId': None}. Импакт: ops видит «авторизованы» при фактическом бане IP — куки не проверены, ложноположительная диагностика живости сессии скрывает реальную проблему доступа к Cian. Фикс: добавить ветку `if state.get('_ban'): return {'authenticated': False, 'userId': None, 'reason': 'banned_403'}` перед извлечением userId (как требует докстринг cian_session.py:64-67). **Почему баг:** Сам модуль cian_session.py:64-68 документирует, что callers, которым нужно отличать ban от валидной авторизации, ОБЯЗАНЫ проверять state.get('_ban'). test_cian_auth (admin.py:411-416) этого не делает: truthy sentinel проходит мимо `if state is None`, userId=None, результат — ложное authenticated=True. Это неверный результат в ops-эндпоинте для проверки живости сессии. **Как чинить:** В test_cian_auth (и в upload/auto-login на 308-317, 381-390) явно обрабатывать sentinel: `if state is None or state.get('_ban'): return authenticated=False, reason='banned_or_expired'`. --- <sub>deep-audit «армия ботов 2» · verify+harden, confidence 0.92 · unit U127</sub>
bot-backend added the
week ревью 1
label 2026-06-15 05:59:18 +00:00
bot-backend added the
scope/backend
label 2026-06-15 11:02:18 +00:00
Owner

🔍 week ревью 1 — верификация (ПОДТВЕРЖДЕНО)

Текущее состояние кода: tradein-mvp/backend/app/services/cian_session.py:68 определяет VERIFY_BAN_SENTINEL = {"_ban": True} (truthy), а _classify_verify_response возвращает его при HTTP 403 (строки 82-83). В admin.py:411-416 хендлер test_cian_auth: state = verify_session(...) → проверка только if state is None (412) → при бане sentinel проходит → state.get("user", {}).get("userId") (415) = {}.get("userId") = None → возвращается {"authenticated": True, "userId": None, "reason": None}. Докстринг самого модуля (cian_session.py:64-67) явно требует от callers проверять state.get("_ban").

Корень: test_cian_auth не различает ban-sentinel от валидной авторизации — truthy {"_ban":True} проходит мимо if state is None, и ops видит «authenticated=True» при фактическом 403-бане IP.

Что править:

  • В test_cian_auth (admin.py:411-413) добавить ветку перед извлечением userId: if state is None or state.get("_ban"): return {"authenticated": False, "userId": None, "reason": "banned_403" if state else "session_expired_or_invalid"}.
  • Параллельные сайты upload (admin.py:308-317) и auto-login (381-390) формально не отдают ложный authenticated, но при бане падают невнятным 400 «missing userId» (316/389) вместо явного 403/502 «banned» — желательно тоже обработать state.get("_ban") отдельной веткой для корректного кода ошибки.

Что посмотреть:

  • Код: tradein-mvp/backend/app/api/v1/admin.py:411-416 (test-auth), 308-317 (upload), 381-390 (auto-login); tradein-mvp/backend/app/services/cian_session.py:64-94 (sentinel + classifier). Добавить тест: verify_session→VERIFY_BAN_SENTINEL ⇒ test_cian_auth отдаёт authenticated=False.
  • Vault: релевантных заметок не найдено.
**🔍 week ревью 1 — верификация (ПОДТВЕРЖДЕНО)** **Текущее состояние кода:** `tradein-mvp/backend/app/services/cian_session.py:68` определяет `VERIFY_BAN_SENTINEL = {"_ban": True}` (truthy), а `_classify_verify_response` возвращает его при HTTP 403 (строки 82-83). В `admin.py:411-416` хендлер `test_cian_auth`: `state = verify_session(...)` → проверка только `if state is None` (412) → при бане sentinel проходит → `state.get("user", {}).get("userId")` (415) = `{}.get("userId")` = `None` → возвращается `{"authenticated": True, "userId": None, "reason": None}`. Докстринг самого модуля (cian_session.py:64-67) явно требует от callers проверять `state.get("_ban")`. **Корень:** `test_cian_auth` не различает ban-sentinel от валидной авторизации — truthy `{"_ban":True}` проходит мимо `if state is None`, и ops видит «authenticated=True» при фактическом 403-бане IP. **Что править:** - В `test_cian_auth` (admin.py:411-413) добавить ветку перед извлечением userId: `if state is None or state.get("_ban"): return {"authenticated": False, "userId": None, "reason": "banned_403" if state else "session_expired_or_invalid"}`. - Параллельные сайты `upload` (admin.py:308-317) и `auto-login` (381-390) формально не отдают ложный `authenticated`, но при бане падают невнятным 400 «missing userId» (316/389) вместо явного 403/502 «banned» — желательно тоже обработать `state.get("_ban")` отдельной веткой для корректного кода ошибки. **Что посмотреть:** - Код: `tradein-mvp/backend/app/api/v1/admin.py:411-416` (test-auth), 308-317 (upload), 381-390 (auto-login); `tradein-mvp/backend/app/services/cian_session.py:64-94` (sentinel + classifier). Добавить тест: verify_session→VERIFY_BAN_SENTINEL ⇒ test_cian_auth отдаёт authenticated=False. - Vault: релевантных заметок не найдено.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#1527
No description provided.