KamoCRM

Cap upload size and concurrent conversions on the unauthenticated pipeline endpoints

FixVectorService
Shipped
September 23, 2026 at 2:28 AM UTC
Author
Kamo
Commit
4820f44

POST /convert-vector and WS /ws/pipeline take no auth (see this commit's companion report for why that is not fixed here) and, until now, read a caller's whole upload into memory before looking at its size at all — max_image_size_mb was defined in settings and never referenced anywhere. Either endpoint also ran background removal and vectorization (rembg, vtracer — both CPU-bound, via asyncio.to_thread) with no cap on how many could run at once. Together that is an open door to running this pod out of memory or CPU with a handful of concurrent requests, from anyone who can reach it — and per **************** that is any browser on the internet: Traefik routes /vector-ws/* straight to this service, bypassing apiservice's gateway entirely. - /convert-vector now reads the upload in bounded chunks and refuses (413) as soon as the running total crosses max_image_size_mb, rather than after buffering the whole thing. - The WebSocket pipeline has no equivalent of a chunked read — receive_text() already holds the full decoded frame by the time it's seen — so the same limit is checked immediately after base64-decoding an incoming image/mask, before it is ever handed to bg removal or vectorization. - A new conversion_semaphore (max_concurrent_conversions, default 4, in settings/configmap like max_image_size_mb already was) wraps every bg-removal and vectorization call in both endpoints. Excess callers wait; they are not refused. Tests: test_resource_limits.py (pytest + httpx only — the heavy ML/CV deps in requirements.txt are all imported lazily inside services/*.py function bodies, never at module load, so the two conversion entry points are mocked instead of installed). Not run by CI today; this build has none (build-and-deploy.yml goes straight from checkout to docker build/push/deploy). Each guard was verified red first: the size cap removed (an oversized upload reaches the mocked converter instead of being refused) and the WebSocket size check disabled, in a local worktree, restored after.

All changes

Like what you see shipping?

All of it arrives in your workspace on its own. Start on the free plan and read this page again in a month.

Start Free ForeverView Pricing