Repository navigation
v0.33.0: security + correctness patch
Six Critical findings from the post-v0.32.0 code review, batched into
one focused security + correctness release. No API changes; clients
with the same wire usage are unaffected.
Fixed
Security
-
Constant-time admin token comparison (
admin/auth.py). Naive
!=short-circuited on first byte mismatch, leaking the admin token
byte-by-byte to a network attacker measuring response time. The
admin API can disable models, restart workers, and trigger arbitrary
muse pullof any HF URI (full code execution via crafted
manifest), so this was the only thing standing between an attacker
and supervisor takeover. Now usessecrets.compare_digest. -
SSRF protection in
_fetch_http_url(image_input.py). The
imagefield on/v1/images/generations(img2img),
/v1/images/embeddings, and/v1/images/animationsaccepted any
http(s):// URL with no IP validation. An unauthenticated request
could reach169.254.169.254(cloud metadata), the worker's own
loopback ports (127.0.0.1:9001), and private LAN ranges. Now
resolves the hostname and rejects private/loopback/link-local/
multicast/reserved/unspecified IPs. Operators on trusted networks
can opt out viaMUSE_ALLOW_PRIVATE_FETCH=1. -
Bounded reads on multipart uploads (
image_input.py).
decode_image_filedidawait file.read()(unbounded) then checked
size after, fully buffering a 1GB upload before rejection. Used by
/v1/images/edits,/variations,/upscale,/segment. Now uses
await file.read(max_bytes + 1). Same hazard fixed in the data-URL
path (a 1GB base64 string would inflate viab64decodebefore the
size check; now pre-checks the b64 length before decoding).
Correctness
-
SSE error event on stream backend failure
(chat_completion/routes.py). Whenchat_streamraised
mid-stream, the consumer logged the error then yielded[DONE],
indistinguishable from a clean empty completion. Now yields
event: errorcarrying the OpenAI error envelope, then[DONE].
Also switched the producer thread from
asyncio.run_coroutine_threadsafe(...).result()to
loop.call_soon_threadsafe(queue.put_nowait, ...)(the pattern
used correctly inaudio_speech), avoiding a producer-thread
deadlock when the event loop is busy. -
OpenAI error envelope on audio_speech encoding failure
(audio_speech/routes.py). A failure inaudio_to_wav_bytes
raisedHTTPException(detail=str(e)), yielding{"detail": "..."}
instead of the documented{"error": {code, message, type}}
envelope. Now useserror_response(...).
Operability
- Pip subprocess timeouts (
refresh.py,core/venv.py,
core/install.py). All three pip-install pathways had no
timeout=, so a hung PyPI mirror could wedge the parent
indefinitely with no escape except SIGINT. All three now use
_PIP_TIMEOUT = 1800(30 min);refresh.pycatches
TimeoutExpiredand returns a failedRefreshResult.
New env var
MUSE_ALLOW_PRIVATE_FETCH=1opts out of the SSRF guard on
_fetch_http_url. Default-off; operators on trusted networks who
wantimageURLs to reach internal services can flip it on.
Test count
2259 (v0.32.0) → 2272 (v0.33.0). Net +13 regression guards across
the six fixes. Every pre-existing test still passes; no test changes
were required for the existing suite.
Plan + transcript
docs/superpowers/plans/2026-05-01-v0.33.0-security-correctness.md- Findings sourced from a code-reviewer agent run after the v0.32.0
ship, surfacing 22 issues (6 Critical, 9 Important, 7 Minor). This
release closes the 6 Critical. Important and Minor findings are
tracked for follow-up patch releases.