fix: job_id невалидного сообщения пишется в лог через repr (M-7)
job_id из сообщения, не прошедшего контракт, — данные отправителя; без экранирования перевод строки в нём позволял подделать строку лога. Теперь repr(job_id[:64]), как в рулинге R-18 для kid токена. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
7a6a7fb36b
commit
87816ef6c9
@ -560,7 +560,8 @@ def _parse_message(msg: InboundMessage) -> RecognitionResultMessage | None:
|
||||
return RecognitionResultMessage.model_validate(data)
|
||||
except ValidationError as exc:
|
||||
raw_job_id = data.get("job_id")
|
||||
job_id = raw_job_id[:LOG_ID_MAX_LENGTH] if isinstance(raw_job_id, str) else None
|
||||
# job_id невалидного сообщения — данные отправителя: repr экранирует переводы строк и управляющие символы
|
||||
job_id = repr(raw_job_id[:LOG_ID_MAX_LENGTH]) if isinstance(raw_job_id, str) else None
|
||||
errors = "; ".join(
|
||||
f"{'.'.join(str(part) for part in error['loc']) or '<root>'}: {error['msg']}"
|
||||
for error in exc.errors(include_url=False, include_input=False, include_context=False)
|
||||
|
||||
@ -238,6 +238,18 @@ async def test_invalid_message_log_carries_job_id_when_readable(logs: list[Any])
|
||||
assert str(_JOB) in record["message"]
|
||||
|
||||
|
||||
async def test_invalid_message_job_id_is_escaped_in_log(logs: list[Any]):
|
||||
"""job_id невалидного сообщения с переводом строки попадает в лог через repr: подделать строку лога нельзя (M-7)."""
|
||||
forged = "not-a-uuid\n2026-10-04 | INFO | подделанная запись\r\x1b[31m"
|
||||
body = {**envelope(_JOB, _FILE, "done"), "job_id": forged}
|
||||
msg = fake_msg(body, "result:x:1", validate=False)
|
||||
await handle_message(msg, session_factory=_UntouchableFactory()) # type: ignore[arg-type]
|
||||
(record,) = _logged(logs, "отклонено", "WARNING")
|
||||
message = record["message"]
|
||||
assert "\n" not in message and "\r" not in message and "\x1b" not in message
|
||||
assert repr(forged) in message
|
||||
|
||||
|
||||
async def test_database_error_is_logged_and_not_raised(logs: list[Any]):
|
||||
"""Ошибка БД (сервер недоступен) — `logger.exception`, без повторов, наружу не выходит."""
|
||||
engine = create_async_engine("postgresql+asyncpg://nobody:nothing@127.0.0.1:1/none")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user