やりたいことと試したこと
HTMLの構造を把握し、中身をチェックした上で改めて適切なHTMLを再構築したいと考えております。
調査した結果、そのための手段としてDOMを利用することが考えられることがわかり、例えば以下のようなコードを実行してみました。
html
1<!--$dataの中身--> 2<div id="wrapper"> 3 <p class="hoge" style="color:black;" onclick="js_alert()">aa<span style="background-color:hsl(60, 75%, 60%);">bb</span>aaa</p> 4 <img src="javascript:alert('XSS!');"> 5 <p class="piyo"> 6 <script>alert("XSS!")</script> 7 </p> 8</div>
php
1 $dom = new DOMDocument(); 2 $dom -> loadHTML($data); 3 $childNodes = $dom->getElementById('wrapper')->childNodes; 4 foreach ($childNodes as $key) { 5 var_dump($key->textContent);//aabbaaa 6 echo "<br>"; 7 var_dump($key->tagName); 8 if($key->tagName==="script"){ 9 //無害化 10 } 11 echo "<br>"; 12 var_dump($key->attributes); 13 if($key->tagName==="img" && substr($key->getAttribute('src'),0,4)==="java") 14 { 15 //無害化 16 } 17 echo "<br>"; 18 //再帰的な処理をして繰り返す 19 var_dump($key->childNodes); 20 }
問題点
ここに来て、いくつか解決すべき問題点に2つに気がつきました。
-
実際にHTMLの構造は深いものもあり、上記の自前で用意したHTMLではどこまでchildNodesを追跡すれば良いのか全貌がわかっているので対応できるのですが、HTML構造を事前に知らない場合など、DOMを利用してどのような方法で再帰的に走査することが一般的なのでしょうか? DomdocumentクラスのchildNodesプロパティで取得できる事は分かったのですが、NULLになるまで繰り返すようなやり方はしないと思うので、アドバイスをいただきたいです。
-
また、構造に関連して
var_dump($key->textContent);//aabbaaa
について、テキストノードの中に要素ノードが混ざる場合でも、どの位置に要素ノードが入るかが示されず、textContentではaabbaaaを返してきます。このようなケースではDOMを利用してどのようにテキストと要素ノードの順番を解釈すれば良いのでしょうか?特にこの問題があるため↓#3のHTMLの再構築が非常に困難と感じています。 -
一般的に、DOMを利用して、上記のように解析した結果を踏まえてHTMLを再構築する場合、どのようなアプローチが取られるのでしょうか? まだ、無知な私には上記の走査を通じて、再構築しやすいような連想配列やJSON形式のデータを用意して、そこから一定のルールでechoしていくようなことくらいしか思いつかないのですが、一般的に採られる方法についてアドバイスを頂ければと思います。例えば、再構築目的の連想配列は以下のようなイメージです。あくまでイメージで、、全くとるべきアプローチとして間違っているのであればご指摘いただきたいです。。
php
1$ary = 2[ 3 [ 4 "tag"=>"p", 5 "attr"=> 6 ["class","style"], //onclickは消毒済み 7 "content1"=>"aa", 8 "content2"=>"aaa", 9 "insertTag"=> 10 [ 11 "tag"=>"span", 12 "attr"=>"class", 13 "content1"=>"bbb" 14 "insertTag" => NULL 15 ] 16 ] 17 18 [ 19 "tag"=>"img",//以下省略 20 ] 21]
回答1件
あなたの回答
tips
プレビュー