gendesign/tradein-mvp/backend/tests/services
bot-backend 1c9f0e1161
All checks were successful
CI / changes (pull_request) Successful in 7s
CI Trade-In / changes (pull_request) Successful in 8s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 51s
fix(tradein/photos): защита от pixel-flood DoS в image_sanitizer
sanitize_image декодировал изображение целиком (img.load) ДО ресайза,
а Pillow MAX_IMAGE_PIXELS оставался дефолтным (~89 MP). Хорошо сжимаемый
≤10 MB аплоад с заявленными ~89-178 MP разворачивался в raw RGB буфер на
сотни MB до thumbnail — OOM-kill backend'а (768 MiB, #2214), усиление ×12
слотов на estimate.

Defense in depth:
- _MAX_PIXELS = 40 MP: проверка img.size (из хедера, без декода) ДО img.load;
  превышение → ImageSanitizationError без загрузки полного буфера.
- Image.MAX_IMAGE_PIXELS понижен до 40 MP — Pillow сам бросает
  DecompressionBombError на любом декод-пути в обход явной проверки.
- Явный except Image.DecompressionBombError + re-raise ImageSanitizationError
  (byte/pixel cap) до широкого except — грациозный reject, не 500.
- _MAX_BYTES backstop (endpoint уже режет 10 MB → 413, но сервис standalone).

Контракт caller'а не меняется: reject → ImageSanitizationError → HTTP 400.
Тест tests/services/test_image_sanitizer.py: happy-path, resize, pixel-flood
без декода (load не вызывается), byte-backstop, граница cap, garbage bytes.
2026-07-12 22:12:12 +03:00
..
scrapers chore(tradein/scrapers): удалить весь legacy scrapers/ каталог — final E (#2397, #2277) 2026-07-04 15:58:15 +03:00
__init__.py feat(tradein): cadastral reverse geocode via main backend cad_buildings (#492) 2026-05-24 07:31:12 +00:00
test_cadastral_reverse.py test(tradein): patch _geoportal_house_match in cadastral-before-yandex test 2026-06-19 18:06:28 +03:00
test_dadata.py fix(tradein/dadata): suggest-fallback для house_fias_id когда CLEAN выключен 2026-07-12 19:55:37 +03:00
test_estimator_precision.py feat(tradein): бейдж точности адреса (qc_geo) на карточке оценки (accuracy #1) 2026-05-28 15:37:33 +05:00
test_image_sanitizer.py fix(tradein/photos): защита от pixel-flood DoS в image_sanitizer 2026-07-12 22:12:12 +03:00
test_location_coef.py feat(tradein): location-coef MVP через FDW-мост к OSM POI Птицы (#2045) 2026-07-03 23:44:55 +03:00
test_proxy_pool.py feat(proxy-pool): pool service (acquire/release/health) + healthcheck scheduler task (#2162) 2026-07-02 16:41:39 +00:00
test_trade_in_pdf_dual_price.py feat(tradein): expected-sold price in estimate PDF (#648 S5b — final) (#665) 2026-05-29 14:09:46 +00:00