Category: MySQL
PostgreSQLカンファレンス2008
June 3rd, 2008PostgreSQLカンファレンス2008が今週金曜日(6/6)に開催されます。
http://www.postgresql.jp/events/postgresql-conference-2008
例年通り参加費が必要ですが懇親会費込みです。
参加費:
カンファレンス ならび に懇親会 4,000 円
チュートリアルも含むカンファレンス ならびに 懇親会 10,000 円
今回のカンファレンスの目玉は色々ありますが、その一つはチュートリアルセッションです。まだ、空席が残っているようなのでライセンスもBSDでMySQLよりも使いやすいPostgreSQLを始めてみたい方には良いチャンスだと思います。新人研修の一環としても良いと思います。
* MySQLユーザのためのPostgreSQL入門
(リナックスアカデミー 学校長 濱野 賢一朗 氏)
興味がある方は是非カンファレンスにお越し下さい。
誤解を招く記事 - LAMPセキュリティを強化する4つの方法
March 14th, 2008LAMPセキュリティを強化する4つの方法
http://enterprisezine.jp/article/detail/311
書いてある情報は有用な事も記載されていますが、偏狭な視点からの記述により誤解を招く記事になっていると考えられます。著者はセキュリティの専門家ではないようなので仕方ないかも知れませんが、間違った認識は有害です。
# 原本は読んでいません。もしかすると日本語訳にも問題があるのかも知れません。
文字エンコーディングを利用したSQLインジェクション
January 19th, 2008PHPのSQLインジェクションを実体験
http://www.thinkit.co.jp/free/article/0801/5/2/
を書かせて頂きました。この文字エンコーディングを利用した攻撃は古い脆弱性です。知っている方なら2年以上前からよくご存知とは思います。
記事のタイトル通り、文字エンコーディングを利用したSQLインジェクションを実体験できます。ご興味のある方、まだご存知でない方はぜひご覧ください。
万が一、文字エンコーディングベースの攻撃に未対策で攻撃される可能性のある方はできるだけ早く対策することをお勧めします。
FreeBSD7はPostgreSQL, MySQLユーザにとって救いになるか?
January 14th, 2008http://people.freebsd.org/~kris/scaling/7.0%20Preview.pdf
にFreeBSD7上でのPostgreSQLとMySQLのベンチマークが載っています。
PostgreSQL 8.2.4 - 11ページ

ピーク性能でおよそ5400transactions/secほど。
MySQL 5.0.45 - 15ページ

ピーク性能でおよそ3800transactions/secほど。
Kernelの主要な部分すべてがパラレルに動作するようになったため、かなり高速(数値にして数倍)になったようです。
グラフからもPostgreSQLの方がかなり良い性能であることが分かりますが、PDFファイル(16ページ)によると
On this benchmark PostgreSQL is 35% - 45% faster thanMySQL at all loads
とPostgreSQLの方が全般的に良い性能だったそうです。PostgreSQL 8.3は確実に8.2よりもさらに良い性能を期待できると思います。MySQLも5.1や6.0を利用した方が良い性能が期待できるのかも知れません。
このPDFのベンチマークはデータベースの性能を計る為のベンチマークではなく、OSの性能を計る為のベンチマークです。データベースサーバ設定、SQL文やテーブル構成などが不明なのでデータベースの性能のベンチマークとしては参考値くらいでしかありません。MySQLのテストではMyISAMを使っていると思われますが、MyISAMならこれくらいの性能差は普通です。
WordPress Charset SQL Injection Vulnerability
December 12th, 2007http://www.securiteam.com/unixfocus/6N00D0AKKM.html
に解説されている脆弱性は基本中の基本です。
Most database query in WordPress uses escape() method to sanitize SQL string, which is essentially filtering input via addslashes() function. However addslashes() fails to consider character set used in SQL string, and blindly inserts backslash before any single quote, regardless of whether such backslashes will form another valid character or not.
addslashes()によるエスケープは行ってはならない、とよく言っていますがWordPressでさえaddslashes()を使っていたのですね。WordPressはUTF-8だけでなくGIB5とか使えるのですね。WordPressをSJISを使っている方は同じ脆弱性があるので要注意です。
本質的には私のブログでも指摘している脆弱性と同じ種類の問題です。
追記
CVEが出てます。
http://nvd.nist.gov/nvd.cfm?cvename=CVE-2007-6318
(1) Big5, (2) GBK, or possibly other character set encodings that support a "\" in a multibyte character.
BIG5, GBKエンコーディングが影響を受け他の文字に¥が現れる文字エンコーディングにも影響があると思われる、と書いてあります。つまりSJISが該当します。
対策を書いておきます。
- データベースを正しい文字エンコーディングで作成する
- アプリケーションからデータベースやクライアント文字エンコーディングを変更する場合、データベースのAPI(pg_client_encoding, mysql_set_charsetなど)を利用する(SQL文で変更しない)
- 文字列をデータベースクエリ用にエスケープする場合はデータベースAPIを利用する(pg_escape_string, mysql_real_escape_stringなど)
別の対策として、プリペアードクエリを利用する方法もあります。
壊れた文字エンコーディングの文字列を無理矢理扱えるようにする方法があります。しかし、壊れた文字エンコーディングを扱えるようにするとアプリケーションや環境に存在する未知の脆弱性により攻撃可能になるかもしれないリスクがあります。壊れた文字エンコーディングを扱えるようにするのではなく、既にあるデータは綺麗にして、新しい文字データは全て正しい文字エンコーディングであるように入力時にバリデーションすべきです。
MySQL5.0.51では不十分
December 11th, 2007http://nvd.nist.gov/nvd.cfm?cvename=CVE-2007-5968
によるとMySQL 5.1.23には脆弱性ありその概要は以下とされています。
Overview MySQL 5.1.x before 5.1.23 might allow attackers to gain privileges via unspecified use of the BINLOG statement in conjunction with the binlog filename, which is interpreted as an absolute path by some components of the product, and as a relative path by other components. Impact CVSS Severity (version 2.0): CVSS v2 Base score: 10.0 (High) (AV:N/AC:L/Au:N/C:C/I:C/A:C) (legend) Impact Subscore: 10.0 Exploitability Subscore: 10.0 Access Vector: Network exploitable Access Complexity: Low **NOTE: Access Complexity scored Low due to insufficient information Authentication: Not required to exploit Impact Type: Provides administrator access, Allows complete confidentiality, integrity, and availability violation , Allows unauthorized disclosure of information , Allows disruption of service
MySQL 5.0系の最新版は5.0.51ですが、これには上記の脆弱性の修正が含まれているか気になったので調べてみました。
http://nvd.nist.gov/nvd.cfm?cvename=CVE-2007-5969
これは同じ日付のMySQL 5.0.51のCVEエントリです。これにはBINLOGの脆弱性に関する記述がありませんでした。リリースノートのURLがあったので見てみましたが以下のリリースノートにの記述がありませんでした。(現時点で)
5.0.51のリリースノート
http://dev.mysql.com/doc/refman/5.0/en/releasenotes-cs-5-0-51.html
5.0.52のリリースノート(現時点では、Enterprise版のユーザしかダウンロード出来ない?)
http://dev.mysql.com/doc/refman/5.0/en/releasenotes-es-5-0-52.html
5.0.54のリリースノート(現時点ではまだダウンロード出来ない)
http://dev.mysql.com/doc/refman/5.0/en/releasenotes-es-5-0-54.html
5.0には影響ない?
5.0.51で修正?
5.0.52で修正?
5.0.54で修正?
どれなのかよく分かりません。分かったのはMySQLはコミュニティ版とエンタープライズ版でセキュリティパッチリリースを差別化している事です。5.0.52にもセキュリティフィックスが記載されています。つまり最新のコミュニティ版の5.0.51では不十分です。探せばダウンロードできるのか?アカウントを取ればダウンロードできるのか?いづれにせよどれが最新で安全なのか分かりづらいです。
リポジトリへのコミットを見ていればセキュリティパッチを見分けてインストールする事も可能ですが、とても一般向けとは言い難いです。
MySQL 6.0のバージョン管理にはBitKeeperを利用しているようです。5.1、5.0はsubversionのようなので今はまだよいですが、BitKeeperも障壁の一つになりそうです。リポジトリ自体にアクセスしてみよう、と思ったのですが少しググっただけではどこへアクセスすればよいのか分かりませんでした...
追記
しばらくしてからまた新しいMySQLのCVEが出ています。
http://nvd.nist.gov/nvd.cfm?cvename=CVE-2007-5970
http://nvd.nist.gov/nvd.cfm?cvename=CVE-2007-6303
http://nvd.nist.gov/nvd.cfm?cvename=CVE-2007-6304
新しい方は明確にかいてあるので古い方はどうなの?と思わなくてもよいようになっています。
簡単なベンチマーク
October 11th, 2007最近のPostgreSQL, MySQL, SQLiteのパフォーマンスはどうかな?と言うことで非常に簡単なベンチマークをしてみました。
デフォルト状態のデータベースに郵便番号データ(12万件とちょっと)をINSERTしてみました。フラグを除く全てのフィールドをテキスト型として定義し、全てのフィールドを挿入しました。旧番号と現行番号にインデックスを付けています。スクリプトはPHPで記述し、DBが動作しているPC上からPHP 5.2.4で実行しました。1レコードが分割されている場合などは無視して挿入しているので12万2000レコードになりました。
PC
CPU: PentiumD 2.8GHz
Memory: 3GB
HDD: PATA
DBMS
MySQL: 5.0.45
PostgreSQL: 8.2.4
SQLite: 3.4.0 (PDO)
実行結果(12万行INSERTの実行時間)
InnoDb: 130.70663690567
MyISAM: 131.24672317505
Postgres: 159.47350597382
SQLite: 676.43534302711
MySQLもPostgreSQLもチューニングは一切無しで実行しています。
非同期クエリを利用するとPostgreSQLもInnoDb, MyISAMと同じくらいの速度になりました。
どのDBもペンチマーク中はディスク待ちの状態でCPU時間はあまり使っていませんでした。
MySQLとPostgresは概ね予想通りの結果でしたが、SQLiteが異常に遅いのでPDOを使わないで計測してみましたがあまり変わりませんでした。トランザクションかな?と思いBEGIN, COMMITを付けてみましたが変わりませんでした。
INSERTしたレコードをランダムにSELECTしてみました。番号はmt_rand関数で生成したのでほとんどがINDEXにヒットしないので、インデックスを利用した検索の最悪のケースのテストになります。単純にテーブルから検索をするだけです。永続的接続を利用しています。
Webサーバ:Apache 2.2.6
クライアント: ab -n 10000 -c 10 (別PCから実行。Athlon64 3500+/3GBメモリ)
パフォーマンス:リクエスト/秒
Postgres: 947.58
SQLite: 1096.00
MySQL(MyISAM): 1190.35
MySQL(InnoDb): 1245.85
概ね予想通りの結果ですが、SQLiteが思っていたより遅いです。PostgreSQLは接続のネゴシエーション処理が重いので非永続的接続を利用するとかなりパフォーマンスが落ちます。システム全体でDBへの接続数を上手に制御できていない場合はpgpoolを利用するとパフォーマンス(システム全体のスループット)が改善することがこの事からも分かります。
「Postgresでこんな数字でないよ」という方、pg_pconnectで試してみましょう。コネクションプーリングが無いと話になりません。
SET NAMESは禁止
August 22nd, 2007MySQLには文字エンコーディングを変更する「SET NAMES」SQL文が用意されています。(PostgreSQLも同様のSQL文、SET CLIENT_ENCODINGがあります)この機能はSQLコンソールからは使ってよい機能ですが、アプリケーションからは使ってはならない機能です。SQLインジェクションに脆弱になる場合があります。
Ruby on Railsの本を読んでいて、ActiveRecordを説明している部分にMySQLの文字エンコーディングを変更する場合の例としてSET NAMESが利用されていました。アプリケーションからはSET NAMESは使ってはならない事を周知させるのは結構時間が必要かなと思いました。
PHPも5.2の途中からMySQLモジュールにlibmysqlの文字エンコーディング設定APIのラッパー関数が追加されていたりするので、たまたま最近読んだRoRの本だけでなく、多くの開発向け情報ソースにSET NAMESを利用した例が載っていると思います。
ストアドプロシージャだけ使っていれば安全ですが、アプリケーションからDBMSの文字エンコーディングを設定する場合、SQL文ではなく必ず文字エンコーディング設定APIを利用するよう紹介しなければならないです。MySQL4はストアドプロシージャが使えないので、フレームワークなどではエミュレートしています。ストアドプロシージャだけ使って防御している「つもり」で防御になっていない場合もあります。これもフレームワークを使っていてもアプリケーションが脆弱になる良い例ですね。
脆弱性の説明は面倒ですが注意事項は簡単です。「DBMSをアプリケーションから利用する場合、文字エンコーディング設定は必ずAPIを利用する」つまり「SET NAMES(SET CLIENT_ENCODING等も)は禁止」です。
PHP 5.2.3リリース
June 5th, 2007日本語環境でMySQLを利用している方には、リリースノートに記載されているmysql_set_charset()の追加に重要な意味がある方も多いと思います。
Added mysql_set_charset() to allow runtime altering of connection encoding.
PHP4にはまだ追加されていませんがかなり重要なセキュリティフィックスだと思います。mysql_set_charset()はlibmysqlのmysql_set_character_set()の簡単なラッパー関数です。
http://dev.mysql.com/doc/refman/4.1/en/mysql-real-escape-string.html
"If you need to change the character set of the connection, you should use the mysql_set_character_set() function rather than executing a SET NAMES (or SET CHARACTER SET) statement. mysql_set_character_set() works like SET NAMES but also affects the character set used by mysql_real_escape_string(), which SET NAMES does not"
つまりSET NEMESだと文字エンコーディングを利用したSQLインジェクションに脆弱となる可能性があります。共有型サービスを利用されている場合、SET NAMESを使用している方も多いと思います。
ググってみると2005年11月には日本のMySQLユーザ会MLでは問題が認識されていたようです。
SQLインジェクションカンニングシート
March 19th, 2007Link: http://ferruh.mavituna.com/makale/sql-injection-cheatsheet/
XSSに比べSQLインジェクションは非常に簡単に防げる脆弱性ですが、まだまだなくなりません。
SQL Injection Cheat Sheetが公開されています。
http://ferruh.mavituna.com/makale/sql-injection-cheatsheet/
XSS Cheat Sheatと同じような形式になっています。PostgreSQL、MySQL、MS SQL Server、Oracle、その他と攻撃可能なDBMSもわかるようになっています。


