最後に取り上げるのはmemcachedです。memcachedは、Key-Value型のオープンソースのキャッシュシステムです。データはメモリ上にのみ格納され、ハードディスクなどには保存されないため、再起動などのタイミングでデータは失われます。
永続的なデータ保持を行わないことなどから、memcachedを「NoSQLデータベース」に分類すべきかは議論のあるところでしょうが、本記事ではNoSQLを広く「非SQL」のデータアクセスインターフェイスを持つ製品ととらえ、その1つとしてmemcachedを取り上げます。
memcachedについては、数年前からmemcachedインジェクションと呼ばれる攻撃手法が存在することが知られています。
Memcached Injection - 佐名木智貴 (NTTコミュニケーションズ)
http://www.ntt.com/icto/security/images/sr20080311.pdf
memcachedインジェクションとは、簡単にまとめると、データ操作コマンドの区切り文字となるCR-LF文字をキーに挿入するなどの方法により、新たなデータ操作コマンドを挿入する攻撃です。memcachedにはASCII版とバイナリ版のプロトコルがありますが、攻撃対象となるのはASCII版です。以下にこのmemcachedインジェクションの概要を説明します。
下記はmemcachedの値を取得して表示するPHPのプログラムの例です。
// リクエストパラメータの値を取得 $key = $_GET['key']; // memcachedを検索した結果を出力 // 文字列「pub_」にパラメータの値を結合したキーを使う echo $memcached->get('pub_'. $key);
正常なパラメータの例は下記の通りです。
正常パラメータ例: key=c0001
上記のパラメータを送信すると、「pub_c0001」というキーに対応する値が応答のHTMLに出力されます。
本来このプログラムは、memcached上のデータを参照するためのものですが、CR-LF文字を使ってmemcached上のデータを変更するコマンドを送り込むことができます。操作パラメータの値は下記の通りです。
操作パラメータ例: key=c0001%0D%0Aset somekey 0 0 8%0D%0Atesttest
操作値に含まれる「%0D%0A」は、改行文字(CR、LF)をURLエンコードして表したものです。上記のプログラムに操作パラメータを付けたリクエストを送信すると、改行文字によって「set somekey...」というデータを変更するmemcachedコマンドが有効になり、データベース上のデータが改ざんされてしまいます。
仮に、Webページの表示データの一部をmemcachedに保存しているならば、Webページの改ざん被害につながる可能性があります。また、memcachedにアクセスするライブラリは、保存の際にオブジェクトをシリアライズしてmemcachedに保存し、取り出す時にはデシリアライズしてプログラムに渡します。このデシリアライズする挙動とmemcachedインジェクションを組み合わせると、状況によってはサーバ上で意図しない処理を実行させることができます。Pythonでの悪用の可能性は、以下の資料で触れられています。
Cache on Delivery - Marco Slaviero (Sensepost)
http://www.slideshare.net/sensepost/cache-on-delivery
次は、任意のキーの値をHTMLに出力させる攻撃の例です。上記のプログラムは「pub_」で始まるキーの値のみをHTMLに出力するようになっていますが、その制限を回避する攻撃です。
操作パラメータ例: key=xxx%0D%0Aget some_secret
今度は改行文字の後にgetコマンドを付与しています。memcachedサーバは2つのgetコマンド(キー「pub_xxx」と「some_secret」)を受け取る格好になりますが、1つ目のget要求は存在しないキーであるため、2つ目の「some_secret」への応答がecho文によってHTMLに出力されてしまいます。この攻撃はタイミングに依存する面があり、筆者の環境でも100%再現するものではありませんでしたが、何回かトライすることで再現できると思います。
これらの問題の原因は、memcachedのキーには改行文字などが使用できないことになっているにもかかわらず、それが守られていないことです。このほかにも、キーには250バイト以下という長さの制限もあり、この制限を超える長さのキーを使用することで、別のコマンドを挿入する攻撃も知られています。
上記でリンクを示したPDFドキュメントに記載があるとおり、一部のライブラリ(プログラム言語からmemcachedにアクセスするためのライブラリ)は、キー文字列のチェックやエンコードをライブラリ側で実施してくれます。それがライブラリとしての望ましい処理ではありますが、エンコードやチェックをしてくれないライブラリも存在します。
例えば、今回の執筆に当たり、PHP系の最新のmemcachedやライブラリ(memcached 1.4.15、libmemcached 1.0.16、PECL memcached 2.1.0)を使用して検証を行いましたが、memcachedインジェクション攻撃への対処はされていませんでした。このほかに、いくつかのライブラリで検証を行った結果を下記に示します。
言語 | ライブラリ | バージョン | 対応 | 備考 |
---|---|---|---|---|
PHP | PECL memcached | 2.1.0 | × | libmemcached 1.0.16 |
PHP | PECL memcache | 2.2.7 | ○ | - |
ruby | memcache-client | 1.8.5 | ○ | - |
Java | Memcached-Java-Client | 2.6.6 | △ | キー長制限処理がない |
対応欄が×あるいは△のライブラリは、memcachedインジェクションの対策がされていない、もしくは不十分です。そのようなライブラリを使用する場合は、「キーが半角英数で250バイト以下である」といったチェックをアプリケーション側で実施する必要があります。このようなチェックを行うクラスでライブラリをラップしてしまうのが確実でしょう。
本記事では、比較的使用事例が多いと思われるMongoDBとその他3つのNoSQLデータベース(Cassandra、Redis、memcached)を取り上げて、それらを使うアプリケーションの不備により生じるインジェクション系の脆弱性について説明しました。アプリケーションに不備があれば、SQLデータベースと同じようにデータの窃取や改ざんなどの被害を受ける可能性があることが理解いただけたと思います。
おさらいのために、今回取り上げたNoSQLを使ったアプリケーション開発を行う際の注意点を以下にまとめます。
注意点 | 対象のNoSQL |
---|---|
連想配列型のパラメータに注意 | MongoDB(演算子インジェクション) |
スクリプトの動的生成に注意 | MongoDB(JavaScript)、Redis(Luaスクリプト) |
クエリ文字列の動的生成に注意 | MongoDB(JSON)、Cassandra(CQL)、memcached(キー) |
想定外のパラメータ追加に注意 | MongoDBほか |
いずれも、脆弱性の根本的な発生原理は既存の脆弱性から大きく変わるものではありませんが、MongoDBの演算子インジェクションとmemcachedキーのインジェクションについては、アプリケーション開発者が想定しにくい問題だと思われますので、特に注意が必要です。
また、これからNoSQLを使用するアプリケーションを開発する方は、導入前に製品提供元サイトのマニュアルなどでセキュリティに関する情報を収集していただきたいと思います。一口にNoSQLといっても、データベースごとに機能もまちまちであり、脆弱性もまちまちだからです。
しかもNoSQLには新しい製品が多く、速いペースで機能の追加・変更が行われています。その中にはセキュリティに影響を与える変更も含まれるでしょうし、それに応じて攻撃手法が増えていくことも考えられます。そのため、メジャーアップデートなどのタイミングで継続的に情報収集を行っていただきたいと思います。
最後に、今回の記事はセキュリティがテーマということで、NoSQLを使うアプリケーションの危険な側面を多く取り上げています。しかし、現状のアプリケーションセキュリティを全体的に見た場合、NoSQLの導入が既存のSQLデータベースと比較して著しくリスクが大きいということはありません。NoSQLの性質や安全な使い方を理解した上で、新しい技術を楽しんで使っていただければと思います。本記事がその一助となれば幸いです。
また今回の記事ではアプリケーションのインジェクション系の脆弱性を取り上げましたが、NoSQLのセキュリティを脅かすのはそれだけではありません。NoSQLについては、既存の商用RDBと比較して、認証・認可・暗号化・監査などのセキュリティ機能が不十分であることが指摘されています。
特に問題となり得るのは認証で、デフォルト設定では外部のホストから認証なしでアクセスできるようになっているNoSQLが大半です。そのままサーバをグローバルなネットワークに置いてしまい、インターネットから認証なしに全データの参照・更新が可能になっている――そんな状況にだけはならないよう注意いただきたいと思います。下記のスライドには、そのような危険な状態にあったNoSQL(memcached)の実例がいくつか書かれています。
Cache on Delivery - Marco Slaviero (Sensepost)
http://www.slideshare.net/sensepost/cache-on-delivery
また、トランザクションやバックアップ/リストアなどのデータの一貫性・可用性を保つ機能も商用RDBと比べて不十分であるといわれています。保存するデータの性格を見定めて導入の検討をしていただきたいと思います。
プロフェッショナルサービス事業部
シニアセキュリティスペシャリスト
ポータル・サイトなどでのWebアプリケーションのシステム開発・運用経験を生かし、セキュリティコンサルタントとして、Webアプリケーション・スマートフォンアプリケーションなどのセキュリティ診断や関連する研究開発に従事している。ECサイトや金融機関などのWebサイト検査の実績を持つ。CISSP、情報セキュリティアドミニストレータ。
Copyright © ITmedia, Inc. All Rights Reserved.