2012-05-01 46 views
7

HTML属性コンテキストの信頼できないデータをエンコードする適切な方法は何ですか?たとえば:PHP:HTML属性エンコーディング/ JavaScriptデコード

<input type="hidden" value="<?php echo htmlentities($data); ?>" /> 

は、しかし、私は最近、私が合格するために必要なデータだったとき、これは自分のアプリケーションを壊した問題に遭遇した:

<input type="hidden" value="<?php echo $data; ?>" /> 

私は通常これを行うためにhtmlentities()htmlspecialchars()を使用しますページの場所を変更するためにJavaScriptにハンドオフされるために必要なURL:この場合

<input id="foo" type="hidden" value="foo?bar=1&amp;baz=2" /> 
<script> 
    // ... 
    window.location = document.getElementById('foo').value; 
    // ... 
</script> 

を、fooはCのプログラムであり、 URLとsegfaultのエンコードされた文字は理解できません。

JavaScriptで値を取得してvalue.replace('&amp;', '&')のようにしてもかまいませんが、それはクルージュに見えますが、アンパサンドのみで動作します。

私の質問は、HTML属性に注入されるデータのエンコードまたはデコードについてのより良い方法はありますか?

私はOWASP's XSS Prevention Cheatsheetのすべてを読んだことがある、と限り、私は自分の属性を引用するように注意していて、その後、私はエンコードする必要がある唯一の文字が引用符自体(")であるように、それは私に聞こえる - その場合は、I str_replace('"', '&quot;', ...)のようなものを使うことができますが、正しく理解しているかどうかはわかりません。

+2

を見つけることができますか?コメントにPHPのマニュアルでXSSを保護する方法を示すコード例はほとんどありません。 http://php.net/manual/en/function.urlencode.php – GillesC

+0

@gillesc: 'urlencode()'は、URL属性ではなく、URL *パラメータ*をエンコードするためのもので、HTML属性コンテキストのためにエンコードしません。このマニュアルでは、このことについても議論するセクションがあります。*「そのままで、htmlentities()またはhtmlspecialchars()を使用してURLをエンコードしてください」* – FtDRbwLXw6

+0

あなたは 'window.location = document.getElementById( 'foo'); '?これは私が思うようにすべきです - > 'window.location = document.getElementById( 'foo')。value;'そして右ページにリダイレクトされます(foo?bar = 1&baz = 2) – ocanal

答えて

11

htmlentities()htmlspecialchars()を使用してのあなたの現在の方法は正しいアプローチです。

あなたが提供した例は、正しいHTMLである:

<input id="foo" type="hidden" value="foo?bar=1&amp;baz=2" /> 

value属性にアンパサンドは確かにそうでない場合は、あなたのHTMLが無効である、HTMLエンコードする必要がありません。ほとんどのブラウザは、そこにある&で正しく解析しますが、無効であり、エンコードするのが正しいという事実は変わりません。

あなたの問題は値のエンコーディングにはありません。これは良いことですが、正しくデコードしないJavascriptコードを使用しているという事実にあります。

JSコードがDOMにアクセスしており、DOMがデコードされた値を返す必要があるため、実際にはこれに驚いています。私は自分自身にこれを証明するためにJSfiddleを書いた

http://jsfiddle.net/qRd4Z/

はこれを実行すると、それは私が期待としてデコード値との警告ボックスを提供します。 console.logに変更すると、私が期待した結果も得られます。だからなぜあなたは別の結果を得ているのか分かりません。おそらくあなたは別のブラウザを使用していますか?あなたがテストしているものを指定する価値があります。あるいは間違ってエンティティをダブルエンコードしたのでしょうか?そうでないことを確認できますか?

0

あなたは値をデコードするためにDOMを使用することができます。これに

'http://someurl.com/foo?bar=1&amp;baz=2' 

decodeHTMLSpecialChars('http://someurl.com/foo?bar=1&amp;baz=2'); 
// => 'http://someurl.com/foo?bar=1&baz=2 

そして、いや、HTMLのための

function decodeHTMLSpecialChars(input){ 
    var div = document.createElement('div'); 
    div.innerHTML = input; 
    return div.childNodes.length === 0 ? "" : div.childNodes[0].nodeValue; 
} 

これには次の文字列をレンダリングしますエンコードとデコード、htmlspecialcharsとhtmlエスケープは標準的な方法であり、仕事をしているあなたのために良い。

5

HTML属性コンテキストの信頼できないデータをエンコードする適切な方法は何ですか?

属性値の前後に二重引用符を追加すると、htmlspecialchars()で十分です。

<input id="foo" type="hidden" value="foo?bar=1&amp;baz=2" /> 

これは正しく、ブラウザはfoo?bar=1&baz=2&amp;をデコード)サーバーに送信されます。サーバーにfoo?bar=1&baz=2が表示されない場合は、値を2回エンコードする必要があります。

javascriptで値を取得すると、foo?bar=1&baz=2も返されます(document.getElementById('foo').valuefoo?bar=1&baz=2を返す必要があります)。

ブラウザを使用してページのソースを表示し、入力フィールドの実際のソースを確認してください。

Javascriptを使用して入力フィールドの値を変更する場合、スクリプトはそれをダブルエンコードする必要があります。

ところで、あなたのプログラムが原因で誤ったユーザー入力のセグメンテーションフォールトべきではありません。)

0

htmlentitiesを使用すると、それはdoesnのであるように注意してください助けて!デフォルトでは

それはちょうどそれが問題を作成することができます'をエスケープしません" < > &

をコードしています!

はあなたが機能するためにフラグを使用していることを確認し、あなたはPHPでそのの世話をURLENCODEない使用方法および使用例here

+0

ありがとうございますが、これは属性値を '' '文字で正しく区切らないと問題になります。デリミタを除外するか、' 'で区切るのは悪い習慣です。 – FtDRbwLXw6

関連する問題