MODXで作成されたサイトのページ内アンカー#に上手く飛べない…という悩みに対する回答として、 BaseURL Same-Page-Link Fix が紹介されるケースが良くありますが(このフォーラムでも過去に何度か出てるようです)、このコードにxss脆弱性の要因になりかねない箇所があるようです。
コード: 全て選択
// here the link is replaced with the full path, plus the anchor reference:
$source = str_replace($doubleQuote, 'href="'.$_SERVER["REQUEST_URI"].'#', $source);
$source = str_replace($option_value, '<option value="'.$_SERVER["REQUEST_URI"].'#', $source);
// uncomment these lines if you want to check for single quotes or no quotes:
//$source = str_replace($singleQuote, "href='".$_SERVER["REQUEST_URI"].'#', $source);
//$source = str_replace($noQuote, 'href='.$_SERVER["REQUEST_URI"].'#', $source);
実際の所、普通のブラウザ経由でのリクエストだと攻撃コードの一部がエンコードされてしまったりして上手くいかないのですが、生コードをリクエストできるようなツール(Fiddler2とか)を使って
GET /hogehoge.html(#が含まれているページ)?”><script>alert(document.cookie)</script>...
などとリクエストすると#やopitonが存在する位置に目的のコードが入り込んだレスポンスを得られることは確認できました。
xss脆弱性の利用目的と普通のブラウザでは再現させにくいことを考え、また得られたhtmlレスポンスが文法的には破損したものになるので、実際にコードが実行されるかどうかは元のソース次第の部分もあり、個人的には大きな問題に繋がらないと思うのですが、某所でXSS脆弱性として指摘されてしまったので BaseURL Same-Page-Link Fix の使用に心当たりのあるユーザは念のため確認されることをお奨めします…。
問題の箇所を
コード: 全て選択
htmlspecialchars($_SERVER["REQUEST_URI"], ENT_QUOTES)
※最近はページ内の#にはJavascriptで、すい~っとスクロールさせて移動させるケースが大半で BaseURL Same-Page-Link Fix のようなことをする必要も無かったのですが、古いサイトで引っかかってしまいました…。htmlspecialchars の使い方については、他にも phx のget,post,esc 辺り、本体コードにも由来が古そうな所に第1引数のみのhtmlspecialcharsが結構あります。使用目的、それが表のhtmlに現れる部分なのかで第2引数をどうするか、個別に考える必要があるとは思いますが、phxの使われ方を考えると単体phxのget,post,esc(何れも第2引数無しのhtmlspecialchars を使ってます)は危険かな…と思っています(get,postを信用せず :escを使ったつもりが、結果的にシングルクオートを通して脆弱性テストに引っかかったのは内緒にしたいところです。自分の目でソースを確認しなかったのが悪いのですが)。