クロスサイトスクリプティングはhtmlspecialcharsでOK??

先日とあるPHPで作られたウェブアプリのテスト中にこんなことがありました。

そのPHPで作られたウェブアプリは、値をHTML出力する際、「htmlspecialchars($output, ENT_QUOTES)」と指定することで、「"'&<>」をサニタイジングしています。

しかしながらクロスサイトスクリプティングすることが可能でした。

それは何故か???

答えはhref属性に指定されているjavascript内に値を出力されていたからでした。
具体的には下みたいな感じです。

  • 下記のようなコードあります。($outputはhidden値によりPOSTされた値)
<a href="javascript:hoge('<?php htmlspecialchars($output, ENT_QUOTES) ?>')">リンク</a>
  • $outputの値に、「');alert('XSS」を指定します。
  • これをHTMLで出力すると下記のようになります。
<a href="javascript:hoge('&#039;);alert(&#039;XSS')">リンク</a>
  • これだとhoge関数のみしか実行されなさそうですが、実際には埋め込んだalert関数も実行されてしまい、XSSが成功してしまいます。(hoge関数が定義されていないとエラーになります。)

つまり、上記のようなHTML属性値に記述されたjavascriptコード内では、HTMLコードにサニタイジングされた値は元の値(「'」は「'」)として評価されます。

ということで場所によってはサニタイジングしていればOKというわけではないのでした。

ちなみにscriptタグ内では、HTMLコードはそのままHTMLコード(「'」は「'」)としてそのまま評価されるため、上記のようなXSSは発生しません。

またまだ勉強中ですので、間違いなどあればご指摘ください。