アプリ版:「スタンプのみでお礼する」機能のリリースについて

php言語の脆弱性について
パスワード認証において、phpのstrcmp, strcasecmpといった関数には脆弱性があると聞きます。
そこで、具体的にどのような脆弱性があるのかお伺いしたいと思います。

たとえば、認証画面にパスワードの送信フォームがあり、パスワードが分からない場合

$pass = ****

if (isset($_POST['pass']))
if (strcasecmp($_POST['pass'], $pass) == 0)
echo "Correct!";
else
echo "Incorrect"

というプログラムになっていた場合、送信フォームにどのような文字列を渡せば認証が通るのでしょうか。
また、認証が通る仕組みについても教えていただけたらと思います。

A 回答 (4件)

strcmpは型のチェックが厳格でないという仕様上の問題がありますが、それが実際に脆弱性になる *自然な* 例を作ることは容易ではありません。


strcmpによる比較が「おかしい」例として下記があります。

<?php
$a = 8498209348989438;
$b = 8498209348989439;
var_dump($b - $a);
var_dump(strcmp($a, $b));

この結果は下記となります。

float(1)
int(0)

すなわち、異なる数値であるのにも関わらず結果は「等しい」となっています。
しかし、これは入力が数値(float)であるものを文字列にキャストしているからおかしくなっているわけであって、わざわざstrcmpによる比較をすることが不自然です。
では、さっきの例を文字列型で比較するとどうなるかというと、

$a = '8498209348989438';
$b = '8498209348989439';
var_dump(strcmp($a, $b));

この結果は以下となります。これは期待した通りの結果です。

int(-1)

Webアプリケーションの場合、入力値はキャストしない限り文字列として扱われますから、問題は起きないと考えられます。

以上はWebアプリケーションの通常のケースの話ですが、様々なアプリケーションの中には、文字列と思っていた変数に整数や浮動小数点数が入っている可能性もあり得るため、原則として strcmp ではなく === で比較した方がよいということはあります。

まとめますと、strcmpを使うと予期しない結果になることがあるため === を使った方が安全ですが、そんなに簡単に strcmp で破綻が起きると言うことはありません。

参考URL:http://d.hatena.ne.jp/hnw/20090123
    • good
    • 0

> 参照したサイトは色々有りますが、こちらのサイトが簡潔にまとまっていると思います。


> http://firstjun.blog.shinobi.jp/php/php%20strcmp …

そのサイトは、strcmp関数の実際の動作をまとめ、その動作も仕様通りであることが
確認できた旨が報告されているだけで、脆弱性があるなどと一言も書かれていません。

普通、「関数に脆弱性がある」というのは、その関数が仕様通りでない動作を
することがあったり、その関数の仕様自体に不備がありプログラマーの
コーディングで危険を回避できないような仕様になっている場合を言います。
例えば、有名なのはC言語のgets関数です。
(参考)
http://ja.wikipedia.org/wiki/Gets

関数そのものに脆弱性があるということと、その関数を使って作ったあなたのプログラムに
脆弱性があるということは、全く別の話です。

あなたが知りたいのは、strcmpにどのような脆弱性があるかではなく、
strcmpについてどのような使い方をすると自分のプログラムに
脆弱性を作ってしまうのか?
と言うことではないのでしょうか?

> 要は、phpの「緩やかな比較」という仕様に脆弱性があるのではないかと思ったのです。

それは「緩やかな比較」に脆弱性があるのではなく、「緩やかな比較」という
仕様を意識してコーディングしないと、あなたのプログラムにバグ(ひいては脆弱性)を
作ってしまう可能性があるということです。

で、質問に掲示されたプログラムは「$_POST」が元々文字列として格納されているものであり、
おそらく$passもパスワード文字列を格納していることが前提だと思います。
そうであれば文字列同士をstrcasecmpで比較しているだけであり、「緩やかな比較」で
注意すべき問題点にも当たりません。

注意すべきは、文字列として格納されていないものをstrcmp関数で比較した時に、
自動的に文字列に変換して比較されるということです。
そこを意識してコーディングすれば何も問題ないし、
逆にそこを意識しないでコーディングするとバグ(ひいては脆弱性)を作ってしまう
可能性があるので注意してくださいということです。
    • good
    • 0

phpのstrcmp, strcasecmpに脆弱性があるなんて聞いたことないんですが、


どこからの情報ですか? それを補足してください。
Webページの情報なら、URLを示してください。
もしかすると、その情報のあなたの解釈に誤りがあるのかもしれません。

> 送信フォームにどのような文字列を渡せば認証が通るのでしょうか。
そのプログラムの送信フォームに特定の文字列を渡せば、常に認証が通る
ようにできるとお考えなのでしょうか?
それは、どこかに書かれてあったのですか?
それとも、あなたができるのではないかと想像して聞いているのですか?

なんとなくSQLインジェクションのことを勘違いして捉えているような
気もします。このキーワードも調べてみてください。

この回答への補足

参照したサイトは色々有りますが、こちらのサイトが簡潔にまとまっていると思います。
http://firstjun.blog.shinobi.jp/php/php%20strcmp …

要は、phpの「緩やかな比較」という仕様に脆弱性があるのではないかと思ったのです。

ですから、このプログラムはある操作で必ず認証が通るという考えではなく、このプログラムにもどこか脆弱性があるのではないかと想像して考えたのです。


私の考えですが、SQLインジェクションの問題とは関係ないと思われます。

補足日時:2014/05/02 15:09
    • good
    • 0

まずは検索してみてください。



関数名 脆弱性

とでもこの質問の内容を書くくらいなら検索した方が良いです。

また、多くのわかる人は自分で調べて分かるようになっただけなので、自分で調べずに聞く人を嫌う傾向にあると思います。

この回答への補足

補足が足りず申し訳ありません。

実はこの問題には丸一日壁にぶち当たっていたのでした。
もちろん「関数名 脆弱性」でも検索しましたし、他にもいろいろな方法で調べましたが分かりませんでした。自分の調べる力の無さを痛感しております。

ですから、決して「自分で調べずに」質問しているわけではありません。誤解をさせてしまい、申し訳ありません。

補足日時:2014/05/02 00:12
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!