Summary
When handling <use> tag that references an <image> tag, it merges the attributes from the <use> tag to the <image> tag. The problem pops up especially when the href attribute from the <use> tag has not been sanitized. This can lead to an unsafe file read that can cause PHAR Deserialization vulnerability in PHP < 8.
Details
When parsing an <use> tag, it will try to find the referenced object refered by the href attribute. If it is found, it will save it on the $referenced property.
When UseTag::handle is called, the attributes of the <use> tag will be merged with the attributes of the referenced tag:
$mergedAttributes = $this->reference->attributes;
$attributesToNotMerge = ['x', 'y', 'width', 'height'];
foreach ($attributes as $attrKey => $attrVal) {
if (!in_array($attrKey, $attributesToNotMerge) && !isset($mergedAttributes[$attrKey])) {
$mergedAttributes[$attrKey] = $attrVal;
}
}
As shown by the above code, the href attribute is included in the merging process, overiding the href attributes of the referenced tag.
The problem comes if the referenced object is an <image> tag, because the href of the original <image> tag will be overiden, thus bypasing any validation that has occured before for the <image> tag (this is the case in dompdf, as dompdf will sanitize the href attribute in svg file).
Now, after the merging process has finished, the referenced object's handle method is called:
$this->reference->handle($mergedAttributes);
When the <image> tag handle method is called, it will try to draw the image but with the href coming from the <use> tag:
// ImageTag::start
$this->document->getSurface()->drawImage($this->href, $this->x, $this->y, $this->width, $this->height);
Before drawing the image, it will use file_get_contents to load the image based on the href attribute
If this href is pointing to a phar file, it can lead to dangerous deserialization problem ini php <8.
PoC
This is the svg used in this research:
<svg width="200" height="200"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<image id="phar:///poc.phar" xlink:href="file:///existing/safe/image.png" />
<use href="phar:///poc.phar" width="500" height="500"/>
</svg>
When the above code is parsed, the library will load the file via file_get_contents:
$data = file_get_contents("phar:///poc.phar");
Impact
In PHP < 8, the above vulnerability could lead to dangerous deserialization from the phar file. This could lead to file deletion (thus causing denial of service), and even RCE, depending on the classes available in the system.
Mitigation
Systems utilizing php-svg-lib can implement input validation using logic similar to the following:
$parser = xml_parser_create("utf-8");
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false);
xml_set_element_handler(
$parser,
function ($parser, $name, $attributes) {
if (strtolower($name) === "image" || strtolower($name) === "use") {
$attributes = array_change_key_case($attributes, CASE_LOWER);
$urls = [];
$urls[] = $attributes["xlink:href"] ?? "";
$urls[] = $attributes["href"] ?? "";
foreach ($urls as $url) {
if (!empty($url)) {
// perform validation here
}
}
}
// include other tag/attribute validation
},
false
);
if (($fp = fopen($url, "r")) !== false) {
while ($line = fread($fp, 8192)) {
xml_parse($parser, $line, false);
}
fclose($fp);
xml_parse($parser, "", true);
}
xml_parser_free($parser);
Summary
When handling
<use>tag that references an<image>tag, it merges the attributes from the<use>tag to the<image>tag. The problem pops up especially when thehrefattribute from the<use>tag has not been sanitized. This can lead to an unsafe file read that can cause PHAR Deserialization vulnerability in PHP < 8.Details
When parsing an
<use>tag, it will try to find the referenced object refered by thehrefattribute. If it is found, it will save it on the$referencedproperty.When
UseTag::handleis called, the attributes of the<use>tag will be merged with the attributes of the referenced tag:As shown by the above code, the
hrefattribute is included in the merging process, overiding thehrefattributes of the referenced tag.The problem comes if the referenced object is an
<image>tag, because the href of the original<image>tag will be overiden, thus bypasing any validation that has occured before for the<image>tag (this is the case in dompdf, as dompdf will sanitize the href attribute in svg file).Now, after the merging process has finished, the referenced object's
handlemethod is called:When the
<image>tag handle method is called, it will try to draw the image but with the href coming from the<use>tag:Before drawing the image, it will use
file_get_contentsto load the image based on thehrefattributeIf this href is pointing to a phar file, it can lead to dangerous deserialization problem ini php <8.
PoC
This is the svg used in this research:
When the above code is parsed, the library will load the file via
file_get_contents:Impact
In PHP < 8, the above vulnerability could lead to dangerous deserialization from the phar file. This could lead to file deletion (thus causing denial of service), and even RCE, depending on the classes available in the system.
Mitigation
Systems utilizing php-svg-lib can implement input validation using logic similar to the following: