10

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

FORM 要素は非表示のフォームで、データを 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>

PHP ファイルは、提供された SVG データを一時ファイルとして保存します。

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

一時ファイル ($infile) を読み取り、指定された $fileformat (PDF または PNG) で新しいファイル ($outfile) を作成する変換ユーティリティが実行されます。結果の新しいファイルがブラウザーに返され、一時ファイルが削除されます。

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

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

JavaScript (canvg()、次に toDataURL、次に document.write) を使用して SVG を PNG に変換することを調査しましたが、これを使用して PNG を生成できますが、PDF への変換はできません。

そう: ファイルに書き込まれる前に、conversion.php に提供される SVG データを最適にサニタイズまたはフィルタリングするにはどうすればよいでしょうか? SVG サニタイズの現状は? PHP 内で利用できるものは何ですか? conversion.php に提供された SVG データをサニタイズするため のホワイトリスト ベースのアプローチを使用する必要がありますか、それともより良い方法がありますか?

(XSLT はわかりませんが、勉強してみることはできます。できるだけ PHP 内でサニタイズを維持したいと考えています。Windows Server 2008 を使用しているため、外部ツールを使用するソリューションはすべて、そのエコシステム内で利用できる必要があります。)

4

3 に答える 3

3

私はxmlとPHPで作業していますが、あなたの質問についてはまったくわかりません. それ以上ではなく、アイデア/提案として受け取ってください。

SimpleXML は libxml を使用して xml コンテンツをロードします。 http://www.php.net/manual/en/simplexml.requirements.php

以下を使用して、外部エンティティを無効にすることができます。

libxml_disable_entity_loader (TRUE)

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

simpleXML でファイルをロードする前に。

次に、SVG スキーマに対して検証できます

http://us3.php.net/manual/en/domdocument.schemavalidate.php または http://us3.php.net/manual/en/domdocument.validate.php

私が目にする唯一の懸念は、svg にスクリプト要素が含まれる可能性があることです。http://www.w3.org/TR/SVG/script.html#ScriptElement

1.1 DTD に関する情報はこちら: 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

SVG DTD にスクリプト要素の修正バージョンを提供するか、要素をループして、スクリプト要素が存在しないようにすることができます。

完璧ではありませんが、少なくとも何もないよりはましです。

于 2013-03-04T17:34:03.340 に答える
3

XML パーサーとホワイトリストを使用して SVG をサニタイズする必要があります。

SVG には既にコードを実行する複数の方法があり、将来の拡張機能が追加のメソッドを追加する可能性があるため、単に「既知の危険な」構造をブラックリストに載せることはできません。すべての XML コーナー ケース (例: XSLT スタイルシート、エンティティ展開、外部エンティティ参照) を正しく処理する限り、安全な要素と属性をホワイトリストに登録することは機能します。

実装例: https://github.com/alnorris/SVG-Sanitizer/blob/master/SvgSanitizer.php (MIT ライセンス) またはhttps://github.com/darylldoyle/svg-sanitizer (GPL v2 ライセンス)

サポートする機能を選択する際に考慮する必要がある攻撃ベクトルに関する詳細情報:

于 2018-08-28T07:54:22.007 に答える