アカウント名:
パスワード:
>文字列を数値として評価してしまうという「暗黙の型変換」mysqlのこれってものすごく筋としても設計としても悪くないかい。
mysql使ったこと無いんだが、代入先が文字列ならそんなもの動いてもらっちゃ困るだろう。
a=’1+3’ってやったら aには4が入るってことか?aが文字列のフィールドか変数として。じゃ、”式そのものを代入したい時はどうすんだ?”
> a=’1+3’ってやったら aには4が入るってことか?
まったく違う。まあ、タレコミをよく読んでほしいんだが、実際に注入したのは「+」ではなく「'+'」(シングルクオート付きの文字列)であることに注意。
文字列同士の演算として、'1'+3 とやっても、文字列「1」を数値「1」に変換してから演算するので、結果は4になる、というのが暗黙の型変換なわけだけど、さらに、「'A'+3」とやると、文字列「A」を数値「0」に変換するので、結果が3になる、というのが今回問題とされている挙動。
問題のアプリケーションは、そのSQL中で「email = '入力したメールアドレス'」というような、DBカラムと入力したメールアドレスの比較演算を行っていると推測されています。
そんな処理をしているパスワードリセット用フォームに、メールアドレス「foo@exa'+'mple.com」という文字列を入力して実行すると、「email = 'foo@exa'+'mple.com'」というSQLが作られる→「'foo@exa'+'mple.com'」は、「'foo@exa'」も「'mple.com'」も、普通の数値に変換できないので、暗黙の型変換の結果は「0+0」という式になり、右辺の演算結果は数値「0」になる→SQLの条件は、「email=0」という条件式になる→右辺が数値型なので、DBのemailカラムの内容(文字列)を数値に暗黙の型変換してから0と比較することになる→たいていのメールアドレス文字列は、数値と評価出来ないので、この型変換で0になる→「0=0」という比較を行うことになり、」全てのDBレコードがこの条件に合致することになるという流れで、「全ユーザーが条件合致してパスワードリセットされる」ことになったと推測されているわけです。
このようなSQLインジェクション的文字列を「フォームに入力してみる」のはごく標準的な脆弱性チェックです。これで「診断者が悪い」と言うのは問題の見方を間違えてます。
#MySQLの挙動が悪いとは一概には言えないというか、それはそれで便利なんですよね。。#Oracleなんかは、1データでも演算に失敗したらSQL文全体が失敗する、という挙動なんだけど、かなり不便です。
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
アレゲはアレゲを呼ぶ -- ある傍観者
いや、開発したプログラマもテスタもこの診断者も悪いのは前提として、 (スコア:0)
>文字列を数値として評価してしまうという「暗黙の型変換」
mysqlのこれってものすごく筋としても設計としても悪くないかい。
mysql使ったこと無いんだが、代入先が文字列ならそんなもの動いてもらっちゃ困るだろう。
a=’1+3’ってやったら aには4が入るってことか?aが文字列のフィールドか変数として。
じゃ、”式そのものを代入したい時はどうすんだ?”
Re:いや、開発したプログラマもテスタもこの診断者も悪いのは前提として、 (スコア:3, 参考になる)
> a=’1+3’ってやったら aには4が入るってことか?
まったく違う。まあ、タレコミをよく読んでほしいんだが、実際に注入したのは「+」ではなく「'+'」(シングルクオート付きの文字列)であることに注意。
文字列同士の演算として、'1'+3 とやっても、文字列「1」を数値「1」に変換してから演算するので、結果は4になる、というのが暗黙の型変換なわけだけど、さらに、「'A'+3」とやると、文字列「A」を数値「0」に変換するので、結果が3になる、というのが今回問題とされている挙動。
問題のアプリケーションは、そのSQL中で「email = '入力したメールアドレス'」というような、DBカラムと入力したメールアドレスの比較演算を行っていると推測されています。
そんな処理をしているパスワードリセット用フォームに、メールアドレス「foo@exa'+'mple.com」という文字列を入力して実行すると、
「email = 'foo@exa'+'mple.com'」というSQLが作られる
→「'foo@exa'+'mple.com'」は、「'foo@exa'」も「'mple.com'」も、普通の数値に変換できないので、暗黙の型変換の結果は「0+0」という式になり、右辺の演算結果は数値「0」になる
→SQLの条件は、「email=0」という条件式になる
→右辺が数値型なので、DBのemailカラムの内容(文字列)を数値に暗黙の型変換してから0と比較することになる
→たいていのメールアドレス文字列は、数値と評価出来ないので、この型変換で0になる
→「0=0」という比較を行うことになり、」全てのDBレコードがこの条件に合致することになる
という流れで、「全ユーザーが条件合致してパスワードリセットされる」ことになったと推測されているわけです。
このようなSQLインジェクション的文字列を「フォームに入力してみる」のはごく標準的な脆弱性チェックです。
これで「診断者が悪い」と言うのは問題の見方を間違えてます。
#MySQLの挙動が悪いとは一概には言えないというか、それはそれで便利なんですよね。。
#Oracleなんかは、1データでも演算に失敗したらSQL文全体が失敗する、という挙動なんだけど、かなり不便です。