また騙された

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-3843
http://www.procheckup.com/PDFs/bypassing-dot-NET-ValidateRequest.pdf

動かない!動かない!って思ったら騙されてるだけだった。サンプルコードをコピペして動かすまで気付かなかった。

<tagname <~/XSS/*-*/STYLE=xss:e/**/xpression(alert('XSS'))>

チルダとか関係なくて左のタグのstyle属性として認識されているだけという落ち。

セッション変数使用時の注意点

http://d.hatena.ne.jp/teracc/20080225#1203957135
寺田さんの日記より

私が問題だと思うのは、「hiddenの改竄」はWebアプリケーションの開発者の人たちに割と認知されているようですが、セッション変数を使う場合に生じうることは、一般に余り認知されていないように思われることです。

ものすごく同感です。セッション変数を使用する際に注意すべきポイントは、hiddenを使用する際に注意すべきポイントよりも数多いのに・・・
この辺りをまとめた記事を書く予定だったのですが、うまくまとめられなかったので没となってしまいました^^;
簡潔な説明がなかなか難しい問題であるとも思います。

jpドメインはcomドメインよりも優れている

ドメインの中には、技術文書内での例示に使用できるようあらかじめ予約されているものがあります。
これは、予約ドメインと呼ばれるもので、RFC2606には以下の3つが定義されています。

しかし、これだとセカンドレベルドメインを併記したい場合に困ります。

と併記する

  • .com

が書けない訳です。
実在するドメイン名を使用してしまうと、その持ち主に迷惑がかかってしまいます。これは困ったな・・・と悩んでいたら、jpドメインでは、example0.jp〜example9.jpという複数の例示用ドメインが用意されているということを教えてもらいました。http://jprs.jp/info/notice/200508-rule.html
これなら

  • example0.jp
  • example1.jp
  • example2.jp
  • example3.jp
  • example4.jp
  • example5.jp
  • example6.jp
  • example7.jp
  • example8.jp
  • example9.jp

と書き放題です。
個人的には、とっても感動しました。これからは、comドメインよりもjpドメインがメジャーになっていく気がしています。

null文字のPOST

HTMLからnull文字をPOSTする方法を調べていたら、こんな時間になってしまいました。
数値文字参照とか\x00とかでは駄目なのですね・・・
%00じゃないホントのnullが送りたい。
出来るのか出来ないのかすらよく分らない。
勉強が足りないな・・・

価格をPOSTすることの是非

価格をPOSTすることの是非が議論されているようですが、これ単体を取って脆弱であると判断するのは確かに微妙ですね。
一般的に商品の価格は永久に固定である訳ではなく更新される可能性があります。そういえば、マクドナルドでも価格の改定がありましたね。気付いたのは最近ですけれども。
さて、商品の価格が変動する可能性のあるアプリケーションの実装を検討してみましょう。
ユーザが商品を選択し確認画面に遷移したタイミングでは、価格が100円だっとします。ところが、注文を確定したタイミングでは、200円に値上がりしていました。これをシステム的にどう処理するのが望ましいでしょうか?
200円を請求してしまう仕様としたら、ユーザからのクレームに悩まされるかもしれません。
100円を請求してしまう仕様としたら、システムオーナーからのクレームに悩まされるかもしれません。
クレーム対応に追われたくないと考えた開発者は、「申し訳ございません。価格が変更となりました。」といった画面を表示して、コミット処理は実行しない仕様を採用するかもしれません。
この場合、確認画面から注文の確定までの遷移の中で、価格が変更されていることを検知しなければなりませんが、変更はどうやって検知すればよいでしょうか?
手法はいろいろありそうです。商品の価格が改定される時間が前もって分っているならば、確認画面にアクセスした時間をPOSTしてもよさそうです。時間はどこから持ってくるのがよいでしょうか?DBサーバがよいか?アプリケーションサーバがよいか?時間の同期は大丈夫か?
考えるのが面倒なので確認画面で表示した価格をそのままPOSTするのがシンプルだと提案する人がいるかもしれません。この場合、POSTされた価格とコミット処理実行時の価格に不整合が発生していたら、処理を中断すればよさそうです。仕様は固まりました。自信を持ってリリースしましょう。



開発者はある日、価格をPOSTしているだけの理由で、納品したシステムが脆弱であると騒がれていることを知ります。システムオーナーは説明に来い!と、ものすごい剣幕です。クレーム対応に追われないよう対策を練ったはずがこの有様です。忙しい開発の合間をぬって説明資料を作成しなければなりません・・・
説明を終えて偽脆弱性だということは、なんとか納得してもらえました。しかし、失った時間は戻ってきません。なんだか心臓も痛くなってきましたが、この責任はいったい誰が取ってくれるのでしょうか?

などということを考えると、迂闊に脆弱性の指摘などしない方がよいのでは?と感じることがあります。

#本当に脆弱な場合もあるかもしれません
#もっとしっかりした仕様もあるかと思います


追記
誤解を招いてしまったようなので追記です。
価格がPOSTされるだけで脆弱性と判断するのは早計ですよ。ってことを書いただけです。実体験ではないので、難しい背景とかはありません。
ちなみに、Javascriotなしで戻るボタンを実装した場合にも価格をPOSTする実装になりやすいと思います。

最後の砦web.xmlのerror-page要素が破られた

スタックトレースなどアプリケーションが吐き出す詳細な例外情報が出力されてしまうことは、セキュリティ上あまり望ましくありません。この情報を使用して攻撃を仕掛けてくる悪い人達がいるかもしれないからです。
この問題を防ぐための選択肢は2通りあると思われます。
1. 絶対に例外が発生しない完璧なコードを書く
2. 詳細な情報を含まないエラーページを表示する
私は完璧なコードを書ける自信がないので、2.を選択しています。strutsを使用していますので、struts-config.xmlのglobal-exceptions + web.xmlのerror-pageという二段構えの対策です。融通が効くのでエラーページはjspで作成しています。

<global-exceptions>
    <exception key="error.global"
        type="java.lang.Exception"
        path="/WEB-INF/jsp/error.jsp"/>
</global-exceptions>

<error-page> 
  <error-code>500</error-code> 
  <location>/WEB-INF/jsp/error.jsp</location>
</error-page>

しかし先日、この二段構えを突き破ってスタックトレースが表示されてしまうという問題が発生してしまいました。
発生箇所はファイルダウンロードなどresponse.getOutputStream()メソッドを使用するロジックです。Servlet仕様では、response.getOutputStream()コール後のresponse.getWriter()コールが禁止されているのですが、エラーページを表示する為のjspがresponse.getWriter()メソッドを呼び出すために問題が発生したようです。
どうすればよいか??と頭を悩ませましたが、response.getOutputStream()メソッドを呼び出すタイミングを出来るだけ遅くするといった解決策しか思い浮かびませんでした。エラーページをjspで作成しないという選択もあるのかもしれませんが・・・