使用PHP清理SVG

使用PHP清理SVG,php,svg,sanitization,Php,Svg,Sanitization,我正在使用d3.js动态创建SVG图表。这些图表是根据经过身份验证的用户的选择动态生成的。生成这些图表后,用户可以选择将生成的SVG下载为PNG或PDF格式 当前工作流如下所示: // JAVASC // get the element containing generated SVG var svg = document.getElementById("chart-container"); // Extract the data as SVG text string var svg_xml

我正在使用d3.js动态创建SVG图表。这些图表是根据经过身份验证的用户的选择动态生成的。生成这些图表后,用户可以选择将生成的SVG下载为PNG或PDF格式

当前工作流如下所示:

// JAVASC
// get the element containing generated SVG
var svg = document.getElementById("chart-container");

// Extract the data as SVG text string
var svg_xml = (new XMLSerializer).serializeToString(svg);

// Submit the <FORM> to the server.
var form = document.getElementById("svgform");
form['output_format'].value = output_format;  // can be either "pdf" or "png"
form['data'].value = svg_xml ;
form.submit();
运行转换实用程序,读取临时文件($infle)并以指定的$fileformat(PDF或PNG)创建新文件($outfile)。生成的新文件将返回到浏览器,并删除临时文件:

// headers etc generated - omitted for brevity
readfile($outfile);

unlink($infile);  // delete temporary infile  
unlink($outfile);  // delete temporary outfile  
我已经调查过了,可能会用它来生成PNG,但它不允许转换为PDF

因此: 在将SVG数据写入文件之前,如何最好地清理或过滤提供给conversion.php的SVG数据?SVG消毒的现状如何?PHP中提供了什么?我应该使用一种方法来清理提供给conversion.php的SVG数据,还是有更好的方法


(我不知道XSLT,但我可以试着学习它;我希望尽可能地在PHP中保持净化。使用Windows Server 2008,因此任何使用外部工具的解决方案都需要在该生态系统中可用。)

我正在使用xml和PHP,但我对您的问题一点也不确定。请把它当作一个想法/建议,而不是更多

SimpleXML使用libxml加载xml内容。

可以使用以下方法禁用外部实体:

libxml_disable_entity_loader (TRUE)

在使用simpleXML加载文件之前

然后可以根据SVG模式进行验证

我唯一担心的是svg可能包含脚本元素

此处有关于1.1 DTD的信息:

您可以为SVG DTD提供脚本元素的修改版本或循环元素,以防止脚本元素出现


它并不完美,但至少比没有要好。

您需要使用XML解析器+白名单对SVG进行清理

因为SVG已经有多种执行代码的方法,而且未来的扩展可能会添加其他方法,所以不能将“已知的危险”结构列入黑名单。只要您正确处理所有XML角落案例(例如XSLT样式表、实体扩展、外部实体引用),白名单安全元素和属性就可以工作

示例实现:(MIT许可证)或(GPL v2许可证)

<> P>更多关于攻击向量的信息,在选择支持哪些特征时,你必须考虑:

  • (base64编码部件)
  • (执行代码的不同方式)
  • (在SVG中嵌入HTML,SVG几乎可以做任何XML文件和HTML文件都可以做的事情,使用SVG inside
    允许SVG中的JS在父文档中执行)
  • (过滤SVG非常困难,即使WordPress对于用户提交的SVG文件也没有很好的解决方案)
  • (误用不同API的一些已知SVG攻击列表)
  • (不同的编码方式,巧妙地使用空格来避免检测,xml技巧)

您可以使用SVG消毒包:

在编写此答案的日期安装了500k

use enshrined\svgSanitize\Sanitizer;

// Create a new sanitizer instance
$sanitizer = new Sanitizer();

// Load the dirty svg
$dirtySVG = file_get_contents('filthy.svg');

// Pass it to the sanitizer and get it back clean
$cleanSVG = $sanitizer->sanitize($dirtySVG);

// Now do what you want with your clean SVG/XML data

今年早些时候,我问了一个问题,但没被咬多少口。如果不使用1.2(或Inkscape文档中的任何扩展名),您可以根据1.1规范进行验证。请参阅my other。从安全角度看,如果您处理的是可能受污染的SVG文件,主要是剥离XML实体。我认为它们没有任何用处,但是。@halfer-谢谢,但是该死!我曾希望有人能拉开窗帘,展示一个类似的圣诞奇迹。呵呵,那太好了!我一直想回到那个项目,但因为它是空闲时间F/OSS,所以它被搁置了很多。点击这里如果你有任何运气,我应该有兴趣看看你想出了什么。我也想看到一个解决方案,但目前没有现实世界中使用它虽然。如果一个月内没有人给出解决方案,我会悬赏。我已经把这个问题标上了星号,所以我会关注它。
script
元素并不是唯一的问题。请参见记住也要测试实体处理。例如:
&test请不要只是发布一些工具或库作为答案。至少在答案中说明。请根据更新svg sanitizer的许可证
libxml_disable_entity_loader (TRUE)
use enshrined\svgSanitize\Sanitizer;

// Create a new sanitizer instance
$sanitizer = new Sanitizer();

// Load the dirty svg
$dirtySVG = file_get_contents('filthy.svg');

// Pass it to the sanitizer and get it back clean
$cleanSVG = $sanitizer->sanitize($dirtySVG);

// Now do what you want with your clean SVG/XML data