岩本隆史の日記帳(アーカイブ)

はてなダイアリーのサービス終了をうけて移行したものです。更新はしません。

XSS対策パッチを当ててもRailsに残る脆弱性

どのような脆弱性

先日書いた「Rails 2系のXSS脆弱性がRuby 1.9では影響なしとされる理由」という記事に、奥さん(id:kazuhooku)より、下記のブックマークコメントをいただきました。

たとえばブログの場合、誰かに壊れたUTF-8を含むコメントを書き込まれちゃうと、そのブログ全体にアクセスできなくなる(最新コメント一覧に出るから)んじゃないか。XSSが発生しないだけで脆弱性があることは変わらない

はてなブックマーク - kazuhookuのブックマーク / 2009年9月26日

まったくおっしゃる通りです。アプリケーションの構成によっては、サービス自体が提供できなくなる可能性があります。

このような脆弱性を何とよぶのでしょうか。すでに統一的な呼称があるのかどうか、私は知りません。サービス不能という観点からは広義のDoS脆弱性といえるのかもしれません。

追記(2009-09-28

ping of death とかも DoS に分類されるから DoS でいいんじゃないかと思います」とのコメントを奥さんよりいただきました。ありがとうございます。

データベースによる差異

ところで、くだんの記事の検証時に使ったデータベースはSQLiteでした。Rails 2.0.2より、デフォルトのデータベースがMySQLからSQLiteに変更されたのだそうです。*1

Rails 2+SQLite 3という構成の場合、私の検証では、アプリ開発者がバリデーションロジックを加えない限り、不正なUTF-8シーケンスを含むデータが登録できてしまいました。

Ruby 1.9では、そのようなデータがレスポンスエンティティに含まれると、ETag生成時に例外が発生します。この例外が発生してしまうと、冒頭で触れたように、サービス自体の提供ができなくなりかねません。

試しにデータベースをPostgreSQLに変えて検証したところ、PostgreSQLが「ERROR: invalid byte sequence for encoding "UTF8"」というエラーを吐き、不正なUTF-8シーケンスを含むデータは登録できませんでした。

MySQLでも検証したかったのですが、DBマイグレーション時にsegmentation faultが発生したため、そこで諦めました。おそらくSQLiteと同様、不正なデータが登録できてしまうのではないかと思います。

残っている脆弱性への対策

さて、ETag生成時に例外を発生させないためには、次の2つの対策が考えられます。

  • レスポンスエンティティ内の不正バイトをsanitizeしてからETag生成ロジックを呼ぶ
  • 不正なデータがデータベースに登録されないようvalidateする(PostgreSQL環境では実質対策ずみ)

これらの対策は排他的ではないため、両方とも実装してかまわないわけですが、どちらもRailsでは未実装です。

というわけで、「Railsアプリが急にInternal Server Errorになった」という症状があれば、不正データの存在が原因かもしれないという話でした。