web-dev-qa-db-ja.com

javascriptでhtmlをエスケープ解除する方法は?

私は次のような値を提供するWebサービスを使用しています。

var text = "<<<&&&";

そして、これをjavascriptで「<<< &&&」のように印刷する必要があります。

しかし、ここに問題があります:内部HTMLを使用できません(実際には、テキストノードを作成するプロトタイプライブラリにこの値を送信しているため、生のhtml文字列をエスケープ解除しません。ライブラリの編集がオプションではない場合は、どのようにこのhtmlをエスケープ解除しますか?

ここで実際の取引を理解する必要がありますが、このタイプの文字列をエスケープしないリスクは何ですか? innerHTMLはどのように機能しますか?そして他にどのようなオプションがありますか?

[〜#〜] edit [〜#〜]-問題は、javascriptの通常のエスケープ/エスケープ解除またはjQuery /プロトタイプの実装を使用することではなく、これの...別名「彼らはそれらを使用することはかなり安全ではないと私に言った」

(この奇妙な文字列をエスケープしないinnerHTMLで何を話しているのかを理解しようとしている人は、次の簡単な例を確認してください。

<html>
<head>
<title>createTextNode example</title>

<script type="text/javascript">

var text = "&lt;&lt;&lt;&amp;&amp;&amp;";
function addTextNode(){
    var newtext = document.createTextNode(text);
    var para = document.getElementById("p1");
    para.appendChild(newtext);
}
function innerHTMLTest(){
    var para = document.getElementById("p1");
    para.innerHTML = text;
}
</script>
</head>

<body>
<div style="border: 1px solid red">
<p id="p1">First line of paragraph.<br /></p>
</div><br />

<button onclick="addTextNode();">add another textNode.</button>
<button onclick="innerHTMLTest();">test innerHTML.</button>

</body>
</html>
17
DFectuoso

テスト文字列を_&lt;b&gt;&lt;&lt;&amp;&amp;&amp;&lt;/b&gt;_に変更して、リスクをより適切に処理します...(または、Cookieを盗むスパムの場合は&lt;img src='http://www.spam.com/ASSETS/0EE75B480E5B450F807117E06219CDA6/spamReg.png' onload='alert(document.cookie);'&gt;

http://jsbin.com/uveme/139/ の例を参照してください(例に基づいて、エスケープ解除にプロトタイプを使用します。)4つの異なるボタンをクリックして、さまざまな効果を確認してください。最後の1つだけがセキュリティリスクです。 (ソースは http://jsbin.com/uveme/139/edit で表示/編集できます)この例は実際にはCookieを盗みません...

  1. テキストが既知の安全なソースからのものであり、ユーザー入力に基づいていない場合、その後、あなたは安全です。
  2. createTextNodeを使用してテキストノードを作成し、appendChildを使用してその変更されていないノードオブジェクトをドキュメントに直接挿入する場合、あなたは安全です。
  3. それ以外の場合は、安全でないコンテンツが視聴者のブラウザに届かないように適切な対策を講じる必要があります。

注: Ben Vinegarが指摘しているようにcreateTextNodeの使用は特効薬ではありません。文字列をエスケープするために使用してから、textContentまたはinnerHTMLを使用します。エスケープされたテキストを取り出して他のことをすることは、その後の使用であなたを保護しません。特に、 以下のPeter Brownの回答のescapeHtmlメソッド は、属性の入力に使用される場合は安全ではありません。

11
Stobor

非常に良い読み物は http://benv.ca/2012/10/4/you-are-probably-misusing-DOM-text-methods/ であり、これはcreateTextNodeを使用するという一般通念がなぜであるかを説明しています。実際にはまったく安全ではありません。

リスクの上記の記事からの代表的な例:

function escapeHtml(str) {
    var div = document.createElement('div');
    div.appendChild(document.createTextNode(str));
    return div.innerHTML;
};

var userWebsite = '" onmouseover="alert(\'derp\')" "';
var profileLink = '<a href="' + escapeHtml(userWebsite) + '">Bob</a>';
var div = document.getElementById('target');
div.innerHtml = profileLink;
// <a href="" onmouseover="alert('derp')" "">Bob</a>
5
PETER BROWN

Javascriptで利用可能なエスケープおよびエスケープ解除機能を試してください

詳細: http://www.w3schools.com/jsref/jsref_unescape.asp

2
Anuraj

それが何の価値があるかについてのいくつかの当て推量。

innerHTMLは、文字通りhtehtmlを解釈するブラウザです。

したがって、<は、htmlドキュメントに<を入力した場合に発生するシンボル未満になります。

&を含む文字列の最大のセキュリティリスクはevalステートメントであり、JSONを使用するとアプリケーションが安全でなくなる可能性があります。私はセキュリティの専門家ではありませんが、文字列が文字列のままであれば、大丈夫です。

これは、innerHTMLが安全なもう1つの方法であり、エスケープされていない文字列がhtmlになる途中であるため、javascriptを実行するリスクはありません。

2
Fire Crow
function mailpage()
{ mail_str =  "mailto:?subject= Check out the " + escape( document.title ); 
      mail_str += "&body=" + escape("I thought you might be interested in the " + document.title + ".\n\n" );
      mail_str += escape("You can view it at " + location.href + ".\n\n");
      location.href = mail_str;
}
1
Jan

コードがテキストノードを作成している限り、ブラウザは有害なものをレンダリングしてはなりません。実際、FirebugまたはIE Devツールバーを使用して、生成されたテキストノードのソースを調べると、ブラウザーが特殊文字を再エスケープしていることがわかります。

それに与える

"<script>"

そしてそれはそれを次のように再エスケープします:

"&lt;script&gt;"

ノードには、要素、ドキュメント、テキスト、属性など、いくつかのタイプがあります。

危険なのは、ブラウザが文字列をスクリプトを含むものとして解釈する場合です。 innerHTMLプロパティは、要素ノードを作成するようにブラウザに指示するため、この問題の影響を受けやすくなります。要素ノードの1つは、スクリプト要素であるか、マウスオーバーハンドラなどのインラインJavascriptを持っている可能性があります。テキストノードを作成すると、この問題を回避できます。

1