パスワードを忘れた? アカウント作成
311835 story
情報漏洩

MySQL、ブラインド SQL インジェクションにより情報漏洩が発生 45

ストーリー by reo
餅は餅屋だけに餅に弱い 部門より

MySQL.com と関連するサイトが米国時間 27 日にクラックされ、情報が漏洩した模様。手法はブラインド SQL インジェクションによるものと考えられている (Techie Buzz の記事本家 /. 記事より) 。

被害に遭ったのは本家 MySQL.com の他、フランス、ドイツ、イタリアの MySQL のサイト。漏洩した情報には MySQL 関係者の Email アドレスや認証情報の他、顧客情報や内部ネットワーク情報も含まれているという。また XSS 脆弱性についても詳細に報告されており漏洩がさらに拡大する恐れもあるとのことで、さらには Sun.com にあるデータベースの内容も既にクラックされている報告もある。

今のところ MySQL からはこの件に関するニュースリリースが出ていないが、是非とも MySQL の矜恃 (そういうものがあるのなら) を賭して対策を施して欲しいものである。

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
  • by gonta (11642) on 2011年03月28日 12時03分 (#1926710) 日記

    「ブラインド」SQLインジェクションって、区別するものなのかな?SQLインジェクションそのものだと思うんだけど。SQLインジェクションの種類わけならそれでもいいと思うんだが、何か別物のように聞こえてしまって/扱っているようで、違和感感じました。

    PHPのソーシャルアプリを使っている人間に聞いたら、PDOでPlaceFolderを使ったクエリ作成(prepare使うやつ)は、使わないんだとか。PDOって処理速度が重いので、PV稼がなくてはいけないソーシャルアプリには不適切なんだとか。教科書どおりなら、SQLインジェクション防ぐのはprepare()が有効だと思うんだが・・・

    --
    -- gonta --
    "May Macintosh be with you"
    • by Anonymous Coward

      さすがPHPer、期待に違わぬ残念さ。
      Javaで速度を稼ぐためにPreparedStatementをやめたなんて話は聞いたことがないなあ(検索条件が動的に変化するので使えなかったということはあるけど)。むしろかえってparseが必要な分遅くなるとしか思えないんだけど。
      実はDBMSがなんちゃってPreparedStatementしか用意されていないMySQLだったなんてオチはないよね。

      • by ootori (41812) on 2011年03月28日 13時21分 (#1926755) 日記
        詳細聞かずに、PHPerだと無条件でたたくのはやめたほうが良いと思いますよ。

        たとえばJAVA屋さんだとDBコネクションをプーリングするのが常識みたいになってますけど、
        ソーシャルアプリ業界ではプーリングするのは逆にご法度みたいな部分があったり
        ジャンルによってノウハウって違いますからね。

        DBあんまり詳しくないんでまちがってたらすいませんけど、毎回DB接続をオープン、クローズしてたらprepared statementでのSQL解析をするぶん速度は落ちるのではないでしょうか?
        そういう意味ではPrepare statementやめて生SQL生成してそれ投げるというのはわかる気はしますね。

        月間一億PV程度のしょぼいサイト(秒間最大200PVくらい)までしか扱ったことない私はprepare statement使っても問題ないとは思いますが、ソーシャルアプリとか秒間数千から数万のクエリさばく世界ですからね。
        中途半端な知識の人間が根拠なしにPreparedStatementをやめたなんていってるとはおもえないんですけど・・・
        親コメント
        • by kou1slash (5979) on 2011年03月28日 13時48分 (#1926770)

          prepared statement ってクエリキャッシュに載せるために使うものでコネクションプーリングとはあまり関係ないと思ってたんですがあってますかね?
          「毎回DB接続をオープン、クローズした時のSQL解析」を高速化するためのの物という把握でした。

          DBは幾らか分かるんですが、アプリは素人なんで変なコト言ってるかもしれませんけど…。

          親コメント
          • by ootori (41812) on 2011年03月28日 14時23分 (#1926788) 日記
            このあたりの質問が私の言いたかったことに近いですね。

            http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=5374&forum=12 [atmarkit.co.jp]
            > PreparedStatementによりプリコンパイルされたSQLは
            > コネクションをクローズした後もキャッシュされているのでしょうか?

            コネクションクローズしたあともプリコンパイルされたSQLが保持されているということであれば納得です!
            違うなら生SQLの方がはやいですよね??
            親コメント
            • by Anonymous Coward

              > 違うなら生SQLの方がはやいですよね??
              なんで?

              • by ootori (41812) on 2011年03月28日 14時44分 (#1926801) 日記
                プリコンパイルしたSQLのキャッシュがない前提でのはなしですが
                【プリコンパイルあり】
                prepared,execute(プリコンパイルされたSQL) 2回通信または2回実行
                【プリコンパイルなし】
                execute(生SQL) 1回通信または1回実行
                だとおもうんですが?ちがいますか?
                親コメント
              • by Anonymous Coward

                そもそもどうしてstatementがキャッシュされることがないなんて非現実的な仮定にこだわるんですか? 性能が重要なサーバじゃなかったの?

              • by ootori (41812) on 2011年03月28日 15時36分 (#1926828) 日記
                > そもそもどうしてstatementがキャッシュされることがないなんて非現実的な仮定にこだわるんですか? 性能が重要なサーバじゃなかったの?

                ぼくが書いた内容をちゃんと読んでますか?
                こだわるってるんじゃなくてわからなくてずっと質問してるんですが・・・
                質問してる人間に質問で返すなと・・・

                PDOでコネクションクローズしたあとでもstatementがキャッシュにのっているのであればおっしゃるとおりだと思います。
                ただ、コネクションクローズしたあとでもstatementのキャッシュがつかえるのかどうかそこがわからんのです。
                そしてその部分はだれも教えてくれない・・・
                親コメント
              • by Anonymous Coward

                毎回コネクションクローズしてたらそのコストがでか過ぎて、
                preparedだろうとそうでなかろうと大した差がない。

                そもそもプーリングがご法度って本当なの?
                ソース出してくれませんかね?

              • by ootori (41812) on 2011年03月28日 16時06分 (#1926850) 日記
                > ソース出してくれませんかね?

                もう他の人がだしてるよ・・・
                親コメント
              • by Anonymous Coward
                PHPでコネクションプーリングするとき、普通はpg_pconnectを使う。これを使うとプロセスが終了するまでコネクションを開きっぱなしにする。Apacheでmod_phpを使うと1つのプロセスは同時に1つのPHPスクリプトしか実行できないから、pg_closeしてもそのコネクションを再利用できるのは同時実行されている他のプロセスのスクリプトではなく、同じプロセスが実行する次のスクリプトになってしまう。これによって接続しているだけでメモリを占有するのに何もしないコネクションが大量発生し、性能が劣化する。元々MySQLはコネクションの作成がとても速いから、こんな不完全なプーリングを使うよりは、そのつどpg_connectして使い終わったらすぐpg_closeした方がメモリ要求が少なくなってトータルでは効率的。
              • by ootori (41812) on 2011年03月29日 1時31分 (#1927109) 日記
                ですよね・・・
                ソーシャルアプリ界隈って言ったのが癪に障ったのかえらく叩かれてしまいました。

                ソーシャルアプリに限らずPHPの高負荷サイトでpconnect使わないのは比較的常識の部類だと思ってたんですけどね(グッドノウハウなのかバッドノウハウなのかはさておいてね)。

                それにしても「使う技術によってノウハウは違うよ」って言っただけのつもりだったのに何でこんなに叩かれたんだか・・・
                親コメント
              • by Anonymous Coward

                なら最初からPHP+MySQLの話と書けばいいのに。
                それに叩かれてるのはpconnectじゃなくてprepared statementの話だよね。
                prepared statementでなく、生文字列を組み立てて速度を稼ぐのは明らかにバッドノウハウ。
                他のツリーにもあるけど、PDOとMySQLの実装がバカなのが原因。

              • by Anonymous Coward
                考える余地もないと思いますが、説明の仕方に問題があるからでしょう。
              • by b-wind (13096) on 2011年03月29日 13時06分 (#1927223) 日記

                >PHPの高負荷サイトでpconnect使わないのは比較的常識の部類
                それは比較的常識に考えていいけど、まぁバッドノウハウの類だな。

                pconnect 自体が単なる永続的接続で、にコネクションプールと呼べる物じゃ無いって事を忘れてるよ。

                親コメント
              • by Anonymous Coward

                そういう当てこすりをしたいなら、技術論の場には出てこないほうがいいんじゃないかな。
                多くは技術的に正しいか正しくないかを論議しようとしてるよね。

                #1926755 の論点を洗うと、
                1. コネクションプーリングはソーシャルアプリ界隈ではご法度
                2. Prepared Statementを使うとSQLのパースは遅いのではないか
                の二点になると思うけど、これでいい?

                1に関して繋がっているのは #1926785 #1926836 #1927085 で叩きになってるようには見えないけどどうかな。
                #1926793 の「本当にこれ合ってるの?」に対して反論が出てきてないのが気になる。
                #1927085 の通りだとするとMySQL特有で、PHP+Pos

              • by ootori (41812) on 2011年03月29日 14時55分 (#1927280) 日記
                これベースに話してるんだと思ってたんですが・・・
                http://srad.jp/security/comments.pl?sid=527293&cid=1926729 [srad.jp]

                で、私の意見は「使う技術によってノウハウは違うよね?」「詳細聞かずに残念いっちゃだめだよ」の2点ですよ?

                他の発言に関しては質問してる内容を質問でかえされたから私はこう思ってるんだけど違うのかな?って考えをいっただけで議論するつもりはないですよ・・・
                そんな議論ができるほど立派なエンジニアではないですから・・・

                > 叩きが入っているようには見えないんだがどう?
                その後馬鹿馬鹿言われてたので、たたかれたと表現しましたけどね・・・馬鹿とかいわれなければたたかれたとは言いませんよ。それとも馬鹿と相手に対して言い放つのは議論であって叩いてないということでしょうか?
                親コメント
          • by bero (5057) on 2011年03月28日 15時39分 (#1926831) 日記

            逆。prepared statementを使うとクエリキャッキュがきかない
            http://dev.mysql.com/doc/refman/5.1/ja/query-cache-how.html [mysql.com]

            親コメント
        • by shuichi (572) on 2011年03月28日 22時33分 (#1927042) 日記

          色々コメントついてるけど論点がずれてない?
          別にprepared statement が重要な訳じゃないと思うけど。
          要はエスケープ処理を確実にする為なんだからプレースフォルダを解決する関数ひとつ作ればいいだけじゃん。
          1っ箇所だけならまず間違えないし、prepared statement 使ってる人なら簡単な説明で理解してくれるはずだし。

          親コメント
        • by Anonymous Coward

          ソーシャルアプリ業界ではプーリングするのは逆にご法度

          これってどんな理由でご法度にしているのでしょう。
          効率性の問題ではないように思えるのですが。

          • by Anonymous Coward

            自己レス。
            元ネタはきっとこの辺ですね。
            Lampで作るソーシャルアプリの負荷対策~アプリとインフラの調和のテクニック~ [slideshare.net]。
            DB接続への待ち行列を少なくすることが重要な負荷対策であると。

            接続だけして作業してないコネクションがDBの負荷に影響を与えるのだろうかと。
            メモリ増やしてDB側の接続上限を上げればよいだけに見えますが、少し実験してみないと分からないところで。

          • by Anonymous Coward

            RDMS の機能の半分を占める (!) コネクション認証/識別を使用してない、ってことと等価ですからねえ。

        • by Anonymous Coward

          論より証拠で、JavaでPreparedStatementを使う場合と、そうでない場合を比較してみました。
          単純なSELECT文で、以下の条件で10000回ループさせました。

          1. PreparedStatementをループの外で生成して使い回し
          2. 1回ごとにPreparedStatementを生成
          3. 1回ごとにSQLを生成して、executeQueryで生のSQLを実行

          1.が速いのは当然として、2と3のどちらが速いかが問題だと思いますが、結果としては平均で、
          1. 403ms
          2. 7124ms
          3. 7523ms

          となりました。つまり、PreparedStatementを使わない理由はないということです。
          Java+Oracleでのテストなので、PHP+MySQLがヘボイ実装という可能性はありますが:P

          • by ninestars (5792) on 2011年03月28日 18時35分 (#1926916) 日記

            比較するならば Java+MySQL で同じテストをしてみましょう。

            親コメント
          • by Anonymous Coward
            自分PHPerで同じように測ったら、1が速いのは当然として、2より3のほうが速いです。7100と7500のような微小な差ではなくもっと大きい。
            さらに、PHP(ウェブ)の場合リクエストごとに接続するのがスタンダードだから、毎回Prepare作成しないといけない。
            一度Prepareしたものを同スクリプト内で再利用する機会はほとんどない。

            ローカルアプリのように起動したら終了するまで接続を維持するようなものならいいですけど、ウェブのようなものには向いてないような気もする。
            ただの勉強不足ですけど。
            • DBMSの物とバージョン、使ったライブラリを明示するべきかと

              親コメント
            • ちょっと気になったので、PHP上でDBおよび接続手段を変えて測ってみました。
              FreeBSD 7.2-RELEASE/amd64上で、PHP 5.3.6、MySQL 5.1.33、PostgreSQL 8.4.6 を使ってます。

              integer な主キーに対するSELECTを1万回実行した時の、1回あたりの処理時間(マイクロ秒)
              (接続は、単なるDBへの接続と切断を1万回実行)

                              prepare    生SQL
                      接続 1回だけ 毎回   生成
              MySQL
              mysql    161                 44
              mysqli   180    48    134    48
              PDO      151    47     51    50
              MDB2     921   609    996   124
              PostgreSQL
              pg      8260   122    245   159
              PDO     7861    91    366   407
              MDB2   13045   535   1210   406

              PostgreSQL はprepareしておいた方が速いですが、MySQL は毎回生SQL文を生成してもほとんど同じ。
              MySQL PDO だけは、毎回prepareしても似たような数値なので、内部で自前でSQL文を組み立ててるんだと思います。
              まあ、エスケープ処理のアルゴリズムさえ間違えてなければ、その方が速いし悪いことじゃないとは思いますが…釈然としない…

              あと、こうしてみると PostgreSQLは接続にかかる時間が桁違いですね。
              これだと、Webアプリケーションでコネクションプーリングしたくなるのも納得です。

              親コメント
        • この一連のコメントに対する確認なのでここにぶらさげます

          プリペアードクエリ:クライアント側で利用選択する機能。
           実行計画を事前に作成し、実際にいれる値だけを変えて連続実行
           → どちらかというと実行計画の使いまわしより
             プレースホルダによる自動エスケープの恩恵が大きい。

          ステートメントキャッシュ:サーバ側自動機能。
           プリペアードクエリの実行計画をキャッシュ。
           → あまり意味がないとのことでサーバ側で無効にされている

          クエリキャッシュ:サーバ側自動機能。意外とパフォーマンスに影響
           問い合わせで同じデータを返すものをキャッシュ。
           → パラメータ付きのプリペアード
      • by Anonymous Coward

        ちょっと想像してみたら分かることですが、
        まともな実装なら明らかにPreparedStatementの方が速いですね。
        パラメータが変わっても同じSQLとみなされるので、SQLのパース作業が2回目以降は不要になるし。

        # 検索条件が動的に変わる場合も、?付きの条件を動的に生成すべきですね

      • by Anonymous Coward

        PHPを下に見てる割にはJavaの事しか語れないんだね。
        そもそも言語も実装も異なるのに、PHPで使用していない機能をJavaで語っても仕方ないでしょうが。
        PHPもMySQLもよく分かりませんって素直に言えよ。

        • by Anonymous Coward
          ootori見てるとPHPerが馬鹿ばかりに見えるのは仕方がない。
          • by Anonymous Coward
            要するに、PHP+PDO+MySQLの組み合わせでは、いくらprepareを使用しても、exeture時に?をPHP側で文字列置換したSQLをDBに投げるだけなので
            ・SQLがキャッシュされないので遅い
            ・SQLインジェクション脆弱性を防げない
            つこと。
            ootoriはたしかにバカだが、本当にバカなのはPDOとMySQLの実装者で、全世界のPHPユーザが迷惑してる。
            • by tomop (5875) on 2011年03月29日 18時02分 (#1927371) ホームページ

               ソース見たけど、mysql_stmt_prepare()呼んでるよ。

              php-5.3.6/ext/pdo_mysql/mysql_driver.c

              #if HAVE_MYSQL_STMT_PREPARE || PDO_USE_MYSQLND
              ...snip...
                              if (!(S->stmt = mysql_stmt_init(H->server))) {
              ...snip...
                              if (mysql_stmt_prepare(S->stmt, sql, sql_len)) {

              親コメント
            • by Anonymous Coward

              PHP+MySQLの組み合わせはほとんど使ったことないけど

              要するに、PHP+PDO+MySQLの組み合わせでは、いくらprepareを使用しても、exeture時に?をPHP側で文字列置換したSQLをDBに投げるだけなので
              ・SQLがキャッシュされないので遅い
              ・SQLインジェクション脆弱性を防げない

              これマジ?
              でも生SQLに展開されるのならMySQLのクエリキャッシュ(笑)は有効になるんじゃ?

            • by Anonymous Coward

              MySQL関係なくね?
              それともOracle(wなら賢くキャッシュしてくれたりSQLインジェクションを防いでくれるのかよ。

              • by Anonymous Coward
                実はOracleは賢くキャッシュしてくれるんだ。
                簡単に言うと直書きされたSQLを勝手にバインド変数に置き換えてからキャッシュ探してくれる。
                逆にバイント変数使っても変数の中身見て実行計画変更する機能まである。
              • by Anonymous Coward

                昔DB2使ってたけど当然のようにキャッシュもインジェクション防ぐ機能もあるよ。
                むしろエスケープ(笑)とかしてるほうが珍しい。

  • by Anonymous Coward on 2011年03月28日 11時46分 (#1926702)
    今時SQLインジェクションとか低レベルな攻撃に引っかかるとは思わなかった。
  • by Anonymous Coward on 2011年03月29日 4時11分 (#1927116)

    種種雑多なデータを一つのDB(?)で管理してることが間違いじゃないの?
    認証情報や顧客情報や内部ネットワーク情報なんて外部からアクセス制限
    もなしにアクセスできちゃうのが間違いじゃ?
    こういった情報は特定のプログラムからしかアクセスできないとか
    プログラムの実行自体にも認証が必要とか、なんか色々あると思うん
    だけど。

    ずいぶん昔、企業のホームページ用のサーバーでカタログ請求した
    ユーザーのメールアドレスはそのサーバーに保存せずローカルに接続された
    別のサーバーに転送して元のサーバーには置かないようににしてあった。
    大事なデータの取り扱いってこういうことだと思う。

    • by Anonymous Coward

      それをしてたって話でしょ(?)

typodupeerror

192.168.0.1は、私が使っている IPアドレスですので勝手に使わないでください --- ある通りすがり

読み込み中...