Commit f70af73
fix(docker): purge uv wheel cache after opencv swap [security] (#570)
## Summary
Follow-up to #569 (v0.1.4). That PR replaced the PyPI `opencv-python`
wheel with an ffmpeg-free build, but image scanners were still flagging
the 14 ffmpeg CVEs against v0.1.4. Root cause is scanner scope, not a
broken replacement.
## Root cause
`uv pip uninstall` only drops a package from `site-packages`. The
extracted wheel archive stays in the uv cache. Inspecting the pushed
v0.1.4 image:
- ✅ `cv2.__version__` reports `4.12.0` (our replacement wheel)
- ✅ `site-packages/cv2/` has no `.libs/` directory
- ❌
`/home/notebook-user/.cache/uv/archive-v0/<hash>/opencv_python.libs/`
still contains the full extracted old wheel:
- `libavcodec-*.so.59.37.100`
- `libavformat-*.so.59.27.100`
- `libavutil-*.so.57.28.100`
- plus `libavfilter`, `libavdevice`, `libswscale`, `libswresample`
SO-version suffixes (avcodec 59.37 / avformat 59.27 / avutil 57.28) are
ffmpeg 5.1.x — matching the CVE set the upstream PR called out. Scanners
walk the whole filesystem and flag these even though nothing links
against them at runtime. `UV_LINK_MODE=copy` (set globally in this
Dockerfile) compounds it — the cache keeps its own copy independent of
`site-packages`.
## Fix
Add `uv cache clean` to the end of the opencv replacement `RUN` to wipe
the cache (including the old opencv wheel archive) from the final image
layer. Single minimal change — scoped to the opencv-fix RUN, not a
broader image-slimming pass.
Safe because `UV_LINK_MODE=copy` means the live venv copies files out of
cache — wiping the cache doesn't affect the installed packages.
## False positives ignored (not fixed here)
Two other `libav*` filenames in the image that are **not** ffmpeg and
don't trigger these CVEs:
- `/usr/lib/libreoffice/program/libavmedia{gst,lo}.so` — LibreOffice's
\"avmedia\" framework shim
- `pillow.libs/libavif-*.so.16` — AV1 image codec
## Version / Changelog
- Bumps service version `0.1.4` → `0.1.5`
- `CHANGELOG.md` entry under `0.1.5` → Security
- No `uv lock` changes
## Test plan
- [ ] `make docker-build` succeeds on `amd64` and `arm64`
- [ ] In the rebuilt image, `find / -name \"libavcodec*\" -o -name
\"libavformat*\" -o -name \"libswscale*\"` returns nothing under
`/home/notebook-user/.cache/uv/` and nothing under
`site-packages/cv2/.libs/`
- [ ] `cv2.__version__` still reports `4.12.0.88` and `import cv2;
cv2.imdecode(...)` smoke check works
- [ ] Container scan of the rebuilt image no longer flags the 14 ffmpeg
CVEs
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk: a single Docker build-step cleanup (`uv cache clean`) plus
version/changelog bumps; main risk is unintended impact on Docker layer
caching or build time, not runtime behavior.
>
> **Overview**
> Removes leftover ffmpeg `.so` files from the built image by adding `uv
cache clean` after uninstalling/reinstalling OpenCV wheels in the
Dockerfile, preventing scanners from flagging CVEs from cached wheel
contents.
>
> Bumps the service version to `0.1.5` and adds a matching
`CHANGELOG.md` security entry describing the cache purge.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
f73143d. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 03b57e0 commit f70af73
3 files changed
Lines changed: 16 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
1 | 7 | | |
2 | 8 | | |
3 | 9 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
113 | 113 | | |
114 | 114 | | |
115 | 115 | | |
116 | | - | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
117 | 125 | | |
118 | 126 | | |
119 | 127 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
0 commit comments