Enable SVG decode via librsvg, read-only - #95
Conversation
The Appwrite preview endpoint substitutes SVG uploads with a placeholder icon because Imagick cannot open them: the image ships no SVG decode delegate (Alpine's imagemagick package without the imagemagick-svg subpackage) and the hardened policy denies the SVG coders and module. Install imagemagick-svg, which decodes through librsvg — the memory-safe Rust renderer — and grant the SVG/SVGZ coders read-only rights so previews can rasterize, crop, rotate and convert SVG uploads. The reasons SVG was blocked stay enforced: HTTP/HTTPS delegates remain denied (no external hrefs), the @* path deny still blocks local file reads, MSVG — ImageMagick's internal, riskier SVG renderer — stays denied so it cannot be reached even if librsvg goes missing, and SVG encode is denied by the read-only grant. The policy install step now decodes a probe SVG so the build fails loudly if the delegate or policy regresses, and structure tests assert the registered formats, the read-only policy pairing, and a real decode through the PHP extension. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Greptile SummaryThe PR adds librsvg-backed SVG decoding to the runtime image and grants SVG/SVGZ read-only ImageMagick access while retaining existing resource, network-delegate, path, and MSVG restrictions.
Confidence Score: 4/5The PR appears safe to merge, with a non-blocking recommendation to test the external-resource restrictions that now protect SVG decoding. The package, policy, build probe, and runtime capability test are aligned for basic SVG decoding; the remaining concern is that validation proves successful decoding but not continued enforcement of the security controls surrounding hostile SVG references. Files Needing Attention: tests.yaml
|
| Filename | Overview |
|---|---|
| Dockerfile | Installs the SVG delegate and adds a successful basic SVG decode as a build-time capability check. |
| policy.xml | Re-enables SVG/SVGZ decoding with read-only coder rights while retaining MSVG, network-delegate, indirect-path, and resource restrictions. |
| tests.yaml | Verifies format registration, policy rights, and basic Imagick decoding, but does not validate the external-resource restrictions protecting the newly enabled input path. |
| CHANGES.md | Documents the new SVG capability and the security controls intended to remain in force. |
Prompt To Fix All With AI
### Issue 1
tests.yaml:115-118
**External-resource guards untested**
The new test decodes only an empty inline SVG, so image validation does not exercise the HTTP/HTTPS and indirect-path restrictions protecting the newly enabled untrusted SVG path. A later package or policy regression can leave basic decoding green while those security controls no longer isolate external resources.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "Enable SVG decode via librsvg, read-only" | Re-trigger Greptile
Replaces the sanitize-and-serve approach: with appwrite/base 2.1.0 the image ships the librsvg-backed SVG coder with read-only rights, so SVG becomes a regular preview input — decoded by Imagick and run through the existing crop, rotate, border and output pipeline like any raster format. No endpoint changes needed; image/svg+xml joins the accepted inputs and the base image tags move to 2.1.0. Requires the base release from appwrite/docker-base#95. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
What does this PR do?
Makes Imagick able to decode SVG so Appwrite's
/previewendpoint can rasterize SVG uploads and apply the full transformation pipeline (crop, rotate, borders,output=png, …). Today SVG previews fall back to a placeholder icon because the image cannot open SVG at all — two independent blockers:imagemagickpackage is installed without theimagemagick-svgsubpackage, so there is no SVG decode delegate (no decode delegate for this image format 'SVG'even with the policy lifted).policy.xmldenies theSVG/SVGZ/MSVGcoders and module.Changes:
imagemagick-svg, which decodes through librsvg — the memory-safe Rust renderer — never ImageMagick's internal MSVG coder.SVG/SVGZcoders read-only rights inpolicy.xml.rights: Read↔{SVG,SVGZ}policy pairing, and a real decode through the PHP imagick extension.What stays blocked (the reasons SVG was denied in the first place):
@*path reads (local file disclosure)MSVGinternal renderer (riskier fallback if librsvg is absent)Test Plan
Validated against a container from
appwrite/base:2.0.0withimagemagick-svginstalled and this exactpolicy.xml:Utopia\Image\Imagecrop/rotate/output('png')— the exact Appwrite preview pipeline)identify -list policyoutput matches the new structure-test regexAll three new/extended
tests.yamlassertions were validated against real container output.Related PRs and Issues
/preview; will be reworked to rasterize through Imagick once a base release with this change is available🤖 Generated with Claude Code