XSS脆弱性修正に失敗してしまった駄目な例(その後)

このエントリーはなに?何がその後なの?

ご参照願います→XSS脆弱性修正に失敗してしまった駄目な例::当日記

その後って?

いえね、別に公的な脆弱性報告窓口のIPAさんから、くだんのサイトについてのその後の連絡がありましたとか、そういうオハナシではないんです。私自身の知見が昨日増えました、というオハナシなんです。

あの頃

あの時長谷川さんから、

<input type=hidden name=foo value='$USEROUTPUT'>
の$USEROUTPUTにおいて、サーバサイドの処理系がダメダメなせいでstyle属性の追加が出来るのであるならば、IEをターゲットとして、expressionをベクターにすれば、hiddenなフィールドでもスクリプトが動いちゃうよ、と教えていただいたのでした。超ビックリだったのですね。

昨日わかったこと

上の事情ですが、IEだけでなく、Firefoxでもなんとかなりそうだと偶然知ったのです。(ver 1.5.0.8の古いので検証)
-moz-bindingで。あ〜ビックリした。

ところで前々から主張している通り

なんでスタイル記述からスクリプトが動きますか。不要

知見が増えました第二弾

知見が増えたというのは、頭のサキッチョでなんとなくわかっている部分ではなくて、カラダでわかって腹にストンと落ちた、という意味なのですが、上記に鑑みての第二弾が昨日発生したのでして。今頃かよ!というお叱りは覚悟の上で恥さらしを以下に試みます。

これは駄目なんです

発現の原因

ユーザ入力をエスケープして $USEROUTPUT とするわけですが、恐るべきことに、エスケープとしては、『>』を『&gt;』に変換しているのみでした。『<』『'』『&』『"』についてはノータッチなのです。

いや、そんなことしてもまだまだ駄目ですから〜、残念っ!>ダメダメな俺。

自分がダメなのにヒトサマのダメぶりをあげへつらい、あまつさえ今日までノンビリ過ごして来たとは・・・謹んで訂正し、お詫び申し上げます。

訂正理由

実体参照(この説明では数値文字参照含む)を、『>』、『<』、『'』、『&』、『"』に施した上で、属性値は必ず括弧で囲んでやって、そうそう、URLが埋め込み可能ならば適切にホワイトリストで処理してやって・・・という私の昨日までのXSS対策の常識が実は非常識であったことを・・・ようやく今頃になって体得した次第なのです。XSSが発動する事例が比較的簡単にみつかるからなのですね。ガックシ。
※というか、昔勤めていた会社の私が作成したウェブサイトのCGIにも思い起こせばこの脆弱性があるのでありました。デモ版がローカルにあったので試したのですが・・・参りました。心底。hiddenフィールドが複数あって・・・汚染されちゃったです。んでスクリプト起動。orz・・・(←だっぷんだ)ま、個人情報を取り扱っているサイトではないはずなので危険度は多少なりとも下がるのですがヨソサマに迷惑がかかるやもしれず。困惑中。現在のお守り役(HTMLが書けないぐらいの一般人です)に連絡するのが精一杯です。転職しちゃったからなぁ。現在ワタクシ非IT労働者だし。

とはいえ(TOWAIE)

とはいえ。定番の実体参照によるエスケープを施してもXSSが発動するのはどういうことなのかと、これは、サーバ側の脆弱性といえるのかどうか。本質的に言えば、これ、サーバ側・サイト側の責任にあらず、ブラウザ側の瑕疵であろうと思われるのであります。昨日試験したのはFirefox。でも原理的にIEでも同じ。それぞれちょっと工夫がいりそうですが。あ、誤解すると困りますので付け加えますが、本日の日記の最初のほうで述べたhiddenなフィールドに関するオハナシに限定しているわけではありません。念のために申し添えます。
※今ここで曖昧に言っていることをお許し下さい。流行すると困るので。

でもでもでも

上で私が述べたことは、既にセキュリティ系のメーリングリストではとっくの昔に述べられまくり済みですし、各種書籍やブログや掲示板やニュースサイトでもそこはかとなく示されている通りなのです。私が昨日したことは、それらなんとなく知っていることを示されている通りにつなぎ合わせてみて結果として体感してみて、うぁぁぁぁぁと腰を抜かしただけのことなのです。
※なお、UTF-7事件その他の、エンコードをわざと変化させるワルサとは違います。そんなのかんけいねぇ、そんなのかんけいねぇ、オッパッピーなのであります。

ブラウザ側の対策がどこまで進んでいるのか

ごめんなさい。よく知りません。どこまで進んでいるのかどうか。遅遅として進んでいないのかもしれず鋭意対策中なのかもしれず。でもたぶん、対策済みのブラウザのパース速度は遅くなると思います。XHTMLならばパースをきちんとしている限り現状でも(たぶん?)ほぼ安心なので体感スピードはそれほど変わらないのかもとも考えます。HTMLがなぁ・・・

サイト側の対策

本来ブラウザ側の責任だと思われますけれども、場合によってはサーバ側で(本来しなくてよいはずの)対策をしておくケースもあろうかと思われます。我慢我慢。
要するに全部過激にエスケープしておきましょう。というきわめて不自然な対策です。この対策、最近言われ始めていますが、ダイッキライなんですよね、ワタシ的にはこの対策。そんなのウェブじゃねぇ、という気持ちがして。
もしくは。ホワイトリストで対策を取りきれないブツをエスケープする際には、たとえばUnicodeへ変換してみてもう一回逆変換してみるとか結果を比較してみて不正な符号がはいっていないことを確認するとか。とにもかくにも人間ならそんな文字列いれないだろうというものは排除ですね。日本語的には。うーん。たとえば属性値を囲む括弧が食われちゃう現象が困るのですから。とっくの昔に述べられまくり済みですけれど。

あ〜あ

今頃になって気がつくとは。セキュ界の皆さんがヒソカに言ってくれていたのにぃ。ん〜。というか今思えば、どうどうと公然と各種メディアのチャンネルでおっしゃっていらっしゃいますので、こんなことがわからなかったのは私が馬鹿なだけなんですぅ。あ〜。
きちんとした技術文書があればいいのになぁ。

最後に

今回の話題とは無関係ですけれど、かつてreferrerでCSRF対策ができていた(とされていた)のに今はそうでないのって、やっぱし、referrerによる対策という本当ならば正しいはずの対策の側の責任ではなくて、人工的な変なreferrerを送出できてしまう側の脆弱性なんだとワタシは思うのですね。

※これまた関係ないけど、同一ドメイン制限を無視してHTTPなやり取りを勝手にしてくれちゃうActionscriptとか、(条件がありますが)IE6とか、もどうかと思いますね、本当に。おまえらの変な実装で世の中が困るんです。

もとい。今日のこのオハナシも、HTML的には、必要最小限の文字に対する実体参照によるエスケープなんて、そもそもXSS対策のためではなくて、HTMLを書いたり吐き出したりする以上、文法上半ば以上、当然のことなのであって。正しい書き方を意識していないからXSS穴ができちゃうわけで。きちんと標準に従ってHTMLを書いたり吐き出したりするサーバサイドのシステムならば、恐らくほとんどXSS的な穴なんてナイはずなんですよね。ところが現実はそうなっていない感じ。うへぇ。必要最小限の文字に対する実体参照によるエスケープだけで防衛可能ということ・・・がなんとかできていて欲しいわけです。

それと・・・「暗黙的に形成する事実標準の話と回避策の話を混同してはいけない」という金言は、とても大事なことだと思います。だから今回の件でも、そもそもブラウザになんとかなって欲しいし。だけどサーバサイドとしては複数のブラウザが修正されるまで待てるのかってハナシにもなるわけです。悩ましい・・・