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 thehref
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 thehref
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:As shown by the above code, the
href
attribute is included in the merging process, overiding thehref
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: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_contents
to load the image based on thehref
attributeIf 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: