imagemagick-security.md (7947B)
1 --- 2 title: "ImageMagick Security" 3 section: "Network Services" 4 sectionSlug: "network-services-pentesting" 5 sourcePath: "src/network-services-pentesting/pentesting-web/imagemagick-security.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/network-services-pentesting/pentesting-web/imagemagick-security.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # ImageMagick Security 14 15 Check further details in [**https://blog.doyensec.com/2023/01/10/imagemagick-security-policy-evaluator.html**](https://blog.doyensec.com/2023/01/10/imagemagick-security-policy-evaluator.html)<sup>[[1]](#references)</sup> 16 17 ImageMagick is commonly used behind upload, thumbnailing, document-conversion, and CI/CD pipelines. That makes it a high-value target whenever untrusted images, SVGs, EPS, PS, or PDFs reach `magick` / `convert`. 18 19 Classic **ImageTragick**-style payloads are only part of the story. A modern chain can start from a **single SVG** and end in **arbitrary file write** by abusing how ImageMagick generates MVG plus how it delegates EPS/PS parsing to Ghostscript. 20 21 ## SVG -> MVG injection -> `msl:` execution 22 23 When ImageMagick rasterizes SVG, it first emits an intermediate **MVG** script. If attacker-controlled SVG data reaches that generated MVG without normalizing both LF and CR, an XML-encoded carriage return (` `) can become a **new MVG line**.<sup>[[2]](#references)</sup> 24 25 A practical injection point is the `<polyline points="...">` attribute because the points string is copied into MVG almost verbatim. A payload like:<sup>[[2]](#references)</sup> 26 27 ```xml 28 <polyline points="0,0 50,50 image Over 0,0 1,1 'msl:/tmp/payload.msl' 100,0"/> 29 ``` 30 31 can turn one SVG attribute into attacker-controlled MVG commands.<sup>[[2]](#references)</sup> 32 33 The most useful primitive is:<sup>[[2]](#references)</sup> 34 35 ```text 36 image Over X,Y W,H 'URL' 37 ``` 38 39 This does **not** only load remote HTTP resources. It can also trigger internal coders / protocol handlers such as `data:` and `msl:`.<sup>[[2]](#references)</sup> 40 41 If `msl:` is reachable, an attacker can execute **Magick Scripting Language** from disk and turn the bug into **arbitrary file write**:<sup>[[2]](#references)</sup> 42 43 ```xml 44 <image> 45 <read filename="xc:red[10x10]"/> 46 <write filename="png:/var/www/html/poc.png"/> 47 </image> 48 ``` 49 50 This is different from older ImageTragick payloads: instead of directly trying to get shell metacharacters into a delegate command, the chain abuses **MVG line injection** and then pivots into a **second-stage MSL script**.<sup>[[2]](#references)</sup> 51 52 ## Ghostscript delegate as the file dropper 53 54 ImageMagick usually sends **EPS/PS/PDF** work to a **Ghostscript delegate**. That matters even for an SVG upload, because injected MVG can load an embedded: 55 56 ```text 57 data:image/x-eps;base64,... 58 ``` 59 60 payload.<sup>[[2]](#references)</sup> 61 62 In the published **ImagePanick** repro, Ghostscript `10.06.0` running under SAFER can be abused as a file dropper:<sup>[[2]](#references)</sup><sup>[[3]](#references)</sup> 63 64 - `.tempfile` creates a writable temp file and also extends the read/write/control permit lists for that temp path. 65 - `writestring` stores attacker-controlled MSL bytes. 66 - `renamefile` moves the random temp name to a predictable filename such as `/tmp/payload.msl`. 67 68 Then a second injected MVG line loads:<sup>[[2]](#references)</sup> 69 70 ```text 71 msl:/tmp/payload.msl 72 ``` 73 74 and ImageMagick executes the MSL, producing **arbitrary file write**. From there, writing into a web root, cron path, shell init file, or `authorized_keys` is usually enough for practical RCE or persistence.<sup>[[2]](#references)</sup> 75 76 For more Ghostscript-centric notes, see [Ghostscript Injection](/hacktricks/pentesting-web/formula-csv-doc-latex-ghostscript-injection). 77 78 ## Quick triage 79 80 If a target processes untrusted images, first check which dangerous coders and delegates are still available: 81 82 ```bash 83 magick -list policy 84 identify -list format | grep -E 'SVG|MSL|PS|EPS|PDF' 85 convert -list delegate | grep -iE 'gs|ghostscript' 86 find / -iname policy.xml 2>/dev/null 87 ``` 88 89 If the application accepts SVG and the backend simply does: 90 91 ```bash 92 magick input.svg output.png 93 ``` 94 95 that alone may be enough to trigger the chain when weak policies and a Ghostscript delegate are present. 96 97 ## Towards Safer Policies 98 99 To address these challenges, a [tool has been developed](https://imagemagick-secevaluator.doyensec.com/) to aid in designing and auditing ImageMagick's security policies. This tool is rooted in extensive research and aims to ensure policies are not only robust but also free from loopholes that could be exploited.<sup>[[1]](#references)</sup> 100 101 ## Allowlist vs Denylist Approach 102 103 Historically, ImageMagick policies relied on a denylist approach, where specific coders were denied access. However, changes in ImageMagick 6.9.7-7 shifted this paradigm, enabling an allowlist approach. This approach first denies all coders and then selectively grants access to trusted ones, enhancing the security posture.<sup>[[1]](#references)</sup> 104 105 ```xml 106 ... 107 <policy domain="coder" rights="none" pattern="*" /> 108 <policy domain="coder" rights="read | write" pattern="{GIF,JPEG,PNG,WEBP}" /> 109 ... 110 ``` 111 112 ## Case Sensitivity in Policies 113 114 It's crucial to note that policy patterns in ImageMagick are case sensitive. As such, ensuring that coders and modules are correctly upper-cased in policies is vital to prevent unintended permissions.<sup>[[1]](#references)</sup> 115 116 ## Resource Limits 117 118 ImageMagick is prone to denial of service attacks if not properly configured. Setting explicit resource limits in the policy is essential to prevent such vulnerabilities.<sup>[[1]](#references)</sup> 119 120 ## Policy Fragmentation 121 122 Policies may be fragmented across different ImageMagick installations, leading to potential conflicts or overrides. It's recommended to locate and verify the active policy files using commands like:<sup>[[1]](#references)</sup> 123 124 ```bash 125 $ find / -iname policy.xml 126 ``` 127 128 ## A Starter, Restrictive Policy 129 130 A restrictive policy template has been proposed, focusing on stringent resource limitations and access controls. This template serves as a baseline for developing tailored policies that align with specific application requirements.<sup>[[1]](#references)</sup> 131 132 The effectiveness of a security policy can be confirmed using the `identify -list policy` command in ImageMagick. Additionally, the [evaluator tool](https://imagemagick-secevaluator.doyensec.com/) mentioned earlier can be used to refine the policy based on individual needs.<sup>[[1]](#references)</sup> 133 134 For **untrusted uploads**, prefer an **allowlist**.<sup>[[1]](#references)</sup> If SVG / EPS / PS are not required, explicitly block the dangerous coders instead of trying to blacklist individual bad payloads:<sup>[[2]](#references)</sup> 135 136 ```xml 137 <policy domain="coder" rights="none" pattern="{SVG,EPS,PS,MSL}" /> 138 ``` 139 140 Additional hardening: 141 142 - Disable the Ghostscript delegate in `delegates.xml` if EPS / PS support is not needed.<sup>[[2]](#references)</sup> 143 - Keep coder names upper-cased because policy patterns are **case sensitive**.<sup>[[1]](#references)</sup> 144 - Prefer a dedicated SVG rasterizer such as `librsvg` for untrusted SVG instead of full ImageMagick + Ghostscript.<sup>[[2]](#references)</sup> 145 - Run conversions in a sandbox (`nsjail`, `firejail`, container, read-only filesystem, restricted tmpdir).<sup>[[2]](#references)</sup> 146 147 ## References 148 149 - [1] [ImageMagick Security Policy Evaluator](https://blog.doyensec.com/2023/01/10/imagemagick-security-policy-evaluator.html) 150 - [2] [ImagePanick: From SVG to RCE Chaining Weak Policies and Bugs in ImageMagick and Ghostscript](https://blog.deephacking.tech/en/posts/imagepanick-from-svg-to-rce-imagemagick-ghostscript/) 151 - [3] [ImagePanick PoC / Docker lab](https://github.com/e1abrador/ImagePanick/)