Content
Introductory
ImageMagick is a free and open source, cross-platform software package designed primarily for displaying, creating, converting, modifying, and editing raster images, but can also handle a variety of vector formats such as EPS (Encapsulated PostScript), AI (Adobe Illustrator) , PDF (Portable Document Format), etc. In total, it supports more than 200 image file formats. And Imagick is a native PHP an extension that allows you to manage different image formats in a web environment using the ImageMagick API. In this quick troubleshooter, we take a look at how to fix errors from the software security policy with a little intervention.
The symptom
Linux under command line a convert command, or we get an error while creating the Imagick object in PHP on our website. In the first case we get the error in the output of the command, and in the latter we get it with a try-catch structure:
try {
$image = new Imagick($dimsloc);
} catch ( ImagickException $e ) {
echo "Hiba: ".$e->getMessage();
die();
}
And the error messages are like or similar, depending on the image format we wanted to process:
attempt to perform an operation not allowed by the security policy `PS' @ error/constitute.c/IsCoderAuthorized/408 attempt to perform an operation not allowed by the security policy `PS2' @ error/constitute.c/IsCoderAuthorized/408 attempt to perform an operation not allowed by the security policy `PS3' @ error/constitute.c/IsCoderAuthorized/408 attempt to perform an operation not allowed by the security policy `EPS' @ error/constitute.c/IsCoderAuthorized/408 attempt to perform an operation not allowed by the security policy `PDF' @ error/constitute.c/IsCoderAuthorized/408 attempt to perform an operation not allowed by the security policy `XPS' @ error/constitute.c/IsCoderAuthorized/408
etc. ...
The solution
We need to look for the solution in the ImageMagick security policy. There is an xml file for this that describes these rules. Depending on the version of ImageMagick, open this file for editing:
For ImageMagick 6 (eg Debian 10):
sudo nano /etc/ImageMagick-6/policy.xml
For ImageMagick 7 (eg Ubuntu 20.04 LTS):
sudo nano /etc/ImageMagick-7/policy.xml
Then scroll to the bottom where you will find:
<policymap> <!-- <policy domain="system" name="shred" value="2"/> --> <!-- <policy domain="system" name="precision" value="6"/> --> <!-- <policy domain="system" name="memory-map" value="anonymous"/> --> <!-- <policy domain="system" name="max-memory-request" value="256MiB"/> --> <!-- <policy domain="resource" name="temporary-path" value="/tmp"/> --> <policy domain="resource" name="memory" value="256MiB"/> <policy domain="resource" name="map" value="512MiB"/> <policy domain="resource" name="width" value="16KP"/> <policy domain="resource" name="height" value="16KP"/> <!-- <policy domain="resource" name="list-length" value="128"/> --> <policy domain="resource" name="area" value="128MB"/> <policy domain="resource" name="disk" value="1GiB"/> <!-- <policy domain="resource" name="file" value="768"/> --> <!-- <policy domain="resource" name="thread" value="4"/> --> <!-- <policy domain="resource" name="throttle" value="0"/> --> <!-- <policy domain="resource" name="time" value="3600"/> --> <!-- <policy domain="coder" rights="none" pattern="MVG" /> --> <!-- <policy domain="module" rights="none" pattern="{PS,PDF,XPS}" /> --> <!-- <policy domain="delegate" rights="none" pattern="HTTPS" /> --> <!-- <policy domain="path" rights="none" pattern="@*" /> --> <!-- <policy domain="cache" name="memory-map" value="anonymous"/> --> <!-- <policy domain="cache" name="synchronize" value="True"/> --> <!-- <policy domain="cache" name="shared-secret" value="passphrase" stealth="true"/> --> <!-- <policy domain="system" name="pixel-cache-memory" value="anonymous"/> --> <!-- <policy domain="system" name="shred" value="2"/> --> <!-- <policy domain="system" name="precision" value="6"/> --> <!-- not needed due to the need to use explicitly by mvg: --> <!-- <policy domain="delegate" rights="none" pattern="MVG" /> --> <!-- use curl --> <policy domain="delegate" rights="none" pattern="URL" /> <policy domain="delegate" rights="none" pattern="HTTPS" /> <policy domain="delegate" rights="none" pattern="HTTP" /> <!-- in order to avoid to get image with password text --> <policy domain="path" rights="none" pattern="@*"/> <!-- disable ghostscript format types --> <policy domain="coder" rights="none" pattern="PS" /> <policy domain="coder" rights="none" pattern="PS2" /> <policy domain="coder" rights="none" pattern="PS3" /> <policy domain="coder" rights="none" pattern="EPS" /> <policy domain="coder" rights="none" pattern="PDF" /> <policy domain="coder" rights="none" pattern="XPS" /> </policymap>
And modify the lower "disable ghostscript format types" section: delete this section or comment and then replace it as follows:
<policymap> <!-- <policy domain="system" name="shred" value="2"/> --> <!-- <policy domain="system" name="precision" value="6"/> --> <!-- <policy domain="system" name="memory-map" value="anonymous"/> --> <!-- <policy domain="system" name="max-memory-request" value="256MiB"/> --> <!-- <policy domain="resource" name="temporary-path" value="/tmp"/> --> <policy domain="resource" name="memory" value="256MiB"/> <policy domain="resource" name="map" value="512MiB"/> <policy domain="resource" name="width" value="16KP"/> <policy domain="resource" name="height" value="16KP"/> <!-- <policy domain="resource" name="list-length" value="128"/> --> <policy domain="resource" name="area" value="128MB"/> <policy domain="resource" name="disk" value="1GiB"/> <!-- <policy domain="resource" name="file" value="768"/> --> <!-- <policy domain="resource" name="thread" value="4"/> --> <!-- <policy domain="resource" name="throttle" value="0"/> --> <!-- <policy domain="resource" name="time" value="3600"/> --> <!-- <policy domain="coder" rights="none" pattern="MVG" /> --> <!-- <policy domain="module" rights="none" pattern="{PS,PDF,XPS}" /> --> <!-- <policy domain="delegate" rights="none" pattern="HTTPS" /> --> <!-- <policy domain="path" rights="none" pattern="@*" /> --> <!-- <policy domain="cache" name="memory-map" value="anonymous"/> --> <!-- <policy domain="cache" name="synchronize" value="True"/> --> <!-- <policy domain="cache" name="shared-secret" value="passphrase" stealth="true"/> --> <!-- <policy domain="system" name="pixel-cache-memory" value="anonymous"/> --> <!-- <policy domain="system" name="shred" value="2"/> --> <!-- <policy domain="system" name="precision" value="6"/> --> <!-- not needed due to the need to use explicitly by mvg: --> <!-- <policy domain="delegate" rights="none" pattern="MVG" /> --> <!-- use curl --> <policy domain="delegate" rights="none" pattern="URL" /> <policy domain="delegate" rights="none" pattern="HTTPS" /> <policy domain="delegate" rights="none" pattern="HTTP" /> <!-- in order to avoid to get image with password text --> <policy domain="path" rights="none" pattern="@*"/> <!-- disable ghostscript format types --> <!-- <policy domain="coder" rights="none" pattern="PS" /> <policy domain="coder" rights="none" pattern="PS2" /> <policy domain="coder" rights="none" pattern="PS3" /> <policy domain="coder" rights="none" pattern="EPS" /> <policy domain="coder" rights="none" pattern="PDF" /> <policy domain="coder" rights="none" pattern="XPS" /> --> <policy domain="coder" rights="read | write" pattern="PS" /> <policy domain="coder" rights="read | write" pattern="PS2" /> <policy domain="coder" rights="read | write" pattern="PS3" /> <policy domain="coder" rights="read | write" pattern="EPS" /> <policy domain="coder" rights="read | write" pattern="PDF" /> <policy domain="coder" rights="read | write" pattern="XPS" /> </policymap>
I chose to comment.
Then, when using the command line, it immediately applies the fresh rules, which you can even query identify command:
identify -list policy
Path: /etc/ImageMagick-6/policy.xml Policy: Resource name: disk value: 1GiB Policy: Resource name: map value: 512MiB Policy: Resource name: memory value: 256MiB Policy: Resource name: area value: 128MB Policy: Resource name: height value: 16KP Policy: Resource name: width value: 16KP Policy: Delegate rights: None pattern: URL Policy: Delegate rights: None pattern: HTTPS Policy: Delegate rights: None pattern: HTTP Policy: Path rights: None pattern: @* Policy: Coder rights: Read Write pattern: PS Policy: Coder rights: Read Write pattern: PS2 Policy: Coder rights: Read Write pattern: PS3 Policy: Coder rights: Read Write pattern: EPS Policy: Coder rights: Read Write pattern: PDF Policy: Coder rights: Read Write pattern: XPS Path: [built-in] Policy: Undefined rights: None
However, if you get the error in PHP, then after the modification, restart the page running PHP-FPMif the page works.
The cause of the problem
I’ll only describe this interestingly, what caused this to be that ImageMagick worked earlier and tossed bugs for a while. A vulnerability was found in the program, which was first remedied by disabling access to the file formats in question in the config file above. Later, the bug was fixed correctly, a security update was released, but the security rules were not restored. So it was necessary to make up for that.
Az imagemagick debian package bug tracking log can be found here. The related CVE kódok: CVE-2019-13300, CVE-2019-13304, CVE-2019-13306, CVE-2019-13307, CVE-2019-15140, CVE-2019-19948
Conclusion
For me, one plugin on a WordPress-based website uses ImageMagick, which handles vector files. However, the bug was not listed in the plugin, so I only saw the weird "side effects". Then when I started debugging the whole thing, I only came across the error message itself after a long debug, as the error message itself was not printed in the plugin. Then from here on with just a little read, but the solution was found. If I can use this to shorten the search for others - who are in a similar situation - then it’s worth making this description.
- To post registration and login required
- 213 views