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