2012-12-20 11 views
7

Ich erstellen Diagramme im laufenden Betrieb als SVGs mit d3.js. Diese Diagramme werden basierend auf der Auswahl authentifizierter Benutzer dynamisch generiert. Sobald diese Diagramme erstellt sind, hat der Benutzer die Möglichkeit, das generierte SVG als PNG oder PDF herunterzuladen.Sanieren SVG mit PHP

Der aktuelle Workflow ist die folgende:

// 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(); 

Das FORM-Element ist eine versteckte Form, verwendet, um die Daten POST:

<form id="svgform" method="post" action="conversion.php"> 
    <input type="hidden" id="output_format" name="output_format" value=""> 
    <input type="hidden" id="data" name="data" value=""> 
</form> 

Die PHP-Datei speichert die bereitgestellten SVG-Daten als temporäre Datei:

// check for valid session, etc - omitted for brevity 

$xmldat = $_POST['data']; // serialized XML representing the SVG element 
if(simplexml_load_string($xmldat)===FALSE) { die; } // reject invalid XML 

$fileformat = $_POST['output_format']; // chosen format for output; PNG or PDF 
if ($fileformat != "pdf" && $fileformat != "png"){ die; } // limited options for format 
$fileformat = escapeshellarg($fileformat); // escape shell arguments that might have snuck in 

// generate temporary file names with tempnam() - omitted for brevity 

$handle = fopen($infile, "w"); 
fwrite($handle, $xmldat); 
fclose($handle); 

Ein Konvertierungsprogramm wird ausgeführt, das die temporäre Datei ($ infile) und creat liest Es gibt eine neue Datei ($ outfile) im angegebenen $ Dateiformat (PDF oder PNG). Die daraus resultierende neue Datei wird dann an den Browser zurückgegeben, und die temporären Dateien werden gelöscht:

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

unlink($infile); // delete temporary infile 
unlink($outfile); // delete temporary outfile 

I converting the SVG to a PNG using JavaScript (canvg(), then toDataURL, then document.write) sucht haben, und dies kann die PNGs zur Erzeugung verwenden, aber es erlaubt keine Konvertierung in PDF.

So: Wie kann ich die SVG-Daten, die in der conversion.php bereitgestellt werden, am besten bereinigen oder filtern, bevor sie in eine Datei geschrieben werden? Wie ist der aktuelle Stand der SVG-Bereinigung? Was ist in PHP verfügbar? Sollte ich mit einem whitelist-based approach gehen, um die SVG-Daten zu bereinigen, die conversion.php zur Verfügung gestellt werden, oder gibt es einen besseren Weg?

(Ich weiß nicht, XSLT, obwohl ich versuchen könnte, es zu lernen; Ich hoffe, die Bereinigung in PHP so weit wie möglich zu halten. Mit Windows Server 2008, so dass alle Lösungen, die externe Tools verwenden müssen innerhalb verfügbar sein Dieses Ökosystem.)

+0

Ich fragte eine ähnliche Frage (http://stackoverflow.com/questions/9654664/security-implications-of-letting-users-render-own-svg-files) Anfang dieses Jahres, aber nicht bekommen viele Bisse. Sie können die 1.1-Spezifikation überprüfen, wenn Sie nicht 1.2 (oder Erweiterungen wie in einem Inkscape-Dokument) verwenden, siehe meine andere [Frage hier] (http://stackoverflow.com/questions/9651493/validating-svg-file) -in-php-mit-xmlreader). – halfer

+0

Wenn Sie potenziell beschädigte SVG-Dateien behandeln, müssen Sie aus Sicherheitsgründen XML-Entitäten entfernen. Ich denke nicht, dass sie irgendeinen nützlichen Zweck haben, aber [können böswillig verwendet werden] (http://blog.jondh.me.uk/2012/09/inkscape-xml-entity-vulnerabilities/). – halfer

+0

@halfer - Danke, aber verdammt! Ich hatte gehofft, jemand würde einen Vorhang zurückziehen, um 'SVGpurifier' oder ein vergleichbares Weihnachtswunder zu enthüllen. –

Antwort

2

Ich arbeite mit XML und PHP, aber ich bin überhaupt nicht sicher für Ihre Frage. Bitte nimm es als Idee/Vorschlag, nicht mehr.

SimpleXML Verwenden Sie libxml, um den XML-Inhalt zu laden. http://www.php.net/manual/en/simplexml.requirements.php

Sie können die externen Einheiten deaktivieren mit:

libxml_disable_entity_loader (TRUE) 

http://www.php.net/manual/en/function.libxml-disable-entity-loader.php

bevor Sie Ihre Datei mit SimpleXML laden.

Dann könnten Sie gegen SVG-Schema validieren

http://us3.php.net/manual/en/domdocument.schemavalidate.php oder http://us3.php.net/manual/en/domdocument.validate.php

Die einzige Sorge, die ich sehen würde, ist, dass svg könnte Skript-Element enthalten. http://www.w3.org/TR/SVG/script.html#ScriptElement

Es Informationen über 1.1 DTD hier: http://www.w3.org/Graphics/SVG/1.1/DTD/svg-framework.mod http://www.w3.org/TR/2003/REC-SVG11-20030114/REC-SVG11-20030114.pdf

Sie könnten einen SVG-DTD mit einer modifizierten Version des Skripts Elements oder eine Schleife durch die Elemente liefern das Skript Element zu verhindern, anwesend zu sein.

Es wird nicht perfekt sein, aber zumindest besser als nichts.