~ モバイル版(スマートフォン)の操作 ~
左右にスワイプすると、前後の投稿へ移動します。
← 前の投稿 | 次の投稿 →
日々のコンピュータ情報の集積と整理

Dr.ウーパのコンピュータ備忘録

2015年2月27日金曜日

JavaScript:document.createTextNodeをappendChildしたときの、HTMLはどうなっているか?


スポンサーリンク

イントロダクション

JavaScript にて、「DOM Based XSS」の脆弱性を埋め込むのを防ぐためには、document.write や element.innerHTML などを使うのではなく、以下のように DOM 操作用メソッドを使用すると良いとされています。

入力されたテキストをブラウザのドキュメントに表示:
element.appendChild(document.createTextNode(input_text));

input_text : 入力されたテキスト
element : テキストを追加する親要素(element オブジェクト)


このとき、テキストを追加した親要素の HTML が、入力されたテキストによってどうなるのか気になりませんか?

そこで、実際に JavaScript でコードを作成して試してみました。

element.appendChild(document.createTextNode(input_text))のHTMLはどうなるか?

element.appendChild(document.createTextNode(input_text)) の HTML がどうなるのかを確かめるため、次の検証用 JavaScript コードを作成しました。


実験用コード:

<form onsubmit="return false;">
<b>input_text:</b><br />
<textarea id="input-text" rows="4" cols="80">
&lt;script type="text/javascript"&gt;alert("a");&lt;/script&gt;
</textarea><br />

例)&lt;script type="text/javascript"&gt;alert("a");&lt;/script&gt;<br />

<input type="button" value="実行" onclick="runTest_createTextNode_appendChild_innerHTML();" /><br />

</form>
<br />

<b>element.appendChild(document.createTextNode(input_text))のinnerHTML:</b><br />
<textarea id="output-html" rows="4" cols="80">
ここにデータ出力
</textarea><br />

<b>input_text(確認用):</b><br />
<textarea id="input-text-viewer" rows="4" cols="80">
ここにデータ出力
</textarea><br />

<script type="text/javascript">
<!--

    function runTest_createTextNode_appendChild_innerHTML() {
        var input_text = document.getElementById("input-text").value;

        var parentElement = document.createElement("div");
        parentElement.appendChild(document.createTextNode(input_text));

        document.getElementById("output-html").value = parentElement.innerHTML;
        document.getElementById("input-text-viewer").value = input_text;
    }

//-->
</script>


textarea に入力されたテキストデータ(input-text)に対して、element.appendChild(document.createTextNode(input_text)) を実行し、その innerHTML を textarea (output-html)に出力しています。

また、入力されたテキストデータ(input-text)が何らかの要因によって、勝手に変換されていないことを確認するために、最後に 入力されたテキストデータ(input-text) を textarea (input-text-viewer)に出力しています。


実験結果:

次のテキストデータを入力した時の、element.appendChild(document.createTextNode(input_text)) の innerHTML を見てみます。

入力テキストデータ(input-text):
<script type="text/javascript">alert("a");</script>

element.appendChild(document.createTextNode(input_text))のinnerHTML:
&lt;script type="text/javascript"&gt;alert("a");&lt;/script&gt;

input_text(確認用):
<script type="text/javascript">alert("a");</script>


このように、入力されたテキストデータに HTML のタグが入っていたとしても、HTML のタグとはみなされずエスケープ処理されていることが分かります。

従って、HTML 文書内に表示しようとしたテキストに、意図しない HTML タグを混入し、HTML タグとして解釈させて任意の動作を行わせるような DOM Based XSS を防止することができます。


JavaScript にて、「DOM Based XSS」の脆弱性を埋め込むのを防ぐためには、このような DOM 操作用メソッドを使用すると、確かに安全に入力データを扱うことができることが分かりました。


なお、実際に動作する上記のプログラムを、以下に設置しておきましたので、試したいデータがあれば、試してみてください。


実験用プログラム:

input_text:

例)<script type="text/javascript">alert("a");</script>


element.appendChild(document.createTextNode(input_text))のinnerHTML:

input_text(確認用):



関連記事

セキュリティ対策:JavaScriptでHTML操作をする人は必読!IPAテクニカルウォッチ 『DOM Based XSS』に関するレポート
http://upa-pc.blogspot.com/2015/02/javascript-dom-based-xss-ipa.html

JavaScript:element.setAttributeしたときの、HTMLはどうなっているか?
http://upa-pc.blogspot.com/2015/02/javascript-dom-based-xss-protect-setAttribute.html


スポンサーリンク

コメントを投稿

コメント投稿機能について