ラムネグから一言:寝る前に読むとくだらなすぎて逆に寝れると好評なすごい適当なブログをこっちではじめてます.
いや、ほんっとに怖い思いをしました。
php側でhtmlspecialcharsを使ってちゃんとサニタイズしてたんですが、そのサニタイズ済みテキストをjavascript側でいじって(replaceで置換)、そしてjqueryのhtml()を使ってそのいじった後のテキストを元のテキストの場所に入れたんです。
んじゃサニタイズ関係なく普通にタグが有効に…。
よくあるXSS攻撃の例としてある「<script>alret("test");</script>
」とかも普通に実行されてしまって、アラートでちゃう。
ここではjavascriptのinnerHTML、それからjqueryのhtml()を使うのは避けた方がいい、というのと、んじゃ代替手段は?というのを書きたいです。
html()とinnerHTMLの問題点
html()とかinnerHTMLでテキストを取得するのは問題ないんですが、これら関数を使ってテキストを設定する際にXSS問題が発生します。
javascriptのinnerHTMLは今は非推奨になってるっぽいですが、これはその中のHTMLタグを全部そのまま取得したり設定したりする関数になってるんで、php側できちんと「<
」とか「>
」とかをエスケープ処理したタグでも「あ、これHTMLの部品だよね!んじゃ有効にしちゃうかんねー!」で有効になってしまってるっぽい。
「っぽい」というのはそれをきちんと書いた言語仕様を見つけられなかったため。なのでやってみたらそうなってるよね、で書いています。
で、さらにjqueryのhtml()はたぶん内部でjavascriptのinnerHTMLを呼んでるんじゃないかなーって思います。試してみると同じ挙動で、phpでサニタイズしてても関係なくそのタグが有効になっていました。
代替手段
そのテキストに改行が含まれていないのなら、jqueryのtext()、javascriptのtextContentでオッケー。
代替手段2
改行が含まれているならjavascriptのinnerTextでオッケー。
というか特に大きな理由がないならinnerTextを使うのがいいと思います。改行もきちんと対応してくれるし、試した限りデメリットがなかったです。
まとめ
ここではjqueryのhtml()とjavascriptのinnerHTMLを使ってテキストを設定する際はサニタイジングに気を付けよう、という事を書きました。
取得するのは問題ないんで、設定するときだけはjqueryのhtml()とjavascriptのinnerHTMLを使うのは避けた方が無難です。もっというとそういうXSSの脆弱性が出てくるんで、可能なら取得時も違う関数(textContent,text(),innerText)を使う方がおすすめです。その方が後からソースコードを見直す際、ヒヤッとするのを防げます。grepですぐにその脆弱性を探せるのもグッド(取得時にhtml()やinnerHTMLを使っているとgrepで検索はできてしまうんでいちいちコードを目で追う必要がある)。
参考にしてみてくださいね。
【おしらせ、というか完全なる宣伝】
文体がもうぜんぜん適当すぎてあれだけどものすごい自由に書いてるブログ「檸檬だくだく」もよろしく.寝る前に読める恐ろしくくだらないやつです.
こんなにも一ミリも目を引かれないタイトルを取り扱ってます: ココア20g / ハイチュウとかってさ / なぜ米と小麦を食べようと思ったのかの謎 /