Skip to content

Commit 5dcc071

Browse files
committed
fix: harden ImageMagick policy and install rsvg-convert (OC10-164)
Neither owncloud-docker/ubuntu, php, base nor server ship any ImageMagick policy.xml or MAGICK_CONFIGURE_PATH override - the product runs on whatever the OS imagemagick-6-common package defaults to, which denies neither the MSL/MVG/MSVG script coders nor the EPHEMERAL/TEXT/SHOW/WIN/PLT/LABEL/ CAPTION/PANGO coders. Confirmed against the real published owncloud/server :11.0.0 and :10.16.4 images: readImage("msl:...") and the SVG <image xlink:href="MSL:...">/MVG "image" primitive vectors that owncloud/core's OC10-164 fix addresses in application code are not blocked by ImageMagick's own policy at all. Deny MSL, MVG, MSVG, EPHEMERAL, TEXT, SHOW, WIN, PLT, LABEL, CAPTION and PANGO coders, plus the URL/HTTPS/HTTP/FTP delegates, matching the ticket's Item A recommendation. Deliberately does not touch the PS/PDF/EPS/XPS coders or add a blanket delegate/coder deny-all: ownCloud's PDF and Postscript previews decode through the Ghostscript delegate, and a deny-all would break them - upstream ImageMagick's own hardening advice warns against exactly that. Also install librsvg2-bin (missing in both real images - only the .so from librsvg2-common was present, not the rsvg-convert binary). ImageMagick's delegates.xml routes SVG decoding to rsvg-convert; without the binary on PATH it silently falls through to ImageMagick's own internal SVG/MSVG coder, the exact vulnerable path. This is a second, independent layer: it protects any future code path that reads SVG content through Imagick, not just the one owncloud/core patches. Verified by building v24.04 locally and replicating the v22.04 package set on a bare ubuntu:22.04 container (v22.04's own Dockerfile needs a private Freexian mirror secret this environment doesn't have): msl:, the SVG xlink:href="MSL:..." PoC payload, and an MVG "image" primitive referencing msl: are all blocked by policy on both; a real PDF and a legitimate SVG both still render correctly afterward. Signed-off-by: Thomas Müller <323649642+oc-tmueller@users.noreply.github.com>
1 parent de4262e commit 5dcc071

5 files changed

Lines changed: 101 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## 2026-09-11
4+
5+
* Security
6+
* Ship a restrictive ImageMagick policy denying the MSL/MVG/MSVG script
7+
coders and the EPHEMERAL/URL/HTTP/HTTPS/FTP delegates, and install
8+
`librsvg2-bin` so ImageMagick delegates SVG decoding to `rsvg-convert`
9+
instead of falling back to its own coder when the binary is missing
10+
(OC10-164)
11+
312
## 2026-07-06
413

514
* Added

v22.04/Dockerfile.multiarch

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ RUN apt-get update -y && \
5050
exiftool \
5151
sqlite3 \
5252
librsvg2-common \
53+
librsvg2-bin \
5354
ghostscript && \
5455
apt-add-repository -r "https://deb.owncloud.com/php.freexian.com/" -y && \
5556
rm -rf /etc/apache2/envvars /etc/apache2/conf-* /etc/apache2/sites-* /var/log/apache2/* && \
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE policymap [
3+
<!ELEMENT policymap (policy)*>
4+
<!ATTLIST policymap xmlns CDATA #FIXED ''>
5+
<!ELEMENT policy EMPTY>
6+
<!ATTLIST policy xmlns CDATA #FIXED '' domain NMTOKEN #REQUIRED
7+
name NMTOKEN #IMPLIED pattern CDATA #IMPLIED rights NMTOKEN #IMPLIED
8+
stealth NMTOKEN #IMPLIED value CDATA #IMPLIED>
9+
]>
10+
<!--
11+
ownCloud-managed ImageMagick policy (owncloud-docker/php).
12+
13+
Denies the script/vector coders that read and write arbitrary files via
14+
ImageMagick's MSL interpreter (see OC10-164) and the delegates that let a
15+
processed image reach the network or the filesystem outside its own input.
16+
Deliberately does NOT deny the PS/PDF/EPS/XPS coders or add a blanket
17+
delegate/coder deny-all - ownCloud's PDF and Postscript previews decode
18+
through the Ghostscript delegate, and a deny-all would break them.
19+
-->
20+
<policymap>
21+
<policy domain="resource" name="memory" value="256MiB"/>
22+
<policy domain="resource" name="map" value="512MiB"/>
23+
<policy domain="resource" name="width" value="16KP"/>
24+
<policy domain="resource" name="height" value="16KP"/>
25+
<policy domain="resource" name="area" value="128MP"/>
26+
<policy domain="resource" name="disk" value="1GiB"/>
27+
<policy domain="path" rights="none" pattern="@*"/>
28+
<policy domain="delegate" rights="none" pattern="URL"/>
29+
<policy domain="delegate" rights="none" pattern="HTTPS"/>
30+
<policy domain="delegate" rights="none" pattern="HTTP"/>
31+
<policy domain="delegate" rights="none" pattern="FTP"/>
32+
<policy domain="coder" rights="none" pattern="EPHEMERAL"/>
33+
<policy domain="coder" rights="none" pattern="URL"/>
34+
<policy domain="coder" rights="none" pattern="HTTPS"/>
35+
<policy domain="coder" rights="none" pattern="MVG"/>
36+
<policy domain="coder" rights="none" pattern="MSL"/>
37+
<policy domain="coder" rights="none" pattern="MSVG"/>
38+
<policy domain="coder" rights="none" pattern="TEXT"/>
39+
<policy domain="coder" rights="none" pattern="SHOW"/>
40+
<policy domain="coder" rights="none" pattern="WIN"/>
41+
<policy domain="coder" rights="none" pattern="PLT"/>
42+
<policy domain="coder" rights="none" pattern="LABEL"/>
43+
<policy domain="coder" rights="none" pattern="CAPTION"/>
44+
<policy domain="coder" rights="none" pattern="PANGO"/>
45+
</policymap>

v24.04/Dockerfile.multiarch

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ RUN apt-get update -y && \
4040
exiftool \
4141
sqlite3 \
4242
librsvg2-common \
43+
librsvg2-bin \
4344
ghostscript && \
4445
rm -rf /etc/apache2/envvars /etc/apache2/conf-* /etc/apache2/sites-* /var/log/apache2/* && \
4546
a2enmod rewrite headers env dir mime expires remoteip && \
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE policymap [
3+
<!ELEMENT policymap (policy)*>
4+
<!ATTLIST policymap xmlns CDATA #FIXED ''>
5+
<!ELEMENT policy EMPTY>
6+
<!ATTLIST policy xmlns CDATA #FIXED '' domain NMTOKEN #REQUIRED
7+
name NMTOKEN #IMPLIED pattern CDATA #IMPLIED rights NMTOKEN #IMPLIED
8+
stealth NMTOKEN #IMPLIED value CDATA #IMPLIED>
9+
]>
10+
<!--
11+
ownCloud-managed ImageMagick policy (owncloud-docker/php).
12+
13+
Denies the script/vector coders that read and write arbitrary files via
14+
ImageMagick's MSL interpreter (see OC10-164) and the delegates that let a
15+
processed image reach the network or the filesystem outside its own input.
16+
Deliberately does NOT deny the PS/PDF/EPS/XPS coders or add a blanket
17+
delegate/coder deny-all - ownCloud's PDF and Postscript previews decode
18+
through the Ghostscript delegate, and a deny-all would break them.
19+
-->
20+
<policymap>
21+
<policy domain="resource" name="memory" value="1024MiB"/>
22+
<policy domain="resource" name="map" value="2048MiB"/>
23+
<policy domain="resource" name="width" value="32KP"/>
24+
<policy domain="resource" name="height" value="32KP"/>
25+
<policy domain="resource" name="area" value="256MP"/>
26+
<policy domain="resource" name="disk" value="2GiB"/>
27+
<policy domain="path" rights="none" pattern="@*"/>
28+
<policy domain="delegate" rights="none" pattern="URL"/>
29+
<policy domain="delegate" rights="none" pattern="HTTPS"/>
30+
<policy domain="delegate" rights="none" pattern="HTTP"/>
31+
<policy domain="delegate" rights="none" pattern="FTP"/>
32+
<policy domain="coder" rights="none" pattern="EPHEMERAL"/>
33+
<policy domain="coder" rights="none" pattern="URL"/>
34+
<policy domain="coder" rights="none" pattern="HTTPS"/>
35+
<policy domain="coder" rights="none" pattern="MVG"/>
36+
<policy domain="coder" rights="none" pattern="MSL"/>
37+
<policy domain="coder" rights="none" pattern="MSVG"/>
38+
<policy domain="coder" rights="none" pattern="TEXT"/>
39+
<policy domain="coder" rights="none" pattern="SHOW"/>
40+
<policy domain="coder" rights="none" pattern="WIN"/>
41+
<policy domain="coder" rights="none" pattern="PLT"/>
42+
<policy domain="coder" rights="none" pattern="LABEL"/>
43+
<policy domain="coder" rights="none" pattern="CAPTION"/>
44+
<policy domain="coder" rights="none" pattern="PANGO"/>
45+
</policymap>

0 commit comments

Comments
 (0)