Railsの脆弱性: XML実体爆発攻撃
2008年8月25日(月曜日)
Railsの脆弱性: XML実体爆発攻撃
「REXMLのDoS脆弱性 (www.ruby-lang.org)」。
RailsでXMLリクエストのパースに使用されているREXMLに、DoS脆弱性が発見されました。XML entity explosion attackと呼ばれる攻撃手法により、ユーザから与えられたXMLを解析するようなアプリケーションをサービス不能(DoS)状態にすることができます。大部分のRailsアプリケーションはこの攻撃に対して脆弱です。
XML entity explosion attackというのは、実体宣言の中で別の実体を参照することを繰り返して実体参照の処理負荷を高める手法のようですね。掲げられているサンプルコードは短いですが、実体参照を展開するとデータは30メガバイトにもなります。展開の処理方法によっては、メモリを食い尽くしてしまうのでしょう。
外部からXMLデータのPOSTを受け付けるようなサイトは注意……と言いたいところですが、XMLデータのPOSTを受け付けないはずの手元のアプリケーションで試してみたところ、CPU負荷100%になって死んでしまいました。どうも、Railsはかなり上位のところでリクエストの処理を行ってくれているようで、XMLデータがPOSTされたら無条件に処理してしまうようです。上記のリリースでは「ユーザから与えられたXMLを解析するようなアプリケーション」と言ってしまっていますが、XML処理の有無にかかわらず、Railsで構築されたアプリケーションはほとんど全て影響を受けるように思います。「XMLを扱ってないから関係ないもんねー」などと思ってしまわないように注意しましょう。
……ところで、このサイトで使用している .NET ではどうなのだろうと思い、以下のようなコードでサンプルのXMLを処理してみました。
DateTime start = DateTime.Now; XmlDocument xd = new XmlDocument(); xd.XmlResolver = null; xd.Load("dos.xml"); Console.WriteLine(xd.DocumentElement.InnerText.Length); Console.WriteLine(DateTime.Now - start);
結果は、
30000000
00:00:05.1866700
というわけで、約5秒で正常に処理できました。この程度なら特に問題なさそうです。
しかし考えてみると、外部から突っ込まれてくるXMLを処理するのは結構怖いですね。外部実体の宣言が含まれていることもあり得るわけで……。
<!ENTITY foo SYSTEM "http://example.com/?exploitcode">
……なんてのがあると、XMLパーサの設定によってはあっさり読みに行ってしまう可能性があります。この辺も気をつけないといけないですね。
※上記の C# のコードでは XmlResolver = null としているので外部実体は読みに行きませんが、これを null にしていないと、平気な顔で外部のサーバにHTTPアクセスしに行ってしまいます。Railsの場合は外部実体は読みに行かないようです。
- 「Railsの脆弱性: XML実体爆発攻撃」へのコメント (1件)
- 前(古い): System.Uriに%2fが入らない
- 次(新しい): 標識の新ジョーシキ