gendesign/tradein-mvp/backend/tests/test_3194_hide_sql_parameters.py
bot-backend 7e59c1e5b0
All checks were successful
CI / changes (pull_request) Successful in 9s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI Trade-In / changes (pull_request) Successful in 7s
CI / openapi-codegen-check (pull_request) Successful in 3m10s
CI Trade-In / backend-tests (pull_request) Successful in 5m47s
CI / backend-tests (pull_request) Successful in 18m3s
fix(#3194): hide_parameters=True на всех движках, include_local_variables=False у scheduler
Ключ шифрования кук и сами куки уезжали в GlitchTip: сервисы сессий передают
их bind-параметрами в pgp_sym_encrypt(:cookies_json, :key), а SQLAlchemy при
ошибке печатает ВСЕ параметры в тексте StatementError.

Правка на уровне движка (backend + tradein-mvp: db.py, auth_db.py,
alembic/env.py) кроет все сайты вызова разом, включая четвёртую копию в
scraper-kit и всё будущее.

scheduler_main.py был единственным из трёх sentry_sdk.init без
include_local_variables=False — процесс скрейпера, в кадрах лежат прокси-креды.

НЕ закрывает: текст ошибки самого драйвера (Postgres DETAIL со значением) и
сырые psycopg-подключения мимо движков — отдельный класс.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-30 14:53:41 +05:00

47 lines
2.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""#3194: bind-параметры не должны попадать в текст исключения (→ GlitchTip).
Через них уезжали ключ шифрования кук и сами куки: сервисы сессий зовут
`db.execute(text("... pgp_sym_encrypt(:cookies_json, :key) ..."), {...})`, а
SQLAlchemy при ошибке оборачивает всё в StatementError и печатает ВСЕ
параметры в `str(exc)`.
Отказ здесь обязан произойти НА УРОВНЕ ЗАПРОСА: если соединение падает на
CONNECT, до bind-параметров дело не доходит и тест зелёный по построению.
Поэтому — живой sqlite в памяти и обращение к несуществующей таблице.
"""
from __future__ import annotations
import pytest
from sqlalchemy import create_engine, text
from sqlalchemy.exc import StatementError
SECRET = "sup3r-secret-cookie-key-3194"
def _provoke_statement_error(*, hide: bool) -> str:
engine = create_engine("sqlite://", hide_parameters=hide)
with engine.connect() as conn:
with pytest.raises(StatementError) as excinfo:
conn.execute(text("SELECT :key FROM no_such_table_3194"), {"key": SECRET})
return str(excinfo.value)
def test_bind_parameters_hidden_in_exception_text() -> None:
message = _provoke_statement_error(hide=True)
# Отказ именно на запросе, а не на соединении — иначе проверка ниже пуста.
assert "no_such_table_3194" in message
assert SECRET not in message
def test_falsification_secret_leaks_without_the_flag() -> None:
"""Обратная сторона: без флага секрет ВИДЕН — тест выше не тавтология."""
message = _provoke_statement_error(hide=False)
assert SECRET in message
def test_app_engine_hides_parameters() -> None:
"""Сам прод-движок, а не только принцип: create_engine ленив, коннекта нет."""
from app.core.db import engine
assert engine.hide_parameters is True