2012-12-20 25 views
7

Tworzę wykresy w locie jako SVG przy użyciu d3.js. Te wykresy są generowane dynamicznie w oparciu o wybory uwierzytelnionych użytkowników. Po wygenerowaniu tych wykresów użytkownik ma możliwość pobrania wygenerowanego pliku SVG jako pliku PNG lub PDF.Sanitizing SVG przy użyciu PHP

Prąd pracy jest następujący:

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

elementu formularza jest ukryta forma, używany do wysyłania danych:

<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> 

Plik PHP zapisuje wprowadzone dane SVG jako tymczasowy file:

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

Uruchomiono narzędzie do konwersji, które odczytuje plik tymczasowy ($ infile) i tworzy es nowy plik ($ outfile) w określonym pliku $ format (PDF lub PNG). Otrzymany nowy plik jest następnie powrócił do przeglądarki, a pliki tymczasowe są usuwane:

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

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

ja badali converting the SVG to a PNG using JavaScript (canvg(), then toDataURL, then document.write), i mogą to wykorzystać do generowania PNG, ale nie pozwala na konwersję do formatu PDF.

A więc: Jak najlepiej odkażać lub filtrować dane SVG dostarczane do pliku conversion.php, zanim zostanie zapisane w pliku? Jaki jest obecny stan sanityzacji SVG? Co jest dostępne w PHP? Czy powinienem użyć whitelist-based approach do odkażenia danych SVG dostarczonych do conversion.php, czy jest lepszy sposób?

(Nie znam XSLT, chociaż mógłbym spróbować się tego nauczyć, mam nadzieję, że uda mi się utrzymać higienę w PHP tak bardzo, jak to tylko możliwe, używając Windows Server 2008, więc wszelkie rozwiązania wykorzystujące narzędzia zewnętrzne będą musiały być dostępne w ten ekosystem.)

+0

Na początku bieżącego roku zadałem [podobne pytanie] (http://stackoverflow.com/questions/9654664/security-implications-of-letting-users-render-own-svg-files), ale nie otrzymałem wiele ugryzień. Możesz sprawdzić poprawność względem specyfikacji 1.1, jeśli nie korzystasz z wersji 1.2 (lub jakichkolwiek rozszerzeń zgodnie z dokumentem Inkscape), zobacz moje inne [pytanie tutaj] (http://stackoverflow.com/questions/9651493/validating-svg-file -in-php-with-xmlreader). – halfer

+0

Z perspektywy bezpieczeństwa, jeśli przetwarzasz potencjalnie skażone pliki SVG, najważniejsze jest usuwanie elementów XML. Nie sądzę, że służą one jakimkolwiek użytecznym celom, ale [mogą być wykorzystywane złośliwie] (http://blog.jondh.me.uk/2012/09/inkscape-xml-entity-vulnerabilities/). – halfer

+0

@halfer - Dzięki, ale cholernie! Miałem nadzieję, że ktoś odsunie zasłonę, by odsłonić "SVGpurifier" lub porównywalny bożonarodzeniowy cud. –

Odpowiedz

2

Pracuję z xml i PHP, ale nie jestem pewien na twoje pytanie. Proszę przyjąć to jako pomysł/sugestię, a nie więcej.

SimpleXML używa libxml do załadowania treści XML. http://www.php.net/manual/en/simplexml.requirements.php

Można wyłączyć podmioty zewnętrzne za pomocą:

libxml_disable_entity_loader (TRUE) 

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

przed załadowaniem pliku z SimpleXML.

Następnie można potwierdzić na schemacie SVG

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

Jedynym problemem jest to, że widzę SVG może zawierać elementu skryptu. http://www.w3.org/TR/SVG/script.html#ScriptElement

informacja o 1.1 DTD Tu: 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

może podać SVG DTD ze zmodyfikowaną wersją elementu skryptu lub pętli poprzez elementów zapobiegania element skryptu być obecny.

Nie będzie idealnie, ale przynajmniej lepiej niż nic.

Powiązane problemy