Security release
Fixes an SVG sanitization bypass and unvalidated curation paths. See GHSA-3xm3-q2fj-x8rq for the full advisory.
- SVG sanitization could be bypassed by renaming the file. Sanitization was gated on the client-supplied filename extension while acceptance and the served content type were decided from the file's contents, so SVG markup uploaded as
payload.txtwas stored unsanitized. Sanitizing now keys off the detected type as well as the extension, in both the uploader andCuratorUtils::importMedia, and the serving layer pinsContent-Typefrom the stored extension instead of the sniffed bytes. - The curation modal wrote to a client-supplied path.
saveCuration()consumed the crop payload unvalidated, so a key such as../../othercould overwrite a sibling file inside the storage disk. The payload is now validated before anything is written. curator:sanitize-svgsnow selects on the detected type as well as the extension, so rows stored under a spoofed filename are no longer invisible to it.
After upgrading
Re-scan stored media to clean up anything already on disk:
php artisan curator:sanitize-svgs --dry-run # report only
php artisan curator:sanitize-svgsThe serving-layer change already prevents affected rows from rendering as documents, so this is cleanup rather than the primary fix.
Also in this release
- Removed the unused
exifform view. It was not referenced anywhere in the package and could not render as shipped, since it requested an Alpine component that is never registered. If you published views withvendor:publish --tag=curator-views, your local copy is untouched by this removal and still contains a raw{!! !!}echo of EXIF metadata — escape or delete it.
Reported by Afsana Alijabarova (@afa114).